← Back to file list Raw

src/U_String.cpp

#include "U_String.h"
#include <algorithm>
#include <cctype>
#include <iostream>
#include <cwctype>
std::wstring StringUtils::StrToWstr(const std::string& str)
{
/*std::vector<wchar_t> buf(str.size());
std::use_facet<std::ctype<wchar_t>>(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<wchar_t>(str);
}
std::string StringUtils::WstrToStr(const std::wstring& wstr)
{
/*std::vector<char> buf(wstr.size());
std::use_facet<std::ctype<wchar_t>>(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<char>(wstr);
}
std::u16string StringUtils::Utf8ToU16(const std::string& str)
{
return boost::locale::conv::utf_to_utf<char16_t>(str);
}
std::string StringUtils::U16ToUtf8(const std::u16string& str)
{
return boost::locale::conv::utf_to_utf<char>(str);
}
std::u16string StringUtils::WstrToU16(const std::wstring& wstr)
{
return boost::locale::conv::utf_to_utf<char16_t>(wstr);
}
std::wstring StringUtils::U16ToWstr(const std::u16string& str)
{
return boost::locale::conv::utf_to_utf<wchar_t>(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<std::string>& 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<std::wstring>& 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<std::string> StringUtils::split_str(const std::string& s, char delim)
{
std::vector<std::string> ret;
split_str(s, delim, ret);
return ret;
}
std::vector<std::wstring> StringUtils::split_str(const std::wstring& s, wchar_t delim)
{
std::vector<std::wstring> 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<std::wstring> CommandPreprocess::SplitCommands(const std::wstring& input)
{
std::vector<std::wstring> 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<std::wstring> CommandPreprocess::ParseArguments(const std::wstring& command)
{
std::vector<std::wstring> 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<std::vector<std::wstring>> CommandPreprocess::PreProcessString(std::wstring cmdline)
{
Trim(cmdline);
if (cmdline.empty())
{
return {};
}
PreprocessEscapes(cmdline);
std::vector<std::vector<std::wstring>> result;
std::vector<std::wstring> commands = SplitCommands(cmdline);
for (auto& cmd : commands)
{
std::vector<std::wstring> 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<std::string> ArgumentsPreprocess::ParseArguments(std::string cmdline)
{
std::vector<std::string> 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<double>(str);
double numarg = StringUtils::FromStr<double>(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;
}