Skip to content

Commit 022553d

Browse files
authored
File read (#31)
* Read file support Signed-off-by: jparisu <javierparis@eprosima.com> * apply suggestions Signed-off-by: jparisu <javierparis@eprosima.com> * uncrustify Signed-off-by: jparisu <javierparis@eprosima.com> * Remove Exception specialization Signed-off-by: jparisu <javierparis@eprosima.com> * Add file tests Signed-off-by: jparisu <javierparis@eprosima.com> * uncrustify Signed-off-by: jparisu <javierparis@eprosima.com> Signed-off-by: jparisu <javierparis@eprosima.com>
1 parent 932abda commit 022553d

10 files changed

Lines changed: 457 additions & 1 deletion

File tree

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* @file PreconditionNotMet.hpp
17+
*/
18+
19+
#pragma once
20+
21+
#include <cpp_utils/exception/Exception.hpp>
22+
23+
namespace eprosima {
24+
namespace utils {
25+
26+
/**
27+
* @brief Exception thrown when a precondition is not met before calling a function or running a routine.
28+
*
29+
* For example:
30+
* - Reading a file that does not exist or has no read permissions.
31+
* - One argument does not fulfill the preconditions (a ptr with value nullptr).
32+
*/
33+
class PreconditionNotMet : public Exception
34+
{
35+
// Use parent class constructors
36+
using Exception::Exception;
37+
};
38+
39+
} // namespace utils
40+
} // namespace eprosima
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* @file file_utils.hpp
17+
*/
18+
19+
#pragma once
20+
21+
#include <string>
22+
#include <vector>
23+
24+
#include <cpp_utils/library/library_dll.h>
25+
26+
namespace eprosima {
27+
namespace utils {
28+
29+
/**
30+
* @brief Read a file and convert it to a single string.
31+
*
32+
* @param file_name name of the file to read
33+
* @param strip_chars whether to eliminate not desired characters from string (as windows line breaks)
34+
*
35+
* @return String with the whole file
36+
*/
37+
CPP_UTILS_DllAPI std::string file_to_string(
38+
const char* file_name,
39+
bool strip_chars = true);
40+
41+
/**
42+
* @brief Read a file and convert it to a string per line in file.
43+
*
44+
* @param file_name name of the file to read
45+
* @param strip_chars whether to eliminate not desired characters from string (as windows line breaks)
46+
* @param strip_empty_lines whether empty lines should be removed or else add it as a value of the vector
47+
*
48+
* @return Vector of strings with the whole file
49+
*/
50+
CPP_UTILS_DllAPI std::vector<std::string> file_to_strings(
51+
const char* file_name,
52+
bool strip_chars = true,
53+
bool strip_empty_lines = false);
54+
55+
} /* namespace utils */
56+
} /* namespace eprosima */

cpp_utils/include/cpp_utils/utils.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,34 @@ CPP_UTILS_DllAPI void* copy_to_void_ptr(
177177
const T* source,
178178
size_t size = sizeof(T));
179179

180+
CPP_UTILS_DllAPI bool replace_first(
181+
std::string& st,
182+
std::string const& to_replace,
183+
std::string const& replace_by);
184+
185+
CPP_UTILS_DllAPI unsigned int replace_all(
186+
std::string& st,
187+
std::string const& to_replace,
188+
std::string const& replace_by);
189+
190+
/**
191+
* @brief Remove undesired substrings from string.
192+
*
193+
* Characters as \r or not UTF-8 could be removed or replaced by a string.
194+
* By default, it will replace "\n" and "\r" by an empty string (that means remove it).
195+
*
196+
* @param st [in, out] string to make changes
197+
* @param replace_by [in] string to replace the undesired chars
198+
* @param undesired_strings [in] set of undesired strings (if want to strip by char, just add chars separated)
199+
*
200+
* @return number of strings removed.
201+
*/
202+
CPP_UTILS_DllAPI unsigned int strip_str(
203+
std::string& to_strip,
204+
const std::string& replace_by = "",
205+
const std::set<std::string>& undesired_strings = {"\n", "\r"});
206+
207+
180208
} /* namespace utils */
181209
} /* namespace eprosima */
182210

cpp_utils/src/cpp/exception/Exception.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@
1717
*/
1818

1919
#include <cpp_utils/exception/Exception.hpp>
20+
#include <cpp_utils/macros/macros.hpp>
2021

