Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 <xercesc/util/XMLString.hpp>
30 : #include <utils/common/StdDefs.h>
31 :
32 :
33 : // ===========================================================================
34 : // class definitions
35 : // ===========================================================================
36 : /**
37 : * @class StringUtils
38 : * @brief Some static methods for string processing
39 : */
40 : class StringUtils {
41 :
42 : public:
43 :
44 : /// @brief Removes trailing and leading whitechars
45 : static std::string prune(const std::string& str);
46 :
47 : /// @brief Removes trailing zeros (at most 'max')
48 : static std::string pruneZeros(const std::string& str, int max);
49 :
50 : /// @brief Transfers the content to lower case
51 : static std::string to_lower_case(const std::string& str);
52 :
53 : /// @brief Transfers from Latin 1 (ISO-8859-1) to UTF-8
54 : static std::string latin1_to_utf8(std::string str);
55 :
56 : /// @brief Converts german "Umlaute" to their latin-version
57 : static std::string convertUmlaute(std::string str);
58 :
59 : /// @brief Replaces all occurrences of the second string by the third string within the first string
60 : static std::string replace(std::string str, const std::string& what, const std::string& by);
61 :
62 : /// @brief Replaces an environment variable with its value (similar to bash); syntax for a variable is ${NAME}
63 : static std::string substituteEnvironment(const std::string& str, const std::chrono::time_point<std::chrono::system_clock>* const timeRef = nullptr);
64 :
65 : ///@brief Checks whether a given string starts with the prefix
66 : static bool startsWith(const std::string& str, const std::string prefix);
67 :
68 : /// @brief Checks whether a given string ends with the suffix
69 : static bool endsWith(const std::string& str, const std::string suffix);
70 :
71 : //// @brief pads the given string with padding character up to the given total length
72 : static std::string padFront(const std::string& str, int length, char padding);
73 :
74 : /**
75 : * @brief Replaces the standard escapes by their XML entities.
76 : *
77 : * The strings &, <, >, ", and ' are replaced by &, <, >, ", and '
78 : *
79 : * @param[in] orig The original string
80 : * @param[in] maskDoubleHyphen Whether -- in input shall be converted to -- (semantically equivalent but allowed in XML comments)
81 : * @return the string with the escaped sequences
82 : */
83 : static std::string escapeXML(const std::string& orig, const bool maskDoubleHyphen = false);
84 :
85 : /**
86 : * @brief Escape special characters with backslash
87 : */
88 : static std::string escapeShell(const std::string& orig);
89 :
90 : /// @brief An empty string
91 : static std::string emptyString;
92 :
93 : /// @brief encode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
94 : static std::string urlEncode(const std::string& url, const std::string encodeWhich = "");
95 :
96 : /// @brief decode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
97 : static std::string urlDecode(const std::string& encoded);
98 :
99 : /// @brief char to hexadecimal
100 : static std::string charToHex(unsigned char c);
101 :
102 : /// @brief hexadecimal to char
103 : static unsigned char hexToChar(const std::string& str);
104 :
105 : /**@brief converts a string into the integer value described by it by calling the char-type converter, which
106 : * @throw an EmptyData - exception if the given string is empty
107 : * @throw NumberFormatException - exception when the string does not contain an integer
108 : */
109 : static int toInt(const std::string& sData);
110 :
111 : /// @brief converts a string into the integer value described by it
112 : /// @return the default value if the data is empty
113 : static int toIntSecure(const std::string& sData, int def);
114 :
115 : /**@brief converts a string into the long value described by it by calling the char-type converter, which
116 : * @throw an EmptyData - exception if the given string is empty
117 : * @throw NumberFormatException - exception when the string does not contain a long integer
118 : */
119 : static long long int toLong(const std::string& sData);
120 :
121 : /**@brief converts a string with a hex value into the integer value described by it by calling the char-type converter
122 : * @throw an EmptyData - exception if the given string is empty
123 : * @throw a NumberFormatException - exception when the string does not contain an integer
124 : */
125 : static int hexToInt(const std::string& sData);
126 :
127 : /**@brief converts a string into the double value described by it by calling the char-type converter
128 : * @throw an EmptyData - exception if the given string is empty
129 : * @throw a NumberFormatException - exception when the string does not contain a double
130 : */
131 : static double toDouble(const std::string& sData);
132 :
133 : /// @brief converts a string into the integer value described by it
134 : /// @return the default value if the data is empty
135 : static double toDoubleSecure(const std::string& sData, const double def);
136 :
137 : /**@brief converts a string into the bool value described by it by calling the char-type converter
138 : * @return true if the sData is one of the following (case insensitive): '1', 'x', 'true', 'yes', 'on', 't'
139 : * @return false if the sData is one of the following (case insensitive): '0', '-', 'false', 'no', 'off', 'f'
140 : * @throw EmptyData - exception if the given string is empty
141 : * @throw BoolFormatException in any other case
142 : */
143 : static bool toBool(const std::string& sData);
144 :
145 : /// @brief parse a (network) version string
146 : static MMVersion toVersion(const std::string& sData);
147 :
148 : /// @brief parse a distance, length or width value with a unit
149 : static double parseDist(const std::string& sData);
150 :
151 : /// @brief parse a speed value with a unit
152 : static double parseSpeed(const std::string& sData, const bool defaultKmph = true);
153 :
154 : /**@brief converts a 0-terminated XMLCh* array (usually UTF-16, stemming from Xerces) into std::string in UTF-8
155 : * @throw an EmptyData - exception if the given pointer is 0
156 : */
157 101676529 : static inline std::string transcode(const XMLCh* const data) {
158 101676529 : return transcode(data, (int)XERCES_CPP_NAMESPACE::XMLString::stringLen(data));
159 : }
160 :
161 : /**@brief converts a 0-terminated XMLCh* array (usually UTF-16, stemming from Xerces) into std::string in UTF-8 considering the given length
162 : * @throw EmptyData if the given pointer is 0
163 : */
164 : static std::string transcode(const XMLCh* const data, int length);
165 :
166 : /// @brief convert a string from the local codepage to UTF-8
167 : static std::string transcodeFromLocal(const std::string& localString);
168 :
169 : /// @brief convert a string from UTF-8 to the local codepage
170 : static std::string transcodeToLocal(const std::string& utf8String);
171 :
172 : /// @brief remove leading whitespace from string
173 : static std::string trim_left(const std::string s, const std::string& t = " \t\n");
174 :
175 : /// @brief remove trailing whitespace from string
176 : static std::string trim_right(const std::string s, const std::string& t = " \t\n");
177 :
178 : /// @brief remove leading and trailing whitespace
179 : static std::string trim(const std::string s, const std::string& t = " \t\n");
180 :
181 : /// @brief remove leading and trailing whitespace
182 : static std::string wrapText(const std::string s, int width);
183 :
184 : /// @brief must be called when shutting down the xml subsystem
185 : static void resetTranscoder();
186 :
187 : /// @brief adds a new formatted message
188 : // variadic function
189 : template<typename T, typename... Targs>
190 900715 : static const std::string format(const std::string& format, T value, Targs... Fargs) {
191 900715 : std::ostringstream os;
192 900715 : os << std::fixed << std::setprecision(gPrecision);
193 1801112 : _format(format.c_str(), os, value, Fargs...);
194 900715 : return os.str();
195 900715 : }
196 :
197 : private:
198 : static void _format(const char* format, std::ostringstream& os) {
199 900715 : os << format;
200 : }
201 :
202 : /// @brief adds a new formatted message
203 : // variadic function
204 : template<typename T, typename... Targs>
205 2083281 : static void _format(const char* format, std::ostringstream& os, T value, Targs... Fargs) {
206 31894308 : for (; *format != '\0'; format++) {
207 31894308 : if (*format == '%') {
208 2083281 : os << value;
209 2545148 : _format(format + 1, os, Fargs...); // recursive call
210 2083281 : return;
211 : }
212 29811027 : os << *format;
213 : }
214 : }
215 :
216 : static XERCES_CPP_NAMESPACE::XMLLCPTranscoder* myLCPTranscoder;
217 : };
|