| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266 |
- #include "common/string_utils.hpp"
- #include <cstdlib>
- #include <openssl/bio.h>
- #include <openssl/evp.h>
- #include <openssl/buffer.h>
- namespace smartbotic::common {
- std::string StringUtils::trim(std::string_view str) {
- return trimRight(trimLeft(str));
- }
- std::string StringUtils::trimLeft(std::string_view str) {
- auto it = std::find_if(str.begin(), str.end(),
- [](unsigned char c) { return !std::isspace(c); });
- return std::string(it, str.end());
- }
- std::string StringUtils::trimRight(std::string_view str) {
- auto it = std::find_if(str.rbegin(), str.rend(),
- [](unsigned char c) { return !std::isspace(c); });
- return std::string(str.begin(), it.base());
- }
- std::string StringUtils::toLower(std::string_view str) {
- std::string result(str);
- std::transform(result.begin(), result.end(), result.begin(),
- [](unsigned char c) { return std::tolower(c); });
- return result;
- }
- std::string StringUtils::toUpper(std::string_view str) {
- std::string result(str);
- std::transform(result.begin(), result.end(), result.begin(),
- [](unsigned char c) { return std::toupper(c); });
- return result;
- }
- std::vector<std::string> StringUtils::split(std::string_view str, char delimiter) {
- std::vector<std::string> result;
- std::string current;
- for (char c : str) {
- if (c == delimiter) {
- result.push_back(std::move(current));
- current.clear();
- } else {
- current += c;
- }
- }
- result.push_back(std::move(current));
- return result;
- }
- std::vector<std::string> StringUtils::split(std::string_view str, std::string_view delimiter) {
- std::vector<std::string> result;
- size_t start = 0;
- size_t end = str.find(delimiter);
- while (end != std::string_view::npos) {
- result.emplace_back(str.substr(start, end - start));
- start = end + delimiter.length();
- end = str.find(delimiter, start);
- }
- result.emplace_back(str.substr(start));
- return result;
- }
- std::string StringUtils::join(const std::vector<std::string>& parts, std::string_view delimiter) {
- if (parts.empty()) return "";
- std::ostringstream ss;
- ss << parts[0];
- for (size_t i = 1; i < parts.size(); ++i) {
- ss << delimiter << parts[i];
- }
- return ss.str();
- }
- bool StringUtils::startsWith(std::string_view str, std::string_view prefix) {
- return str.size() >= prefix.size() && str.substr(0, prefix.size()) == prefix;
- }
- bool StringUtils::endsWith(std::string_view str, std::string_view suffix) {
- return str.size() >= suffix.size() &&
- str.substr(str.size() - suffix.size()) == suffix;
- }
- bool StringUtils::contains(std::string_view str, std::string_view substr) {
- return str.find(substr) != std::string_view::npos;
- }
- std::string StringUtils::replace(std::string_view str, std::string_view from, std::string_view to) {
- std::string result(str);
- size_t pos = result.find(from);
- if (pos != std::string::npos) {
- result.replace(pos, from.length(), to);
- }
- return result;
- }
- std::string StringUtils::replaceAll(std::string_view str, std::string_view from, std::string_view to) {
- std::string result(str);
- size_t pos = 0;
- while ((pos = result.find(from, pos)) != std::string::npos) {
- result.replace(pos, from.length(), to);
- pos += to.length();
- }
- return result;
- }
- std::string StringUtils::interpolate(std::string_view tmpl,
- const std::unordered_map<std::string, std::string>& vars) {
- std::string result(tmpl);
- std::regex pattern(R"(\$\{([^}]+)\})");
- std::string output;
- auto it = std::sregex_iterator(result.begin(), result.end(), pattern);
- auto end = std::sregex_iterator();
- size_t lastPos = 0;
- for (; it != end; ++it) {
- output += result.substr(lastPos, it->position() - lastPos);
- std::string varName = (*it)[1].str();
- auto found = vars.find(varName);
- if (found != vars.end()) {
- output += found->second;
- } else {
- output += it->str(); // Keep original if not found
- }
- lastPos = it->position() + it->length();
- }
- output += result.substr(lastPos);
- return output;
- }
- std::string StringUtils::expandEnvVars(std::string_view str) {
- std::string result(str);
- std::regex pattern(R"(\$\{([^:}]+)(?::([^}]*))?\})");
- std::string output;
- auto it = std::sregex_iterator(result.begin(), result.end(), pattern);
- auto end = std::sregex_iterator();
- size_t lastPos = 0;
- for (; it != end; ++it) {
- output += result.substr(lastPos, it->position() - lastPos);
- std::string varName = (*it)[1].str();
- std::string defaultValue = (*it)[2].matched ? (*it)[2].str() : "";
- const char* envValue = std::getenv(varName.c_str());
- if (envValue) {
- output += envValue;
- } else {
- output += defaultValue;
- }
- lastPos = it->position() + it->length();
- }
- output += result.substr(lastPos);
- return output;
- }
- std::string StringUtils::urlEncode(std::string_view str) {
- std::ostringstream escaped;
- escaped.fill('0');
- escaped << std::hex;
- for (char c : str) {
- if (std::isalnum(static_cast<unsigned char>(c)) ||
- c == '-' || c == '_' || c == '.' || c == '~') {
- escaped << c;
- } else {
- escaped << std::uppercase;
- escaped << '%' << std::setw(2) << int(static_cast<unsigned char>(c));
- escaped << std::nouppercase;
- }
- }
- return escaped.str();
- }
- std::string StringUtils::urlDecode(std::string_view str) {
- std::string result;
- result.reserve(str.size());
- for (size_t i = 0; i < str.size(); ++i) {
- if (str[i] == '%' && i + 2 < str.size()) {
- int hex = std::stoi(std::string(str.substr(i + 1, 2)), nullptr, 16);
- result += static_cast<char>(hex);
- i += 2;
- } else if (str[i] == '+') {
- result += ' ';
- } else {
- result += str[i];
- }
- }
- return result;
- }
- std::string StringUtils::base64Encode(std::string_view data) {
- BIO* b64 = BIO_new(BIO_f_base64());
- BIO* bio = BIO_new(BIO_s_mem());
- bio = BIO_push(b64, bio);
- BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
- BIO_write(bio, data.data(), static_cast<int>(data.size()));
- BIO_flush(bio);
- BUF_MEM* bufferPtr;
- BIO_get_mem_ptr(bio, &bufferPtr);
- std::string result(bufferPtr->data, bufferPtr->length);
- BIO_free_all(bio);
- return result;
- }
- std::string StringUtils::base64Decode(std::string_view encoded) {
- BIO* b64 = BIO_new(BIO_f_base64());
- BIO* bio = BIO_new_mem_buf(encoded.data(), static_cast<int>(encoded.size()));
- bio = BIO_push(b64, bio);
- BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
- std::string result(encoded.size(), '\0');
- int length = BIO_read(bio, result.data(), static_cast<int>(result.size()));
- BIO_free_all(bio);
- if (length > 0) {
- result.resize(length);
- } else {
- result.clear();
- }
- return result;
- }
- std::string StringUtils::hexEncode(const std::vector<uint8_t>& data) {
- static const char hex[] = "0123456789abcdef";
- std::string result;
- result.reserve(data.size() * 2);
- for (uint8_t byte : data) {
- result += hex[byte >> 4];
- result += hex[byte & 0x0f];
- }
- return result;
- }
- std::vector<uint8_t> StringUtils::hexDecode(std::string_view hex) {
- std::vector<uint8_t> result;
- result.reserve(hex.size() / 2);
- for (size_t i = 0; i + 1 < hex.size(); i += 2) {
- uint8_t byte = static_cast<uint8_t>(std::stoi(std::string(hex.substr(i, 2)), nullptr, 16));
- result.push_back(byte);
- }
- return result;
- }
- } // namespace smartbotic::common
|