2122
namespace eprosima {
2223
namespace utils {
2324

2425
Exception::Exception(
2526
const char* message) noexcept
26-
: message_(message)
27+
: message_(std::string(message))
2728
{
2829
}
2930

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
/**
16+
* @file file_utils.cpp
17+
*/
18+
19+
#include <iostream> // TODO remove
20+
#include <fstream>
21+
22+
#include <cpp_utils/exception/PreconditionNotMet.hpp>
23+
#include <cpp_utils/file/file_utils.hpp>
24+
#include <cpp_utils/utils.hpp>
25+
26+
namespace eprosima {
27+
namespace utils {
28+
29+
std::string file_to_string(
30+
const char* file_name,
31+
bool strip_chars /* = true */)
32+
{
33+
auto strings = file_to_strings(file_name, strip_chars, false);
34+
std::string result;
35+
36+
for (const auto& st : strings)
37+
{
38+
result += st + "\n";
39+
}
40+
41+
return result;
42+
}
43+
44+
std::vector<std::string> file_to_strings(
45+
const char* file_name,
46+
bool strip_chars /* = true */,
47+
bool strip_empty_lines /* = false */)
48+
{
49+
std::string new_line;
50+
std::vector<std::string> result;
51+
52+
// Open file
53+
std::ifstream file(file_name);
54+
55+
if (!file.is_open())
56+
{
57+
throw PreconditionNotMet(
58+
STR_ENTRY << "File <" << file_name << "> could not be read.");
59+
}
60+
61+
while (getline(file, new_line))
62+
{
63+
if (strip_chars)
64+
{
65+
strip_str(new_line);
66+
}
67+
68+
if (!(strip_empty_lines && new_line.empty()))
69+
{
70+
result.push_back(new_line);
71+
}
72+
}
73+
74+
return result;
75+
}
76+
77+
} /* namespace utils */
78+
} /* namespace eprosima */

cpp_utils/src/cpp/utils.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,48 @@ bool is_file_accessible(
116116
return access(file_path, static_cast<FileAccessModeType>(access_mode)) != -1;
117117
}
118118

119+
bool replace_first(
120+
std::string& st,
121+
std::string const& to_replace,
122+
std::string const& replace_by)
123+
{
124+
std::size_t pos = st.find(to_replace);
125+
if (pos == std::string::npos)
126+
{
127+
return false;
128+
}
129+
else
130+
{
131+
st.replace(pos, to_replace.length(), replace_by);
132+
return true;
133+
}
134+
}
135+
136+
unsigned int replace_all(
137+
std::string& st,
138+
std::string const& to_replace,
139+
std::string const& replace_by)
140+
{
141+
unsigned int replacements = 0;
142+
while (replace_first(st, to_replace, replace_by))
143+
{
144+
replacements++;
145+
}
146+
return replacements;
147+
}
148+
149+
unsigned int strip_str(
150+
std::string& to_strip,
151+
const std::string& replace_by /* = "" */,
152+
const std::set<std::string>& undesired_strings /* = {"\r"} */)
153+
{
154+
unsigned int replacements = 0;
155+
for (const auto& undesired : undesired_strings)
156+
{
157+
replacements += replace_all(to_strip, undesired, replace_by);
158+
}
159+
return replacements;
160+
}
161+
119162
} /* namespace utils */
120163
} /* namespace eprosima */

cpp_utils/test/unittest/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# Add test subdirectories
1616
add_subdirectory(event)
1717
add_subdirectory(exception)
18+
add_subdirectory(file)
1819
add_subdirectory(types)
1920
add_subdirectory(macros)
2021
add_subdirectory(math)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright 2021 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
set(TEST_NAME fileTest)
16+
17+
set(TEST_SOURCES
18+
fileTest.cpp
19+
${PROJECT_SOURCE_DIR}/src/cpp/exception/Exception.cpp
20+
${PROJECT_SOURCE_DIR}/src/cpp/Formatter.cpp
21+
${PROJECT_SOURCE_DIR}/src/cpp/file/file_utils.cpp
22+
${PROJECT_SOURCE_DIR}/src/cpp/utils.cpp
23+
)
24+
25+
set(TEST_LIST
26+
read_file_by_lines
27+
read_file_by_lines_no_strip_chars
28+
read_file_by_lines_strip_empty_lines
29+
read_file_one_line
30+
read_file_one_line_strip_chars
31+
read_incorrect_file
32+
)
33+
34+
set(TEST_EXTRA_LIBRARIES
35+
fastcdr
36+
fastrtps
37+
$<$<BOOL:${WIN32}>:iphlpapi$<SEMICOLON>Shlwapi>
38+
)
39+
40+
set(TEST_NEEDED_SOURCES
41+
resources/file.test
42+
)
43+
44+
add_unittest_executable(
45+
"${TEST_NAME}"
46+
"${TEST_SOURCES}"
47+
"${TEST_LIST}"
48+
"${TEST_EXTRA_LIBRARIES}"
49+
"${TEST_NEEDED_SOURCES}"
50+
)

0 commit comments

Comments
 (0)