/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file StringUtils.h14/// @author Daniel Krajzewicz15/// @author Jakob Erdmann16/// @author Michael Behrisch17/// @author Robert Hilbrich18/// @date unknown19///20// Some static methods for string processing21/****************************************************************************/22#pragma once23#include <config.h>24#include <string>25#include <chrono>26#include <sstream>27#include <iomanip>28#include <xercesc/util/XMLString.hpp>29#include <utils/common/StdDefs.h>303132// ===========================================================================33// class definitions34// ===========================================================================35/**36* @class StringUtils37* @brief Some static methods for string processing38*/39class StringUtils {4041public:4243/// @brief Removes trailing and leading whitechars44static std::string prune(const std::string& str);4546/// @brief Removes trailing zeros (at most 'max')47static std::string pruneZeros(const std::string& str, int max);4849/// @brief Transfers the content to lower case50static std::string to_lower_case(const std::string& str);5152/// @brief Transfers from Latin 1 (ISO-8859-1) to UTF-853static std::string latin1_to_utf8(std::string str);5455/// @brief Converts german "Umlaute" to their latin-version56static std::string convertUmlaute(std::string str);5758/// @brief Replaces all occurrences of the second string by the third string within the first string59static std::string replace(std::string str, const std::string& what, const std::string& by);6061/// @brief Replaces an environment variable with its value (similar to bash); syntax for a variable is ${NAME}62static std::string substituteEnvironment(const std::string& str, const std::chrono::time_point<std::chrono::system_clock>* const timeRef = nullptr);6364/// @brief Returns an ISO8601 formatted time string with microsecond precision65static std::string isoTimeString(const std::chrono::time_point<std::chrono::system_clock>* const timeRef = nullptr);6667///@brief Checks whether a given string starts with the prefix68static bool startsWith(const std::string& str, const std::string prefix);6970/// @brief Checks whether a given string ends with the suffix71static bool endsWith(const std::string& str, const std::string suffix);7273//// @brief pads the given string with padding character up to the given total length74static std::string padFront(const std::string& str, int length, char padding);7576/**77* @brief Replaces the standard escapes by their XML entities.78*79* The strings &, <, >, ", and ' are replaced by &, <, >, ", and '80*81* @param[in] orig The original string82* @param[in] maskDoubleHyphen Whether -- in input shall be converted to -- (semantically equivalent but allowed in XML comments)83* @return the string with the escaped sequences84*/85static std::string escapeXML(const std::string& orig, const bool maskDoubleHyphen = false);8687/**88* @brief Escape special characters with backslash89*/90static std::string escapeShell(const std::string& orig);9192/// @brief An empty string93static std::string emptyString;9495/// @brief encode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)96static std::string urlEncode(const std::string& url, const std::string encodeWhich = "");9798/// @brief decode url (stem from http://bogomip.net/blog/cpp-url-encoding-and-decoding/)99static std::string urlDecode(const std::string& encoded);100101/// @brief char to hexadecimal102static std::string charToHex(unsigned char c);103104/// @brief hexadecimal to char105static unsigned char hexToChar(const std::string& str);106107/**@brief converts a string into the integer value described by it by calling the char-type converter, which108* @throw an EmptyData - exception if the given string is empty109* @throw NumberFormatException - exception when the string does not contain an integer110*/111static int toInt(const std::string& sData);112113/// @brief check if the given sData can be converted to int114static bool isInt(const std::string& sData);115116/// @brief converts a string into the integer value described by it117/// @return the default value if the data is empty118static int toIntSecure(const std::string& sData, int def);119120/**@brief converts a string into the long value described by it by calling the char-type converter, which121* @throw an EmptyData - exception if the given string is empty122* @throw NumberFormatException - exception when the string does not contain a long integer123*/124static long long int toLong(const std::string& sData);125126/// @brief Check if the given sData can be converted to long127static bool isLong(const std::string& sData);128129/**@brief converts a string with a hex value into the integer value described by it by calling the char-type converter130* @throw an EmptyData - exception if the given string is empty131* @throw a NumberFormatException - exception when the string does not contain an integer132*/133static int hexToInt(const std::string& sData);134135/// @brief check if the given string can be converted to hex136static bool isHex(std::string sData);137138/**@brief converts a string into the double value described by it by calling the char-type converter139* @throw an EmptyData - exception if the given string is empty140* @throw a NumberFormatException - exception when the string does not contain a double141*/142static double toDouble(const std::string& sData);143144/// @brief check if the given sData can be conveted to double145static bool isDouble(const std::string& sData);146147/// @brief converts a string into the integer value described by it148/// @return the default value if the data is empty149static double toDoubleSecure(const std::string& sData, const double def);150151/**@brief converts a string into the bool value described by it by calling the char-type converter152* @return true if the sData is one of the following (case insensitive): '1', 'x', 'true', 'yes', 'on', 't'153* @return false if the sData is one of the following (case insensitive): '0', '-', 'false', 'no', 'off', 'f'154* @throw EmptyData - exception if the given string is empty155* @throw BoolFormatException in any other case156*/157static bool toBool(const std::string& sData);158159/// @brief check if the given value can be converted to bool160static bool isBool(const std::string& sData);161162/// @brief parse a (network) version string163static MMVersion toVersion(const std::string& sData);164165/// @brief parse a distance, length or width value with a unit166static double parseDist(const std::string& sData);167168/// @brief parse a speed value with a unit169static double parseSpeed(const std::string& sData, const bool defaultKmph = true);170171/**@brief converts a 0-terminated XMLCh* array (usually UTF-16, stemming from Xerces) into std::string in UTF-8172* @throw an EmptyData - exception if the given pointer is 0173*/174static inline std::string transcode(const XMLCh* const data) {175return transcode(data, (int)XERCES_CPP_NAMESPACE::XMLString::stringLen(data));176}177178/**@brief converts a 0-terminated XMLCh* array (usually UTF-16, stemming from Xerces) into std::string in UTF-8 considering the given length179* @throw EmptyData if the given pointer is 0180*/181static std::string transcode(const XMLCh* const data, int length);182183/// @brief convert a string from the local codepage to UTF-8184static std::string transcodeFromLocal(const std::string& localString);185186/// @brief convert a string from UTF-8 to the local codepage187static std::string transcodeToLocal(const std::string& utf8String);188189/// @brief remove leading whitespace from string190static std::string trim_left(const std::string s, const std::string& t = " \t\n");191192/// @brief remove trailing whitespace from string193static std::string trim_right(const std::string s, const std::string& t = " \t\n");194195/// @brief remove leading and trailing whitespace196static std::string trim(const std::string s, const std::string& t = " \t\n");197198/// @brief remove leading and trailing whitespace199static std::string wrapText(const std::string s, int width);200201/// @brief must be called when shutting down the xml subsystem202static void resetTranscoder();203204/// @brief adds a new formatted message205// variadic function206template<typename T, typename... Targs>207static const std::string format(const std::string& format, T value, Targs... Fargs) {208std::ostringstream os;209os << std::fixed << std::setprecision(gPrecision);210_format(format.c_str(), os, value, Fargs...);211return os.str();212}213214private:215static void _format(const char* format, std::ostringstream& os) {216os << format;217}218219/// @brief adds a new formatted message220// variadic function221template<typename T, typename... Targs>222static void _format(const char* format, std::ostringstream& os, T value, Targs... Fargs) {223for (; *format != '\0'; format++) {224if (*format == '%') {225os << value;226_format(format + 1, os, Fargs...); // recursive call227return;228}229os << *format;230}231}232233static XERCES_CPP_NAMESPACE::XMLLCPTranscoder* myLCPTranscoder;234};235236237