Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2026 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file StringUtils.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @author Robert Hilbrich
19 : /// @date unknown
20 : ///
21 : // Some static methods for string processing
22 : /****************************************************************************/
23 : #pragma once
24 : #include <config.h>
25 : #include <string>
26 : #include <chrono>
27 : #include <sstream>
28 : #include <iomanip>
29 : #include <utils/common/StdDefs.h>
30 :
31 :
32 : // ===========================================================================
33 : // class definitions
34 : // ===========================================================================
35 : /**
36 : * @class StringUtils
37 : * @brief Some static methods for string processing
38 : */
39 : class StringUtils {
40 :
41 : public:
42 :
43 : /// @brief Removes trailing and leading whitechars
44 : static std::string prune(const std::string& str);
45 :
46 : /// @brief Removes trailing zeros (at most 'max')
47 : static std::string pruneZeros(const std::string& str, int max);
48 :
49 : /// @brief Transfers the content to lower case
50 : static std::string to_lower_case(const std::string& str);
51 :
52 : /// @brief Transfers the content to upper case
53 : static std::string to_upper_case(const std::string& str);
54 :
55 : /// @brief Transfers from Latin 1 (ISO-8859-1) to UTF-8
56 : static std::string latin1_to_utf8(std::string str);
57 :
58 : /// @brief Converts german "Umlaute" to their latin-version
59 : static std::string convertUmlaute(std::string str);
60 :
61 : /// @brief Replaces all occurrences of the second string by the third string within the first string
62 : static std::string replace(std::string str, const std::string& what, const std::string& by);
63 :
64 : /// @brief Replaces an environment variable with its value (similar to bash); syntax for a variable is ${NAME}
65 : static std::string substituteEnvironment(const std::string& str, const std::chrono::time_point<std::chrono::system_clock>* const timeRef = nullptr);
66 :
67 : /// @brief Returns an ISO8601 formatted time string with microsecond precision
68 : static std::string isoTimeString(const std::chrono::time_point<std::chrono::system_clock>* const timeRef = nullptr);
69 :
70 : ///@brief Checks whether a given string starts with the prefix
71 : static bool startsWith(const std::string& str, const std::string prefix);
72 :
73 : /// @brief Checks whether a given string ends with the suffix
74 : static bool endsWith(const std::string& str, const std::string suffix);
75 :
76 : //// @brief pads the given string with padding character up to the given total length
77 : static std::string padFront(const std::string& str, int length, char padding);
78 :
79 : /**
80 : * @brief Replaces the standard escapes by their XML entities.
81 : *
82 : * The strings &, <, >, ", and ' are replaced by &, <, >, ", and '
83 : *
84 : * @param[in] orig The original string
85 : * @param[in] maskDoubleHyphen Whether -- in input shall be converted to -- (semantically equivalent but allowed in XML comments)
86 : * @return the string with the escaped sequences
87 : */
88 : static std::string escapeXML(const std::string& orig, const bool maskDoubleHyphen = false);
89 :
90 : /**
91 : * @brief Escape special characters with backslash
92 : */
93 : static std::string escapeShell(const std::string& orig);
94 :
95 : /// @brief An empty string
96 : static std::string emptyString;
97 :
98 : /// @brief encode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
99 : static std::string urlEncode(const std::string& url, const std::string encodeWhich = "");
100 :
101 : /// @brief decode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
102 : static std::string urlDecode(const std::string& encoded);
103 :
104 : /// @brief char to hexadecimal
105 : static std::string charToHex(unsigned char c);
106 :
107 : /// @brief hexadecimal to char
108 : static unsigned char hexToChar(const std::string& str);
109 :
110 : /**@brief converts a string into the integer value described by it by calling the char-type converter, which
111 : * @throw an EmptyData - exception if the given string is empty
112 : * @throw NumberFormatException - exception when the string does not contain an integer
113 : */
114 : static int toInt(const std::string& sData);
115 :
116 : /// @brief check if the given sData can be converted to int
117 : static bool isInt(const std::string& sData);
118 :
119 : /// @brief converts a string into the integer value described by it
120 : /// @return the default value if the data is empty
121 : static int toIntSecure(const std::string& sData, int def);
122 :
123 : /**@brief converts a string into the long value described by it by calling the char-type converter, which
124 : * @throw an EmptyData - exception if the given string is empty
125 : * @throw NumberFormatException - exception when the string does not contain a long integer
126 : */
127 : static long long int toLong(const std::string& sData);
128 :
129 : /// @brief Check if the given sData can be converted to long
130 : static bool isLong(const std::string& sData);
131 :
132 : /**@brief converts a string with a hex value into the integer value described by it by calling the char-type converter
133 : * @throw an EmptyData - exception if the given string is empty
134 : * @throw a NumberFormatException - exception when the string does not contain an integer
135 : */
136 : static int hexToInt(const std::string& sData);
137 :
138 : /// @brief check if the given string can be converted to hex
139 : static bool isHex(std::string sData);
140 :
141 : /**@brief converts a string into the double value described by it by calling the char-type converter
142 : * @throw an EmptyData - exception if the given string is empty
143 : * @throw a NumberFormatException - exception when the string does not contain a double
144 : */
145 : static double toDouble(const std::string& sData);
146 :
147 : /// @brief check if the given sData can be conveted to double
148 : static bool isDouble(const std::string& sData);
149 :
150 : /// @brief converts a string into the integer value described by it
151 : /// @return the default value if the data is empty
152 : static double toDoubleSecure(const std::string& sData, const double def);
153 :
154 : /**@brief converts a string into the bool value described by it by calling the char-type converter
155 : * @return true if the sData is one of the following (case insensitive): '1', 'x', 'true', 'yes', 'on', 't'
156 : * @return false if the sData is one of the following (case insensitive): '0', '-', 'false', 'no', 'off', 'f'
157 : * @throw EmptyData - exception if the given string is empty
158 : * @throw BoolFormatException in any other case
159 : */
160 : static bool toBool(const std::string& sData);
161 :
162 : /// @brief check if the given value can be converted to bool
163 : static bool isBool(const std::string& sData);
164 :
165 : /// @brief parse a (network) version string
166 : static MMVersion toVersion(const std::string& sData);
167 :
168 : /// @brief parse a distance, length or width value with a unit
169 : static double parseDist(const std::string& sData);
170 :
171 : /// @brief parse a speed value with a unit
172 : static double parseSpeed(const std::string& sData, const bool defaultKmph = true);
173 :
174 : /// @brief remove leading whitespace from string
175 : static std::string trim_left(const std::string s, const std::string& t = " \t\n");
176 :
177 : /// @brief remove trailing whitespace from string
178 : static std::string trim_right(const std::string s, const std::string& t = " \t\n");
179 :
180 : /// @brief remove leading and trailing whitespace
181 : static std::string trim(const std::string s, const std::string& t = " \t\n");
182 :
183 : /// @brief remove leading and trailing whitespace
184 : static std::string wrapText(const std::string s, int width);
185 :
186 : /// @brief write with maximum precision if needed but remove trailing zeros
187 : static std::string adjustDecimalValue(double value, int precision);
188 :
189 : /// @brief adds a new formatted message
190 : // variadic function
191 : template<typename T, typename... Targs>
192 4769243 : static const std::string format(const std::string& format, T value, Targs... Fargs) {
193 4769243 : std::ostringstream os;
194 4769243 : os << std::fixed << std::setprecision(gPrecision);
195 9537398 : _format(format.c_str(), os, value, Fargs...);
196 4769243 : return os.str();
197 4769243 : }
198 :
199 : private:
200 : static void _format(const char* format, std::ostringstream& os) {
201 4769243 : os << format;
202 : }
203 :
204 : /// @brief adds a new formatted message
205 : // variadic function
206 : template<typename T, typename... Targs>
207 13497175 : static void _format(const char* format, std::ostringstream& os, T value, Targs... Fargs) {
208 210888546 : for (; *format != '\0'; format++) {
209 210888546 : if (*format == '%') {
210 13497175 : os << value;
211 17743807 : _format(format + 1, os, Fargs...); // recursive call
212 13497175 : return;
213 : }
214 197391371 : os << *format;
215 : }
216 : }
217 : };
|