Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
StringUtils.cpp
Go to the documentation of this file.
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/****************************************************************************/
21// Some static methods for string processing
22/****************************************************************************/
23#include <config.h>
24
25#include <string>
26#include <iostream>
27#include <cstdio>
28#include <cstring>
29#include <regex>
30#ifdef WIN32
31#define NOMINMAX
32#include <windows.h>
33#undef NOMINMAX
34#else
35#include <unistd.h>
36#endif
40#include "StringUtils.h"
41
42#define KM_PER_MILE 1.609344
43
44
45// ===========================================================================
46// static member definitions
47// ===========================================================================
48std::string StringUtils::emptyString;
49
50
51// ===========================================================================
52// method definitions
53// ===========================================================================
54std::string
55StringUtils::prune(const std::string& str) {
56 const std::string::size_type endpos = str.find_last_not_of(" \t\n\r");
57 if (std::string::npos != endpos) {
58 const int startpos = (int)str.find_first_not_of(" \t\n\r");
59 return str.substr(startpos, endpos - startpos + 1);
60 }
61 return "";
62}
63
64
65std::string
66StringUtils::pruneZeros(const std::string& str, int max) {
67 const std::string::size_type endpos = str.find_last_not_of("0");
68 if (endpos != std::string::npos && str.back() == '0') {
69 std::string res = str.substr(0, MAX2((int)str.size() - max, (int)endpos + 1));
70 return res;
71 }
72 return str;
73}
74
75std::string
76StringUtils::to_lower_case(const std::string& str) {
77 std::string s = str;
78 std::transform(s.begin(), s.end(), s.begin(), [](char c) {
79 return (char)::tolower(c);
80 });
81 return s;
82}
83
84
85std::string
86StringUtils::to_upper_case(const std::string& str) {
87 std::string s = str;
88 std::transform(s.begin(), s.end(), s.begin(), [](char c) {
89 return (char)::toupper(c);
90 });
91 return s;
92}
93
94
95std::string
97 // inspired by http://stackoverflow.com/questions/4059775/convert-iso-8859-1-strings-to-utf-8-in-c-c
98 std::string result;
99 for (const auto& c : str) {
100 const unsigned char uc = (unsigned char)c;
101 if (uc < 128) {
102 result += uc;
103 } else {
104 result += (char)(0xc2 + (uc > 0xbf));
105 result += (char)((uc & 0x3f) + 0x80);
106 }
107 }
108 return result;
109}
110
111
112std::string
114 str = replace(str, "\xE4", "ae");
115 str = replace(str, "\xC4", "Ae");
116 str = replace(str, "\xF6", "oe");
117 str = replace(str, "\xD6", "Oe");
118 str = replace(str, "\xFC", "ue");
119 str = replace(str, "\xDC", "Ue");
120 str = replace(str, "\xDF", "ss");
121 str = replace(str, "\xC9", "E");
122 str = replace(str, "\xE9", "e");
123 str = replace(str, "\xC8", "E");
124 str = replace(str, "\xE8", "e");
125 return str;
126}
127
128
129std::string
130StringUtils::replace(std::string str, const std::string& what, const std::string& by) {
131 std::string::size_type idx = str.find(what);
132 const int what_len = (int)what.length();
133 if (what_len > 0) {
134 const int by_len = (int)by.length();
135 while (idx != std::string::npos) {
136 str = str.replace(idx, what_len, by);
137 idx = str.find(what, idx + by_len);
138 }
139 }
140 return str;
141}
142
143
144std::string
145StringUtils::substituteEnvironment(const std::string& str, const std::chrono::time_point<std::chrono::system_clock>* const timeRef) {
146 std::string s = str;
147 if (timeRef != nullptr) {
148 const std::string::size_type localTimeIndex = str.find("${LOCALTIME}");
149 const std::string::size_type utcIndex = str.find("${UTC}");
150 const bool isUTC = utcIndex != std::string::npos;
151 if (localTimeIndex != std::string::npos || isUTC) {
152 const time_t rawtime = std::chrono::system_clock::to_time_t(*timeRef);
153 char buffer [80];
154 struct tm* timeinfo = isUTC ? gmtime(&rawtime) : localtime(&rawtime);
155 strftime(buffer, 80, "%Y-%m-%d-%H-%M-%S.", timeinfo);
156 auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(*timeRef);
157 auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(*timeRef - seconds);
158 const std::string micro = buffer + toString(microseconds.count());
159 if (isUTC) {
160 s.replace(utcIndex, 6, micro);
161 } else {
162 s.replace(localTimeIndex, 12, micro);
163 }
164 }
165 }
166 const std::string::size_type pidIndex = str.find("${PID}");
167 if (pidIndex != std::string::npos) {
168#ifdef WIN32
169 s.replace(pidIndex, 6, toString(::GetCurrentProcessId()));
170#else
171 s.replace(pidIndex, 6, toString(::getpid()));
172#endif
173 }
174 if (std::getenv("SUMO_LOGO") == nullptr) {
175 s = replace(s, "${SUMO_LOGO}", "${SUMO_HOME}/data/logo/sumo-128x138.png");
176 }
177 const std::string::size_type tildeIndex = str.find("~");
178 if (tildeIndex == 0) {
179 s.replace(0, 1, "${HOME}");
180 }
181 s = replace(s, ",~", ",${HOME}");
182#ifdef WIN32
183 if (std::getenv("HOME") == nullptr) {
184 s = replace(s, "${HOME}", "${USERPROFILE}");
185 }
186#endif
187
188 // Expression for an environment variables, e.g. ${NAME}
189 // Note: - R"(...)" is a raw string literal syntax to simplify a regex declaration
190 // - .+? looks for the shortest match (non-greedy)
191 // - (.+?) defines a "subgroup" which is already stripped of the $ and {, }
192 std::regex envVarExpr(R"(\$\{(.+?)\})");
193
194 // Are there any variables in this string?
195 std::smatch match;
196 std::string strIter = s;
197
198 // Loop over the entire value string and look for variable names
199 while (std::regex_search(strIter, match, envVarExpr)) {
200 std::string varName = match[1];
201
202 // Find the variable in the environment and its value
203 std::string varValue;
204 if (std::getenv(varName.c_str()) != nullptr) {
205 varValue = std::getenv(varName.c_str());
206 }
207
208 // Replace the variable placeholder with its value in the original string
209 s = std::regex_replace(s, std::regex("\\$\\{" + varName + "\\}"), varValue);
210
211 // Continue the loop with the remainder of the string
212 strIter = match.suffix();
213 }
214 return s;
215}
216
217
218std::string
219StringUtils::isoTimeString(const std::chrono::time_point<std::chrono::system_clock>* const timeRef) {
220 const std::chrono::system_clock::time_point now = timeRef == nullptr ? std::chrono::system_clock::now() : *timeRef;
221 const auto now_seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
222 const std::time_t now_c = std::chrono::system_clock::to_time_t(now);
223 const auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(now - now_seconds).count();
224 std::tm local_tm = *std::localtime(&now_c);
225
226 // Get the time zone offset
227 std::time_t utc_time = std::time(nullptr);
228 std::tm utc_tm = *std::gmtime(&utc_time);
229 const double offset = std::difftime(std::mktime(&local_tm), std::mktime(&utc_tm)) / 3600.0;
230 const int hours_offset = static_cast<int>(offset);
231 const int minutes_offset = static_cast<int>((offset - hours_offset) * 60);
232
233 // Format the time
234 std::ostringstream oss;
235 char buf[32];
236 std::strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S", &local_tm);
237 oss << buf << "."
238 << std::setw(6) << std::setfill('0') << std::abs(microseconds)
239 << (hours_offset >= 0 ? "+" : "-")
240 << std::setw(2) << std::setfill('0') << std::abs(hours_offset) << ":"
241 << std::setw(2) << std::setfill('0') << std::abs(minutes_offset);
242 return oss.str();
243}
244
245
246bool
247StringUtils::startsWith(const std::string& str, const std::string prefix) {
248 return str.compare(0, prefix.length(), prefix) == 0;
249}
250
251
252bool
253StringUtils::endsWith(const std::string& str, const std::string suffix) {
254 if (str.length() >= suffix.length()) {
255 return str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
256 } else {
257 return false;
258 }
259}
260
261
262std::string
263StringUtils::padFront(const std::string& str, int length, char padding) {
264 return std::string(MAX2(0, length - (int)str.size()), padding) + str;
265}
266
267
268std::string
269StringUtils::escapeXML(const std::string& orig, const bool maskDoubleHyphen) {
270 std::string result = replace(orig, "&", "&amp;");
271 result = replace(result, ">", "&gt;");
272 result = replace(result, "<", "&lt;");
273 result = replace(result, "\"", "&quot;");
274 if (maskDoubleHyphen) {
275 result = replace(result, "--", "&#45;&#45;");
276 }
277 for (char invalid = '\1'; invalid < ' '; invalid++) {
278 result = replace(result, std::string(1, invalid).c_str(), "");
279 }
280 return replace(result, "'", "&apos;");
281}
282
283
284std::string
285StringUtils::escapeShell(const std::string& orig) {
286 return replace(orig, "\"", "\\\"");
287}
288
289
290std::string
291StringUtils::escapeCSV(const std::string& orig, const char separator, const char quote) {
292 const std::string chars{separator, quote};
293 if (orig.find_first_of(chars) == std::string::npos) {
294 return orig;
295 }
296 const std::string quoteStr{quote};
297 return quoteStr + replace(orig, quoteStr, {'\\', quote}) + quoteStr;
298}
299
300
301std::string
302StringUtils::urlEncode(const std::string& toEncode, const std::string encodeWhich) {
303 std::ostringstream out;
304
305 for (int i = 0; i < (int)toEncode.length(); ++i) {
306 const char t = toEncode.at(i);
307
308 if ((encodeWhich != "" && encodeWhich.find(t) == std::string::npos) ||
309 (encodeWhich == "" &&
310 ((t >= 45 && t <= 57) || // hyphen, period, slash, 0-9
311 (t >= 65 && t <= 90) || // A-Z
312 t == 95 || // underscore
313 (t >= 97 && t <= 122) || // a-z
314 t == 126)) // tilde
315 ) {
316 out << toEncode.at(i);
317 } else {
318 out << charToHex(toEncode.at(i));
319 }
320 }
321
322 return out.str();
323}
324
325
326std::string
327StringUtils::urlDecode(const std::string& toDecode) {
328 std::ostringstream out;
329
330 for (int i = 0; i < (int)toDecode.length(); ++i) {
331 if (toDecode.at(i) == '%') {
332 std::string str(toDecode.substr(i + 1, 2));
333 out << hexToChar(str);
334 i += 2;
335 } else {
336 out << toDecode.at(i);
337 }
338 }
339
340 return out.str();
341}
342
343std::string
344StringUtils::charToHex(unsigned char c) {
345 short i = c;
346
347 std::stringstream s;
348
349 s << "%" << std::setw(2) << std::setfill('0') << std::hex << i;
350
351 return s.str();
352}
353
354
355unsigned char
356StringUtils::hexToChar(const std::string& str) {
357 short c = 0;
358 if (!str.empty()) {
359 std::istringstream in(str);
360 in >> std::hex >> c;
361 if (in.fail()) {
362 throw NumberFormatException(str + " could not be interpreted as hex");
363 }
364 }
365 return static_cast<unsigned char>(c);
366}
367
368
369int
370StringUtils::toInt(const std::string& sData) {
371 long long int result = toLong(sData);
372 if (result > std::numeric_limits<int>::max() || result < std::numeric_limits<int>::min()) {
373 throw NumberFormatException(toString(result) + " int overflow");
374 }
375 return (int)result;
376}
377
378
379bool
380StringUtils::isInt(const std::string& sData) {
381 // first check if can be converted to long int
382 if (isLong(sData)) {
383 const long long int result = toLong(sData);
384 // now check if the result is in the range of an int
385 return ((result <= std::numeric_limits<int>::max()) && (result >= std::numeric_limits<int>::min()));
386 }
387 return false;
388}
389
390
391int
392StringUtils::toIntSecure(const std::string& sData, int def) {
393 if (sData.length() == 0) {
394 return def;
395 }
396 return toInt(sData);
397}
398
399
400long long int
401StringUtils::toLong(const std::string& sData) {
402 const char* const data = sData.c_str();
403 if (data == 0 || data[0] == 0) {
404 throw EmptyData();
405 }
406 char* end;
407 errno = 0;
408#ifdef _MSC_VER
409 long long int ret = _strtoi64(data, &end, 10);
410#else
411 long long int ret = strtoll(data, &end, 10);
412#endif
413 if (errno == ERANGE) {
414 errno = 0;
415 throw NumberFormatException("(long long integer range) " + sData);
416 }
417 if ((int)(end - data) != (int)strlen(data)) {
418 throw NumberFormatException("(long long integer format) " + sData);
419 }
420 return ret;
421}
422
423
424bool
425StringUtils::isLong(const std::string& sData) {
426 const char* const data = sData.c_str();
427 if (data == 0 || data[0] == 0) {
428 return false;
429 }
430 char* end;
431 // reset errno before parsing, to keep errors
432 errno = 0;
433 // continue depending of current plattform
434#ifdef _MSC_VER
435 _strtoi64(data, &end, 10);
436#else
437 strtoll(data, &end, 10);
438#endif
439 // check out of range
440 if (errno == ERANGE) {
441 return false;
442 }
443 // check length of converted data
444 if ((int)(end - data) != (int)strlen(data)) {
445 return false;
446 }
447 return true;
448}
449
450
451int
452StringUtils::hexToInt(const std::string& sData) {
453 if (sData.length() == 0) {
454 throw EmptyData();
455 }
456 size_t idx = 0;
457 int result;
458 try {
459 if (sData[0] == '#') { // for html color codes
460 result = std::stoi(sData.substr(1), &idx, 16);
461 idx++;
462 } else {
463 result = std::stoi(sData, &idx, 16);
464 }
465 } catch (...) {
466 throw NumberFormatException("(hex integer format) " + sData);
467 }
468 if (idx != sData.length()) {
469 throw NumberFormatException("(hex integer format) " + sData);
470 }
471 return result;
472}
473
474
475bool
476StringUtils::isHex(std::string sData) {
477 if (sData.length() == 0) {
478 return false;
479 }
480 // remove the first character (for HTML color codes)
481 if (sData[0] == '#') {
482 sData = sData.substr(1);
483 }
484 const char* sDataPtr = sData.c_str();
485 char* returnPtr;
486 // reset errno
487 errno = 0;
488 // call string to long (size 16) from standard library
489 strtol(sDataPtr, &returnPtr, 16);
490 // check out of range
491 if (errno == ERANGE) {
492 return false;
493 }
494 // check if there was an error converting sDataPtr to double,
495 if (sDataPtr == returnPtr) {
496 return false;
497 }
498 // compare size of start and end points
499 if (static_cast<size_t>(returnPtr - sDataPtr) != sData.size()) {
500 return false;
501 }
502 return true;
503}
504
505
506double
507StringUtils::toDouble(const std::string& sData) {
508 if (sData.size() == 0) {
509 throw EmptyData();
510 }
511 try {
512 size_t idx = 0;
513 const double result = std::stod(sData, &idx);
514 if (idx != sData.size()) {
515 throw NumberFormatException("(double format) " + sData);
516 } else {
517 return result;
518 }
519 } catch (...) {
520 // invalid_argument or out_of_range
521 throw NumberFormatException("(double) " + sData);
522 }
523}
524
525
526bool
527StringUtils::isDouble(const std::string& sData) {
528 if (sData.size() == 0) {
529 return false;
530 }
531 const char* sDataPtr = sData.c_str();
532 char* returnPtr;
533 // reset errno
534 errno = 0;
535 // call string to double from standard library
536 strtod(sDataPtr, &returnPtr);
537 // check out of range
538 if (errno == ERANGE) {
539 return false;
540 }
541 // check if there was an error converting sDataPtr to double,
542 if (sDataPtr == returnPtr) {
543 return false;
544 }
545 // compare size of start and end points
546 if (static_cast<size_t>(returnPtr - sDataPtr) != sData.size()) {
547 return false;
548 }
549 return true;
550}
551
552
553double
554StringUtils::toDoubleSecure(const std::string& sData, const double def) {
555 if (sData.length() == 0) {
556 return def;
557 }
558 return toDouble(sData);
559}
560
561
562bool
563StringUtils::toBool(const std::string& sData) {
564 if (sData.length() == 0) {
565 throw EmptyData();
566 }
567 const std::string s = to_lower_case(sData);
568 if (s == "1" || s == "yes" || s == "true" || s == "on" || s == "x" || s == "t") {
569 return true;
570 }
571 if (s == "0" || s == "no" || s == "false" || s == "off" || s == "-" || s == "f") {
572 return false;
573 }
574 throw BoolFormatException(s);
575}
576
577
578bool
579StringUtils::isBool(const std::string& sData) {
580 if (sData.length() == 0) {
581 return false;
582 }
583 const std::string s = to_lower_case(sData);
584 // check true values
585 if (s == "1" || s == "yes" || s == "true" || s == "on" || s == "x" || s == "t") {
586 return true;
587 }
588 // check false values
589 if (s == "0" || s == "no" || s == "false" || s == "off" || s == "-" || s == "f") {
590 return true;
591 }
592 // no valid true or false values
593 return false;
594}
595
596
598StringUtils::toVersion(const std::string& sData) {
599 std::vector<std::string> parts = StringTokenizer(sData, ".").getVector();
600 return MMVersion(toInt(parts.front()), toDouble(parts.back()));
601}
602
603
604double
605StringUtils::parseDist(const std::string& sData) {
606 if (sData.size() == 0) {
607 throw EmptyData();
608 }
609 try {
610 size_t idx = 0;
611 const double result = std::stod(sData, &idx);
612 if (idx != sData.size()) {
613 const std::string unit = prune(sData.substr(idx));
614 if (unit == "m" || unit == "metre" || unit == "meter" || unit == "metres" || unit == "meters") {
615 return result;
616 }
617 if (unit == "km" || unit == "kilometre" || unit == "kilometer" || unit == "kilometres" || unit == "kilometers") {
618 return result * 1000.;
619 }
620 if (unit == "mi" || unit == "mile" || unit == "miles") {
621 return result * 1000. * KM_PER_MILE;
622 }
623 if (unit == "nmi") {
624 return result * 1852.;
625 }
626 if (unit == "ft" || unit == "foot" || unit == "feet") {
627 return result * 12. * 0.0254;
628 }
629 if (unit == "\"" || unit == "in" || unit == "inch" || unit == "inches") {
630 return result * 0.0254;
631 }
632 if (unit[0] == '\'') {
633 double inches = 12 * result;
634 if (unit.length() > 1) {
635 inches += std::stod(unit.substr(1), &idx);
636 if (unit.substr(idx) == "\"") {
637 return inches * 0.0254;
638 }
639 }
640 }
641 throw NumberFormatException("(distance format) " + sData);
642 } else {
643 return result;
644 }
645 } catch (...) {
646 // invalid_argument or out_of_range
647 throw NumberFormatException("(double) " + sData);
648 }
649}
650
651
652double
653StringUtils::parseSpeed(const std::string& sData, const bool defaultKmph) {
654 if (sData.size() == 0) {
655 throw EmptyData();
656 }
657 try {
658 size_t idx = 0;
659 const double result = std::stod(sData, &idx);
660 if (idx != sData.size()) {
661 const std::string unit = prune(sData.substr(idx));
662 if (unit == "km/h" || unit == "kph" || unit == "kmh" || unit == "kmph") {
663 return result / 3.6;
664 }
665 if (unit == "m/s") {
666 return result;
667 }
668 if (unit == "mph") {
669 return result * KM_PER_MILE / 3.6;
670 }
671 if (unit == "knots") {
672 return result * 1.852 / 3.6;
673 }
674 throw NumberFormatException("(speed format) " + sData);
675 } else {
676 return defaultKmph ? result / 3.6 : result;
677 }
678 } catch (...) {
679 // invalid_argument or out_of_range
680 throw NumberFormatException("(double) " + sData);
681 }
682}
683
684
685
686std::string
687StringUtils::trim_left(const std::string s, const std::string& t) {
688 std::string result = s;
689 result.erase(0, s.find_first_not_of(t));
690 return result;
691}
692
693std::string
694StringUtils::trim_right(const std::string s, const std::string& t) {
695 std::string result = s;
696 result.erase(s.find_last_not_of(t) + 1);
697 return result;
698}
699
700std::string
701StringUtils::trim(const std::string s, const std::string& t) {
702 return trim_right(trim_left(s, t), t);
703}
704
705
706std::string
707StringUtils::wrapText(const std::string s, int width) {
708 std::vector<std::string> parts = StringTokenizer(s).getVector();
709 std::string result;
710 std::string line;
711 bool firstLine = true;
712 bool firstWord = true;
713 for (std::string p : parts) {
714 if ((int)(line.size() + p.size()) < width || firstWord) {
715 if (firstWord) {
716 firstWord = false;
717 } else {
718 line += " ";
719 }
720 line += p;
721 } else {
722 if (firstLine) {
723 firstLine = false;
724 } else {
725 result += "\n";
726 }
727 result += line;
728 line.clear();
729 line += p;
730 }
731 }
732 if (line.size() > 0) {
733 if (firstLine) {
734 firstLine = false;
735 } else {
736 result += "\n";
737 }
738 result += line;
739 }
740 return result;
741}
742
743
744std::string
745StringUtils::adjustDecimalValue(double value, int precision) {
746 // obtain value in string format with 20 decimals precision
747 auto valueStr = toString(value, precision);
748 // now clear all zeros
749 while (valueStr.size() > 1) {
750 if (valueStr.back() == '0') {
751 valueStr.pop_back();
752 } else if (valueStr.back() == '.') {
753 valueStr.pop_back();
754 return valueStr;
755 } else {
756 return valueStr;
757 }
758 }
759 return valueStr;
760}
761
762
763/****************************************************************************/
std::pair< int, double > MMVersion
(M)ajor/(M)inor version for written networks and default version for loading
Definition StdDefs.h:71
T MAX2(T a, T b)
Definition StdDefs.h:86
#define KM_PER_MILE
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
std::vector< std::string > getVector()
return vector of strings
static std::string pruneZeros(const std::string &str, int max)
Removes trailing zeros (at most 'max')
static std::string urlEncode(const std::string &url, const std::string encodeWhich="")
encode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
static bool isDouble(const std::string &sData)
check if the given sData can be conveted to double
static MMVersion toVersion(const std::string &sData)
parse a (network) version string
static bool isBool(const std::string &sData)
check if the given value can be converted to bool
static std::string to_upper_case(const std::string &str)
Transfers the content to upper case.
static std::string charToHex(unsigned char c)
char to hexadecimal
static std::string urlDecode(const std::string &encoded)
decode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)
static long long int toLong(const std::string &sData)
converts a string into the long value described by it by calling the char-type converter,...
static double toDoubleSecure(const std::string &sData, const double def)
converts a string into the integer value described by it
static std::string trim(const std::string s, const std::string &t=" \t\n")
remove leading and trailing whitespace
static std::string to_lower_case(const std::string &str)
Transfers the content to lower case.
static std::string trim_right(const std::string s, const std::string &t=" \t\n")
remove trailing whitespace from string
static std::string trim_left(const std::string s, const std::string &t=" \t\n")
remove leading whitespace from string
static std::string escapeShell(const std::string &orig)
Escape special characters with backslash.
static std::string replace(std::string str, const std::string &what, const std::string &by)
Replaces all occurrences of the second string by the third string within the first string.
static int hexToInt(const std::string &sData)
converts a string with a hex value into the integer value described by it by calling the char-type co...
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
static std::string escapeXML(const std::string &orig, const bool maskDoubleHyphen=false)
Replaces the standard escapes by their XML entities.
static bool isHex(std::string sData)
check if the given string can be converted to hex
static std::string latin1_to_utf8(std::string str)
Transfers from Latin 1 (ISO-8859-1) to UTF-8.
static std::string prune(const std::string &str)
Removes trailing and leading whitechars.
static std::string padFront(const std::string &str, int length, char padding)
static std::string convertUmlaute(std::string str)
Converts german "Umlaute" to their latin-version.
static double parseDist(const std::string &sData)
parse a distance, length or width value with a unit
static std::string adjustDecimalValue(double value, int precision)
write with maximum precision if needed but remove trailing zeros
static unsigned char hexToChar(const std::string &str)
hexadecimal to char
static bool startsWith(const std::string &str, const std::string prefix)
Checks whether a given string starts with the prefix.
static std::string wrapText(const std::string s, int width)
remove leading and trailing whitespace
static double parseSpeed(const std::string &sData, const bool defaultKmph=true)
parse a speed value with a unit
static std::string emptyString
An empty string.
static bool endsWith(const std::string &str, const std::string suffix)
Checks whether a given string ends with the suffix.
static std::string substituteEnvironment(const std::string &str, const std::chrono::time_point< std::chrono::system_clock > *const timeRef=nullptr)
Replaces an environment variable with its value (similar to bash); syntax for a variable is ${NAME}.
static bool isLong(const std::string &sData)
Check if the given sData can be converted to long.
static int toIntSecure(const std::string &sData, int def)
converts a string into the integer value described by it
static std::string isoTimeString(const std::chrono::time_point< std::chrono::system_clock > *const timeRef=nullptr)
Returns an ISO8601 formatted time string with microsecond precision.
static std::string escapeCSV(const std::string &orig, const char separator, const char quote='"')
Adds quotes to strings containing the separator or the quote char and escapes the quote char with a b...
static int toInt(const std::string &sData)
converts a string into the integer value described by it by calling the char-type converter,...
static bool isInt(const std::string &sData)
check if the given sData can be converted to int
static bool toBool(const std::string &sData)
converts a string into the bool value described by it by calling the char-type converter