#include "U_String.h" #include #include #include #include std::wstring StringUtils::StrToWstr(const std::string& str) { /*std::vector buf(str.size()); std::use_facet>(std::locale{}).widen(str.data(), str.data() + str.size(), buf.data()); return std::wstring(buf.data(), buf.size());*/ return boost::locale::conv::utf_to_utf(str); } std::string StringUtils::WstrToStr(const std::wstring& wstr) { /*std::vector buf(wstr.size()); std::use_facet>(std::locale{}).narrow(wstr.data(), wstr.data() + wstr.size(), '?', buf.data()); return std::string(buf.data(), buf.size());*/ return boost::locale::conv::utf_to_utf(wstr); } std::u16string StringUtils::Utf8ToU16(const std::string& str) { return boost::locale::conv::utf_to_utf(str); } std::string StringUtils::U16ToUtf8(const std::u16string& str) { return boost::locale::conv::utf_to_utf(str); } std::u16string StringUtils::WstrToU16(const std::wstring& wstr) { return boost::locale::conv::utf_to_utf(wstr); } std::wstring StringUtils::U16ToWstr(const std::u16string& str) { return boost::locale::conv::utf_to_utf(str); } bool StringUtils::StartsWith(const std::string& str, const std::string& startswith) { return StringUtils::SafeSubstring(str, startswith.size()) == startswith; } bool StringUtils::StartsWith(const std::wstring& str, const std::wstring& startswith) { return StringUtils::SafeSubstring(str, startswith.size()) == startswith; } void StringUtils::split_str(const std::string& s, char delim, std::vector& ua) { std::stringstream ss; ss.str(s); std::string item; while (true) { if (!ss) { return; } if (ss.eof()) { break; } std::getline(ss, item, delim); ua.push_back(item); } } void StringUtils::split_str(const std::wstring& s, wchar_t delim, std::vector& ua) { std::wstringstream ss; ss.str(s); std::wstring item; while (true) { if (!ss) { return; } if (ss.eof()) { break; } std::getline(ss, item, delim); ua.push_back(item); } } std::vector StringUtils::split_str(const std::string& s, char delim) { std::vector ret; split_str(s, delim, ret); return ret; } std::vector StringUtils::split_str(const std::wstring& s, wchar_t delim) { std::vector ret; split_str(s, delim, ret); return ret; } void StringUtils::remove_consecutive_commas(std::string& str) { std::regex comma_pattern(",{2,}"); str = std::regex_replace(str, comma_pattern, ","); } void StringUtils::remove_consecutive_commas(std::wstring& str) { std::wregex comma_pattern(L",{2,}"); str = std::regex_replace(str, comma_pattern, L","); } void CommandPreprocess::Trim(std::wstring& str) { str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](wchar_t c) { return !std::iswspace(c); })); str.erase(std::find_if(str.rbegin(), str.rend(), [](wchar_t c) { return !std::iswspace(c); }).base(), str.end()); } void CommandPreprocess::PreprocessEscapes(std::wstring& str) { std::wstring result; for (size_t i = 0; i < str.size(); ++i) { if (str[i] == L'\\' && i + 1 < str.size()) { if (str[i + 1] == L';') { result += L'\x1F'; ++i; } else { result += str[i]; result += str[i + 1]; ++i; } } else { result += str[i]; } } str = result; } void CommandPreprocess::ReplaceEscapes(std::wstring& str) { std::wstring result; for (size_t i = 0; i < str.size(); ++i) { if (str[i] == L'\x1F') { result += L';'; } else if (str[i] == L'\\' && i + 1 < str.size()) { switch (str[i + 1]) { case L'\\': result += L'\\'; ++i; break; case L'n': result += L'\n'; ++i; break; case L'r': result += L'\r'; ++i; break; case L'\"': result += L'\"'; ++i; break; default: result += str[i]; break; } } else { result += str[i]; } } str = result; } std::vector CommandPreprocess::SplitCommands(const std::wstring& input) { std::vector commands; std::wstring current; bool inString = false; for (size_t i = 0; i < input.size(); ++i) { if (input[i] == L'\"' && (i == 0 || input[i - 1] != L'\\')) { inString = !inString; } else if (input[i] == L';' && !inString) { Trim(current); if (!current.empty()) { commands.push_back(current); current.clear(); } continue; } current += input[i]; } Trim(current); if (!current.empty()) { commands.push_back(current); } return commands; } std::vector CommandPreprocess::ParseArguments(const std::wstring& command) { std::vector arguments; std::wstring current; bool inString = false; for (size_t i = 0; i < command.size(); ++i) { if (command[i] == L'\"' && (i == 0 || command[i - 1] != L'\\')) { inString = !inString; continue; } if (std::iswspace(command[i]) && !inString) { if (!current.empty()) { ReplaceEscapes(current); arguments.push_back(current); current.clear(); } continue; } current += command[i]; } if (!current.empty()) { ReplaceEscapes(current); arguments.push_back(current); } return arguments; } std::vector> CommandPreprocess::PreProcessString(std::wstring cmdline) { Trim(cmdline); if (cmdline.empty()) { return {}; } PreprocessEscapes(cmdline); std::vector> result; std::vector commands = SplitCommands(cmdline); for (auto& cmd : commands) { std::vector args = ParseArguments(cmd); if (!args.empty()) { result.push_back(args); } } return result; } void ArgumentsPreprocess::ReplaceEscapes(std::string& str) { std::string result; for (size_t i = 0; i < str.size(); ++i) { if (str[i] == '\\' && i + 1 < str.size()) { switch (str[i + 1]) { case '\\': result += '\\'; ++i; break; case 'n': result += '\n'; ++i; break; case 'r': result += '\r'; ++i; break; case 't': result += '\t'; ++i; break; case '\"': result += '\"'; ++i; break; default: result += str[i]; break; } } else { result += str[i]; } } str = result; } std::vector ArgumentsPreprocess::ParseArguments(std::string cmdline) { std::vector arguments; std::string current; bool inString = false; for (size_t i = 0; i < cmdline.size(); ++i) { if (cmdline[i] == '\"' && (i == 0 || cmdline[i - 1] != '\\')) { inString = !inString; continue; } if ((cmdline[i] == ' ' || cmdline[i] == '\t') && !inString) { if (!current.empty()) { ReplaceEscapes(current); arguments.push_back(current); current.clear(); } continue; } current += cmdline[i]; } if (!current.empty()) { ReplaceEscapes(current); arguments.push_back(current); } return arguments; } bool ArgumentsPreprocess::Compare(const std::string& str, const std::string& op, const std::string& arg) //TODO ugly code { if (op.empty()) { return false; } if (StringUtils::isNumber(str)) { double numstr = StringUtils::FromStr(str); double numarg = StringUtils::FromStr(arg); if (op == "==") { return numstr == numarg; } else if (op == ">") { return numstr > numarg; } else if (op == "<") { return numstr < numarg; } else if (op == ">=") { return numstr >= numarg; } else if (op == "<=") { return numstr <= numarg; } else if (op == "!=") { return numstr != numarg; } else { return false; } } if (op == "==") { return str == arg; } else if (op == ">") { return str > arg; } else if (op == "<") { return str < arg; } else if (op == ">=") { return str >= arg; } else if (op == "<=") { return str <= arg; } else if (op == "!=") { return str != arg; } return false; }