#include #ifdef ENABLE_BASE128 #include "base128.h" #endif namespace Utils { namespace String { const char *VA(const char *fmt, ...) { static VAProvider<4, 100> globalProvider; static thread_local VAProvider<8, 256> provider; va_list ap; va_start(ap, fmt); const char* result; if (Components::Loader::IsUninitializing()) result = globalProvider.get(fmt, ap); else result = provider.get(fmt, ap); va_end(ap); return result; } std::string ToLower(std::string input) { std::transform(input.begin(), input.end(), input.begin(), ::tolower); return input; } std::string ToUpper(std::string input) { std::transform(input.begin(), input.end(), input.begin(), ::toupper); return input; } std::string DumpHex(const std::string& data, const std::string& separator) { std::string result; for (unsigned int i = 0; i < data.size(); ++i) { if (i > 0) { result.append(separator); } result.append(Utils::String::VA("%02X", data[i] & 0xFF)); } return result; } std::string XOR(std::string str, char value) { for (unsigned int i = 0; i < str.size(); ++i) { str[i] ^= value; } return str; } std::vector Split(const std::string& str, const char delim) { std::stringstream ss(str); std::string item; std::vector elems; while (std::getline(ss, item, delim)) { elems.push_back(item); // elems.push_back(std::move(item)); // if C++11 (based on comment from S1x) } return elems; } void Replace(std::string &string, const std::string& find, const std::string& replace) { size_t nPos = 0; while ((nPos = string.find(find, nPos)) != std::string::npos) { string = string.replace(nPos, find.length(), replace); nPos += replace.length(); } } bool StartsWith(const std::string& haystack, const std::string& needle) { return (haystack.size() >= needle.size() && haystack.substr(0, needle.size()) == needle); } bool EndsWith(const std::string& haystack, const std::string& needle) { return (haystack.size() >= needle.size() && haystack.substr(haystack.size() - needle.size()) == needle); } int IsSpace(int c) { if (c < -1) return 0; return _isspace_l(c, nullptr); } // Trim from start std::string& LTrim(std::string& str) { str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](int val) { return !IsSpace(val); })); return str; } // Trim from end std::string& RTrim(std::string& str) { str.erase(std::find_if(str.rbegin(), str.rend(), [](int val) { return !IsSpace(val); }).base(), str.end()); return str; } // Trim from both ends std::string& Trim(std::string& str) { return LTrim(RTrim(str)); } std::string Convert(const std::wstring& wstr) { std::string result; result.reserve(wstr.size()); for (const auto& chr : wstr) { result.push_back(static_cast(chr)); } return result; } std::wstring Convert(const std::string& str) { std::wstring result; result.reserve(str.size()); for (const auto& chr : str) { result.push_back(static_cast(chr)); } return result; } std::string FormatTimeSpan(int milliseconds) { int secondsTotal = milliseconds / 1000; int seconds = secondsTotal % 60; int minutesTotal = secondsTotal / 60; int minutes = minutesTotal % 60; int hoursTotal = minutesTotal / 60; return Utils::String::VA("%02d:%02d:%02d", hoursTotal, minutes, seconds); } std::string FormatBandwidth(size_t bytes, int milliseconds) { static const char* sizes[] = { "B", "KB", "MB", "GB", "TB" }; if (!milliseconds) return "0.00 B/s"; double bytesPerSecond = (1000.0 / milliseconds) * bytes; int i; for (i = 0; bytesPerSecond > 1000 && i < ARRAYSIZE(sizes); ++i) // 1024 or 1000? { bytesPerSecond /= 1000; } return Utils::String::VA("%.2f %s/s", static_cast(bytesPerSecond), sizes[i]); } #ifdef ENABLE_BASE64 // Encodes a given string in Base64 std::string EncodeBase64(const char* input, const unsigned long inputSize) { unsigned long outlen = long(inputSize + (inputSize / 3.0) + 16); unsigned char* outbuf = new unsigned char[outlen]; //Reserve output memory base64_encode(reinterpret_cast(const_cast(input)), inputSize, outbuf, &outlen); std::string ret(reinterpret_cast(outbuf), outlen); delete[] outbuf; return ret; } // Encodes a given string in Base64 std::string EncodeBase64(const std::string& input) { return EncodeBase64(input.data(), input.size()); } #endif #ifdef ENABLE_BASE128 // Encodes a given string in Base128 std::string EncodeBase128(const std::string& input) { base128 encoder; void* inbuffer = const_cast(input.data()); char* buffer = encoder.encode(inbuffer, input.size()); /* Interesting to see that the buffer returned by the encoder is not a standalone string copy but instead is a pointer to the internal "encoded" field of the encoder. So if you deinitialize the encoder that string will probably become garbage. */ std::string retval(buffer); return retval; } #endif } }