OGS
StringTools.cpp
Go to the documentation of this file.
1
15#include "StringTools.h"
16
17#include <algorithm>
18#include <boost/algorithm/string/replace.hpp>
19#include <chrono>
20#include <cstdarg>
21#include <cstdio>
22#include <iterator>
23#include <random>
24
25#include "Error.h"
26
27namespace BaseLib
28{
29std::vector<std::string> splitString(std::string const& str)
30{
31 std::istringstream str_stream(str);
32 std::vector<std::string> items;
33 std::copy(std::istream_iterator<std::string>(str_stream),
34 std::istream_iterator<std::string>(),
35 std::back_inserter(items));
36 return items;
37}
38
39std::list<std::string> splitString(const std::string& str, char delim)
40{
41 std::list<std::string> strList;
42 std::stringstream ss(str);
43 std::string item;
44 while (std::getline(ss, item, delim))
45 {
46 strList.push_back(item);
47 }
48 return strList;
49}
50
51std::string replaceString(const std::string& searchString,
52 const std::string& replaceString,
53 std::string stringToReplace)
54{
55 boost::replace_all(stringToReplace, searchString, replaceString);
56 return stringToReplace;
57}
58
59void trim(std::string& str, char ch)
60{
61 std::string::size_type pos = str.find_last_not_of(ch);
62 if (pos != std::string::npos)
63 {
64 str.erase(pos + 1);
65 pos = str.find_first_not_of(ch);
66 if (pos != std::string::npos)
67 {
68 str.erase(0, pos);
69 }
70 }
71 else
72 {
73 str.erase(str.begin(), str.end());
74 }
75}
76
77void simplify(std::string& str)
78{
79 trim(str);
80 str.erase(std::unique(str.begin(),
81 str.end(),
82 [](char a, char b) { return a == ' ' && b == ' '; }),
83 str.end());
84}
85
86std::string format(const char* format_str, ...)
87{
88 va_list args;
89 va_start(args, format_str);
90 // get the number of chars to write
91 va_list args_tmp;
92 va_copy(args_tmp, args);
93 int char_length = std::vsnprintf(nullptr, 0, format_str, args_tmp);
94 va_end(args_tmp);
95 // allocate buffer and store formatted output there
96 std::vector<char> buffer(char_length + 1); // note +1 for null terminator
97 vsnprintf(buffer.data(), buffer.size(), format_str, args);
98 va_end(args);
99
100 return std::string(buffer.data());
101}
102
103std::string randomString(std::size_t const length)
104{
105 static constexpr char charset[] =
106 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
107
108 static const auto seed = static_cast<std::mt19937::result_type>(
109 std::chrono::system_clock::now().time_since_epoch().count());
110 static std::mt19937 generator{seed};
111 static std::uniform_int_distribution<unsigned short> distribution(
112 0, sizeof(charset) - 2);
113
114 std::string s(length, 0);
115 std::generate_n(begin(s), length,
116 [&]() { return charset[distribution(generator)]; });
117
118 return s;
119}
120
121std::string getUniqueName(std::vector<std::string> const& existing_names,
122 std::string const& input_name)
123{
124 std::string result_name = input_name;
125 std::size_t count = 1;
126 while (std::find(existing_names.cbegin(),
127 existing_names.cend(),
128 result_name) != existing_names.end())
129 {
130 count++;
131 result_name = input_name + "-" + std::to_string(count);
132 }
133 return result_name;
134}
135
136std::vector<int> splitMaterialIdString(std::string const& material_id_string)
137{
138 auto const material_ids_strings =
139 BaseLib::splitString(material_id_string, ',');
140
141 std::vector<int> material_ids;
142 for (auto& mid_str : material_ids_strings)
143 {
144 std::size_t num_chars_processed = 0;
145 int material_id;
146 try
147 {
148 material_id = std::stoi(mid_str, &num_chars_processed);
149 }
150 catch (std::invalid_argument&)
151 {
152 OGS_FATAL(
153 "Could not parse material ID from '{}' to a valid "
154 "integer.",
155 mid_str);
156 }
157 catch (std::out_of_range&)
158 {
159 OGS_FATAL(
160 "Could not parse material ID from '{}'. The integer value "
161 "of the given string exceeds the permitted range.",
162 mid_str);
163 }
164
165 if (num_chars_processed != mid_str.size())
166 {
167 // Not the whole string has been parsed. Check the rest.
168 if (auto const it = std::find_if_not(
169 begin(mid_str) + num_chars_processed, end(mid_str),
170 [](unsigned char const c) { return std::isspace(c); });
171 it != end(mid_str))
172 {
173 OGS_FATAL(
174 "Could not parse material ID from '{}'. Please "
175 "separate multiple material IDs by comma only. "
176 "Invalid character: '{}' at position {}.",
177 mid_str, *it, distance(begin(mid_str), it));
178 }
179 }
180
181 material_ids.push_back(material_id);
182 };
183
184 return material_ids;
185}
186
187} // end namespace BaseLib
#define OGS_FATAL(...)
Definition Error.h:26
Definition of string helper functions.
void simplify(std::string &str)
std::vector< int > splitMaterialIdString(std::string const &material_id_string)
std::string randomString(std::size_t const length)
Returns a random string of the given length containing just a-z,A-Z,0-9.
std::string getUniqueName(std::vector< std::string > const &existing_names, std::string const &input_name)
Append '-' and a number such that the name is unique.
std::string replaceString(const std::string &searchString, const std::string &replaceString, std::string stringToReplace)
void trim(std::string &str, char ch)
std::string format(const char *format_str,...)
std::vector< std::string > splitString(std::string const &str)