40#define KM_PER_MILE 1.609344
54 const std::string::size_type endpos = str.find_last_not_of(
" \t\n\r");
55 if (std::string::npos != endpos) {
56 const int startpos = (int)str.find_first_not_of(
" \t\n\r");
57 return str.substr(startpos, endpos - startpos + 1);
65 const std::string::size_type endpos = str.find_last_not_of(
"0");
66 if (endpos != std::string::npos && str.back() ==
'0') {
67 std::string res = str.substr(0,
MAX2((
int)str.size() - max, (
int)endpos + 1));
76 std::transform(s.begin(), s.end(), s.begin(), [](
char c) {
77 return (char)::tolower(c);
86 std::transform(s.begin(), s.end(), s.begin(), [](
char c) {
87 return (char)::toupper(c);
97 for (
const auto& c : str) {
98 const unsigned char uc = (
unsigned char)c;
102 result += (char)(0xc2 + (uc > 0xbf));
103 result += (char)((uc & 0x3f) + 0x80);
112 str =
replace(str,
"\xE4",
"ae");
113 str =
replace(str,
"\xC4",
"Ae");
114 str =
replace(str,
"\xF6",
"oe");
115 str =
replace(str,
"\xD6",
"Oe");
116 str =
replace(str,
"\xFC",
"ue");
117 str =
replace(str,
"\xDC",
"Ue");
118 str =
replace(str,
"\xDF",
"ss");
119 str =
replace(str,
"\xC9",
"E");
120 str =
replace(str,
"\xE9",
"e");
121 str =
replace(str,
"\xC8",
"E");
122 str =
replace(str,
"\xE8",
"e");
129 std::string::size_type idx = str.find(what);
130 const int what_len = (int)what.length();
132 const int by_len = (int)by.length();
133 while (idx != std::string::npos) {
134 str = str.replace(idx, what_len, by);
135 idx = str.find(what, idx + by_len);
145 if (timeRef !=
nullptr) {
146 const std::string::size_type localTimeIndex = str.find(
"${LOCALTIME}");
147 const std::string::size_type utcIndex = str.find(
"${UTC}");
148 const bool isUTC = utcIndex != std::string::npos;
149 if (localTimeIndex != std::string::npos || isUTC) {
150 const time_t rawtime = std::chrono::system_clock::to_time_t(*timeRef);
152 struct tm* timeinfo = isUTC ? gmtime(&rawtime) : localtime(&rawtime);
153 strftime(buffer, 80,
"%Y-%m-%d-%H-%M-%S.", timeinfo);
154 auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(*timeRef);
155 auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(*timeRef - seconds);
156 const std::string micro = buffer +
toString(microseconds.count());
158 s.replace(utcIndex, 6, micro);
160 s.replace(localTimeIndex, 12, micro);
164 const std::string::size_type pidIndex = str.find(
"${PID}");
165 if (pidIndex != std::string::npos) {
167 s.replace(pidIndex, 6,
toString(::GetCurrentProcessId()));
169 s.replace(pidIndex, 6,
toString(::getpid()));
172 if (std::getenv(
"SUMO_LOGO") ==
nullptr) {
173 s =
replace(s,
"${SUMO_LOGO}",
"${SUMO_HOME}/data/logo/sumo-128x138.png");
175 const std::string::size_type tildeIndex = str.find(
"~");
176 if (tildeIndex == 0) {
177 s.replace(0, 1,
"${HOME}");
179 s =
replace(s,
",~",
",${HOME}");
181 if (std::getenv(
"HOME") ==
nullptr) {
182 s =
replace(s,
"${HOME}",
"${USERPROFILE}");
190 std::regex envVarExpr(R
"(\$\{(.+?)\})");
194 std::string strIter = s;
197 while (std::regex_search(strIter, match, envVarExpr)) {
198 std::string varName = match[1];
201 std::string varValue;
202 if (std::getenv(varName.c_str()) !=
nullptr) {
203 varValue = std::getenv(varName.c_str());
207 s = std::regex_replace(s, std::regex(
"\\$\\{" + varName +
"\\}"), varValue);
210 strIter = match.suffix();
218 const std::chrono::system_clock::time_point now = timeRef ==
nullptr ? std::chrono::system_clock::now() : *timeRef;
219 const auto now_seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
220 const std::time_t now_c = std::chrono::system_clock::to_time_t(now);
221 const auto microseconds = std::chrono::duration_cast<std::chrono::microseconds>(now - now_seconds).count();
222 std::tm local_tm = *std::localtime(&now_c);
225 std::time_t utc_time = std::time(
nullptr);
226 std::tm utc_tm = *std::gmtime(&utc_time);
227 const double offset = std::difftime(std::mktime(&local_tm), std::mktime(&utc_tm)) / 3600.0;
228 const int hours_offset =
static_cast<int>(offset);
229 const int minutes_offset =
static_cast<int>((offset - hours_offset) * 60);
232 std::ostringstream oss;
234 std::strftime(buf,
sizeof(buf),
"%Y-%m-%dT%H:%M:%S", &local_tm);
236 << std::setw(6) << std::setfill(
'0') << std::abs(microseconds)
237 << (hours_offset >= 0 ?
"+" :
"-")
238 << std::setw(2) << std::setfill(
'0') << std::abs(hours_offset) <<
":"
239 << std::setw(2) << std::setfill(
'0') << std::abs(minutes_offset);
246 return str.compare(0, prefix.length(), prefix) == 0;
252 if (str.length() >= suffix.length()) {
253 return str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
262 return std::string(
MAX2(0, length - (
int)str.size()), padding) + str;
268 std::string result =
replace(orig,
"&",
"&");
269 result =
replace(result,
">",
">");
270 result =
replace(result,
"<",
"<");
271 result =
replace(result,
"\"",
""");
272 if (maskDoubleHyphen) {
273 result =
replace(result,
"--",
"--");
275 for (
char invalid =
'\1'; invalid <
' '; invalid++) {
276 result =
replace(result, std::string(1, invalid).c_str(),
"");
278 return replace(result,
"'",
"'");
284 return replace(orig,
"\"",
"\\\"");
290 const std::string chars{separator, quote};
291 if (orig.find_first_of(chars) == std::string::npos) {
294 const std::string quoteStr{quote};
295 return quoteStr +
replace(orig, quoteStr, {
'\\', quote}) + quoteStr;
301 std::ostringstream out;
303 for (
int i = 0; i < (int)toEncode.length(); ++i) {
304 const char t = toEncode.at(i);
306 if ((encodeWhich !=
"" && encodeWhich.find(t) == std::string::npos) ||
307 (encodeWhich ==
"" &&
308 ((t >= 45 && t <= 57) ||
309 (t >= 65 && t <= 90) ||
311 (t >= 97 && t <= 122) ||
314 out << toEncode.at(i);
326 std::ostringstream out;
328 for (
int i = 0; i < (int)toDecode.length(); ++i) {
329 if (toDecode.at(i) ==
'%') {
330 std::string str(toDecode.substr(i + 1, 2));
334 out << toDecode.at(i);
347 s <<
"%" << std::setw(2) << std::setfill(
'0') << std::hex << i;
357 std::istringstream in(str);
363 return static_cast<unsigned char>(c);
369 long long int result =
toLong(sData);
370 if (result > std::numeric_limits<int>::max() || result < std::numeric_limits<int>::min()) {
381 const long long int result =
toLong(sData);
383 return ((result <= std::numeric_limits<int>::max()) && (result >= std::numeric_limits<int>::min()));
391 if (sData.length() == 0) {
400 const char*
const data = sData.c_str();
401 if (data == 0 || data[0] == 0) {
407 long long int ret = _strtoi64(data, &end, 10);
409 long long int ret = strtoll(data, &end, 10);
411 if (errno == ERANGE) {
415 if ((
int)(end - data) != (
int)strlen(data)) {
424 const char*
const data = sData.c_str();
425 if (data == 0 || data[0] == 0) {
433 _strtoi64(data, &end, 10);
435 strtoll(data, &end, 10);
438 if (errno == ERANGE) {
442 if ((
int)(end - data) != (
int)strlen(data)) {
451 if (sData.length() == 0) {
457 if (sData[0] ==
'#') {
458 result = std::stoi(sData.substr(1), &idx, 16);
461 result = std::stoi(sData, &idx, 16);
466 if (idx != sData.length()) {
475 if (sData.length() == 0) {
479 if (sData[0] ==
'#') {
480 sData = sData.substr(1);
482 const char* sDataPtr = sData.c_str();
487 strtol(sDataPtr, &returnPtr, 16);
489 if (errno == ERANGE) {
493 if (sDataPtr == returnPtr) {
497 if (
static_cast<size_t>(returnPtr - sDataPtr) != sData.size()) {
506 if (sData.size() == 0) {
511 const double result = std::stod(sData, &idx);
512 if (idx != sData.size()) {
526 if (sData.size() == 0) {
529 const char* sDataPtr = sData.c_str();
534 strtod(sDataPtr, &returnPtr);
536 if (errno == ERANGE) {
540 if (sDataPtr == returnPtr) {
544 if (
static_cast<size_t>(returnPtr - sDataPtr) != sData.size()) {
553 if (sData.length() == 0) {
562 if (sData.find(
":") == std::string::npos) {
564 }
else if (
isTime(sData)) {
572 if (sData.length() == 0) {
576 if (s ==
"1" || s ==
"yes" || s ==
"true" || s ==
"on" || s ==
"x" || s ==
"t") {
579 if (s ==
"0" || s ==
"no" || s ==
"false" || s ==
"off" || s ==
"-" || s ==
"f") {
588 if (sData.length() == 0) {
593 if (s ==
"1" || s ==
"yes" || s ==
"true" || s ==
"on" || s ==
"x" || s ==
"t") {
597 if (s ==
"0" || s ==
"no" || s ==
"false" || s ==
"off" || s ==
"-" || s ==
"f") {
614 if (sData.size() == 0) {
619 const double result = std::stod(sData, &idx);
620 if (idx != sData.size()) {
621 const std::string unit =
prune(sData.substr(idx));
622 if (unit ==
"m" || unit ==
"metre" || unit ==
"meter" || unit ==
"metres" || unit ==
"meters") {
625 if (unit ==
"km" || unit ==
"kilometre" || unit ==
"kilometer" || unit ==
"kilometres" || unit ==
"kilometers") {
626 return result * 1000.;
628 if (unit ==
"mi" || unit ==
"mile" || unit ==
"miles") {
632 return result * 1852.;
634 if (unit ==
"ft" || unit ==
"foot" || unit ==
"feet") {
635 return result * 12. * 0.0254;
637 if (unit ==
"\"" || unit ==
"in" || unit ==
"inch" || unit ==
"inches") {
638 return result * 0.0254;
640 if (unit[0] ==
'\'') {
641 double inches = 12 * result;
642 if (unit.length() > 1) {
643 inches += std::stod(unit.substr(1), &idx);
644 if (unit.substr(idx) ==
"\"") {
645 return inches * 0.0254;
662 if (sData.size() == 0) {
667 const double result = std::stod(sData, &idx);
668 if (idx != sData.size()) {
669 const std::string unit =
prune(sData.substr(idx));
670 if (unit ==
"km/h" || unit ==
"kph" || unit ==
"kmh" || unit ==
"kmph") {
679 if (unit ==
"knots") {
680 return result * 1.852 / 3.6;
684 return defaultKmph ? result / 3.6 : result;
696 std::string result = s;
697 result.erase(0, s.find_first_not_of(t));
703 std::string result = s;
704 result.erase(s.find_last_not_of(t) + 1);
719 bool firstLine =
true;
720 bool firstWord =
true;
721 for (std::string p : parts) {
722 if ((
int)(line.size() + p.size()) < width || firstWord) {
740 if (line.size() > 0) {
755 auto valueStr =
toString(value, precision);
757 while (valueStr.size() > 1) {
758 if (valueStr.back() ==
'0') {
760 }
else if (valueStr.back() ==
'.') {
SUMOTime string2time(const std::string &r)
convert string to SUMOTime
bool isTime(const std::string &r)
check if the given string is a valid time
std::pair< int, double > MMVersion
(M)ajor/(M)inor version for written networks and default version for loading
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
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 double toDoubleAllowTime(const std::string &sData)
converts a string into a double value. Values in human-readable-time format (see string2time) are per...
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