2014-04-01 02:33:55 +02:00
|
|
|
#include "stdafx.h"
|
2014-08-29 21:51:11 +02:00
|
|
|
#include <wx/string.h>
|
2014-04-01 02:33:55 +02:00
|
|
|
|
2015-01-12 21:37:29 +01:00
|
|
|
std::string u128::to_hex() const
|
|
|
|
{
|
2015-01-18 23:54:56 +01:00
|
|
|
return fmt::format("%016llx%016llx", _u64[1], _u64[0]);
|
2015-01-12 21:37:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string u128::to_xyzw() const
|
|
|
|
{
|
|
|
|
return fmt::Format("x: %g y: %g z: %g w: %g", _f[3], _f[2], _f[1], _f[0]);
|
|
|
|
}
|
|
|
|
|
2015-01-19 14:31:02 +01:00
|
|
|
std::string fmt::to_hex(u64 value, size_t count)
|
2015-01-18 23:54:56 +01:00
|
|
|
{
|
|
|
|
assert(count - 1 < 16);
|
|
|
|
count = std::max<u64>(count, 16 - cntlz64(value) / 4);
|
|
|
|
|
|
|
|
char res[16] = {};
|
|
|
|
|
|
|
|
for (size_t i = count - 1; ~i; i--, value /= 16)
|
|
|
|
{
|
|
|
|
res[i] = "0123456789abcdef"[value % 16];
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::string(res, count);
|
|
|
|
}
|
|
|
|
|
2015-01-19 14:31:02 +01:00
|
|
|
std::string fmt::to_udec(u64 value)
|
|
|
|
{
|
|
|
|
char res[20] = {};
|
|
|
|
size_t first = sizeof(res);
|
|
|
|
|
|
|
|
if (!value)
|
|
|
|
{
|
|
|
|
res[--first] = '0';
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; value; value /= 10)
|
|
|
|
{
|
|
|
|
res[--first] = '0' + (value % 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::string(&res[first], sizeof(res) - first);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string fmt::to_sdec(s64 svalue)
|
|
|
|
{
|
|
|
|
const bool sign = svalue < 0;
|
|
|
|
u64 value = sign ? -svalue : svalue;
|
|
|
|
|
|
|
|
char res[20] = {};
|
|
|
|
size_t first = sizeof(res);
|
|
|
|
|
|
|
|
if (!value)
|
|
|
|
{
|
|
|
|
res[--first] = '0';
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; value; value /= 10)
|
|
|
|
{
|
|
|
|
res[--first] = '0' + (value % 10);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (sign)
|
|
|
|
{
|
|
|
|
res[--first] = '-';
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::string(&res[first], sizeof(res) - first);
|
|
|
|
}
|
|
|
|
|
2015-01-18 23:54:56 +01:00
|
|
|
size_t fmt::detail::get_fmt_start(const char* fmt, size_t len)
|
|
|
|
{
|
|
|
|
for (size_t i = 0; i < len; i++)
|
|
|
|
{
|
|
|
|
if (fmt[i] == '%')
|
|
|
|
{
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t fmt::detail::get_fmt_len(const char* fmt, size_t len)
|
|
|
|
{
|
|
|
|
assert(len >= 2 && fmt[0] == '%');
|
|
|
|
|
|
|
|
size_t res = 2;
|
|
|
|
|
|
|
|
if (fmt[1] == '.' || fmt[1] == '0')
|
|
|
|
{
|
|
|
|
assert(len >= 4 && fmt[2] - '1' < 9);
|
|
|
|
res += 2;
|
|
|
|
fmt += 2;
|
|
|
|
len -= 2;
|
|
|
|
|
2015-01-22 00:45:50 +01:00
|
|
|
if (fmt[0] == '1')
|
2015-01-18 23:54:56 +01:00
|
|
|
{
|
2015-01-22 00:45:50 +01:00
|
|
|
assert(len >= 3 && fmt[1] - '0' < 7);
|
2015-01-18 23:54:56 +01:00
|
|
|
res++;
|
|
|
|
fmt++;
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fmt[1] == 'l')
|
|
|
|
{
|
|
|
|
assert(len >= 3);
|
|
|
|
res++;
|
|
|
|
fmt++;
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fmt[1] == 'l')
|
|
|
|
{
|
|
|
|
assert(len >= 3);
|
|
|
|
res++;
|
|
|
|
fmt++;
|
|
|
|
len--;
|
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t fmt::detail::get_fmt_precision(const char* fmt, size_t len)
|
|
|
|
{
|
|
|
|
assert(len >= 2);
|
|
|
|
|
|
|
|
if (fmt[1] == '.' || fmt[1] == '0')
|
|
|
|
{
|
|
|
|
assert(len >= 4 && fmt[2] - '1' < 9);
|
|
|
|
|
|
|
|
if (fmt[2] == '1')
|
|
|
|
{
|
|
|
|
assert(len >= 5 && fmt[3] - '0' < 7);
|
|
|
|
return 10 + fmt[3] - '0';
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt[2] - '0';
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2015-02-02 10:14:49 +01:00
|
|
|
std::string fmt::detail::format(const char* fmt)
|
2015-01-18 23:54:56 +01:00
|
|
|
{
|
2015-02-02 10:14:49 +01:00
|
|
|
const size_t len = strlen(fmt);
|
2015-01-18 23:54:56 +01:00
|
|
|
const size_t fmt_start = get_fmt_start(fmt, len);
|
|
|
|
if (fmt_start != len)
|
|
|
|
{
|
|
|
|
throw "Excessive formatting: " + std::string(fmt, len);
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::string(fmt, len);
|
|
|
|
}
|
|
|
|
|
2014-04-08 19:29:17 +02:00
|
|
|
extern const std::string fmt::placeholder = "???";
|
2014-04-01 19:44:38 +02:00
|
|
|
|
2015-02-02 11:21:35 +01:00
|
|
|
std::string fmt::replace_first(const std::string& src, const std::string& from, const std::string& to)
|
2014-06-07 16:15:49 +02:00
|
|
|
{
|
|
|
|
auto pos = src.find(from);
|
|
|
|
|
|
|
|
if (pos == std::string::npos)
|
|
|
|
{
|
|
|
|
return src;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (pos ? src.substr(0, pos) + to : to) + std::string(src.c_str() + pos + from.length());
|
|
|
|
}
|
|
|
|
|
2015-02-02 11:21:35 +01:00
|
|
|
std::string fmt::replace_all(const std::string &src, const std::string& from, const std::string& to)
|
2014-06-07 16:15:49 +02:00
|
|
|
{
|
2015-02-02 11:21:35 +01:00
|
|
|
std::string target = src;
|
|
|
|
for (auto pos = target.find(from); pos != std::string::npos; pos = target.find(from, pos + 1))
|
2014-06-07 16:15:49 +02:00
|
|
|
{
|
2015-02-02 11:21:35 +01:00
|
|
|
target = (pos ? target.substr(0, pos) + to : to) + std::string(target.c_str() + pos + from.length());
|
2014-06-07 16:15:49 +02:00
|
|
|
pos += to.length();
|
|
|
|
}
|
|
|
|
|
2015-02-04 13:16:10 +01:00
|
|
|
return target;
|
2014-06-07 16:15:49 +02:00
|
|
|
}
|
|
|
|
|
2014-06-08 23:02:20 +02:00
|
|
|
//TODO: move this wx Stuff somewhere else
|
|
|
|
//convert a wxString to a std::string encoded in utf8
|
|
|
|
//CAUTION, only use this to interface with wxWidgets classes
|
|
|
|
std::string fmt::ToUTF8(const wxString& right)
|
|
|
|
{
|
|
|
|
auto ret = std::string(((const char *)right.utf8_str()));
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
//convert a std::string encoded in utf8 to a wxString
|
|
|
|
//CAUTION, only use this to interface with wxWidgets classes
|
|
|
|
wxString fmt::FromUTF8(const std::string& right)
|
|
|
|
{
|
|
|
|
auto ret = wxString::FromUTF8(right.c_str());
|
|
|
|
return ret;
|
|
|
|
}
|
2014-04-01 02:33:55 +02:00
|
|
|
|
|
|
|
//TODO: remove this after every snippet that uses it is gone
|
|
|
|
//WARNING: not fully compatible with CmpNoCase from wxString
|
|
|
|
int fmt::CmpNoCase(const std::string& a, const std::string& b)
|
|
|
|
{
|
|
|
|
if (a.length() != b.length())
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return std::equal(a.begin(),
|
|
|
|
a.end(),
|
|
|
|
b.begin(),
|
2014-11-30 12:18:17 +01:00
|
|
|
[](const char& a, const char& b){return ::tolower(a) == ::tolower(b); })
|
2014-04-01 02:33:55 +02:00
|
|
|
? 0 : -1;
|
|
|
|
}
|
2014-05-02 08:30:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//TODO: remove this after every snippet that uses it is gone
|
|
|
|
//WARNING: not fully compatible with CmpNoCase from wxString
|
|
|
|
void fmt::Replace(std::string &str, const std::string &searchterm, const std::string& replaceterm)
|
|
|
|
{
|
|
|
|
size_t cursor = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
cursor = str.find(searchterm, cursor);
|
|
|
|
if (cursor != std::string::npos)
|
|
|
|
{
|
|
|
|
str.replace(cursor, searchterm.size(), replaceterm);
|
|
|
|
cursor += replaceterm.size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (true);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> fmt::rSplit(const std::string& source, const std::string& delim)
|
|
|
|
{
|
|
|
|
std::vector<std::string> ret;
|
|
|
|
size_t cursor = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
size_t prevcurs = cursor;
|
|
|
|
cursor = source.find(delim, cursor);
|
|
|
|
if (cursor != std::string::npos)
|
|
|
|
{
|
|
|
|
ret.push_back(source.substr(prevcurs,cursor-prevcurs));
|
|
|
|
cursor += delim.size();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ret.push_back(source.substr(prevcurs));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while (true);
|
|
|
|
return ret;
|
2014-11-29 14:16:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> fmt::split(const std::string& source, std::initializer_list<std::string> separators, bool is_skip_empty)
|
|
|
|
{
|
|
|
|
std::vector<std::string> result;
|
|
|
|
|
|
|
|
size_t cursor_begin = 0;
|
|
|
|
|
|
|
|
for (size_t cursor_end = 0; cursor_end < source.length(); ++cursor_end)
|
|
|
|
{
|
|
|
|
for (auto &separator : separators)
|
|
|
|
{
|
|
|
|
if (strncmp(source.c_str() + cursor_end, separator.c_str(), separator.length()) == 0)
|
|
|
|
{
|
|
|
|
std::string candidate = source.substr(cursor_begin, cursor_end - cursor_begin);
|
|
|
|
if (!is_skip_empty || !candidate.empty())
|
|
|
|
result.push_back(candidate);
|
|
|
|
|
|
|
|
cursor_begin = cursor_end + separator.length();
|
|
|
|
cursor_end = cursor_begin - 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cursor_begin != source.length())
|
|
|
|
{
|
|
|
|
result.push_back(source.substr(cursor_begin));
|
|
|
|
}
|
|
|
|
|
|
|
|
return std::move(result);
|
2014-11-30 12:18:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string fmt::merge(std::vector<std::string> source, const std::string& separator)
|
|
|
|
{
|
2014-12-21 00:30:30 +01:00
|
|
|
if (!source.size())
|
2014-12-26 15:06:36 +01:00
|
|
|
{
|
2014-12-21 00:30:30 +01:00
|
|
|
return "";
|
2014-12-26 15:06:36 +01:00
|
|
|
}
|
2014-12-21 00:30:30 +01:00
|
|
|
|
2014-11-30 12:18:17 +01:00
|
|
|
std::string result;
|
|
|
|
|
2014-12-21 00:30:30 +01:00
|
|
|
for (int i = 0; i < source.size() - 1; ++i)
|
2014-11-30 12:18:17 +01:00
|
|
|
{
|
2014-12-21 00:30:30 +01:00
|
|
|
result += source[i] + separator;
|
2014-11-30 12:18:17 +01:00
|
|
|
}
|
|
|
|
|
2014-12-21 00:30:30 +01:00
|
|
|
return result + source[source.size() - 1];
|
2014-11-30 12:18:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string fmt::merge(std::initializer_list<std::vector<std::string>> sources, const std::string& separator)
|
|
|
|
{
|
2014-12-26 15:06:36 +01:00
|
|
|
if (!sources.size())
|
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
2014-11-30 12:18:17 +01:00
|
|
|
std::string result;
|
2014-12-26 15:06:36 +01:00
|
|
|
bool first = true;
|
2014-11-30 12:18:17 +01:00
|
|
|
|
|
|
|
for (auto &v : sources)
|
|
|
|
{
|
2014-12-26 15:06:36 +01:00
|
|
|
if (first)
|
|
|
|
{
|
|
|
|
result = fmt::merge(v, separator);
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result += separator + fmt::merge(v, separator);
|
|
|
|
}
|
2014-11-30 12:18:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string fmt::tolower(std::string source)
|
|
|
|
{
|
|
|
|
std::transform(source.begin(), source.end(), source.begin(), ::tolower);
|
|
|
|
|
|
|
|
return source;
|
2014-12-17 17:10:20 +01:00
|
|
|
}
|
2015-02-04 13:16:10 +01:00
|
|
|
|
|
|
|
std::string fmt::toupper(std::string source)
|
|
|
|
{
|
|
|
|
std::transform(source.begin(), source.end(), source.begin(), ::toupper);
|
|
|
|
|
|
|
|
return source;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string fmt::escape(std::string source)
|
|
|
|
{
|
|
|
|
const std::pair<std::string, std::string> escape_list[] =
|
|
|
|
{
|
|
|
|
{ "\\", "\\\\" },
|
|
|
|
{ "\a", "\\a" },
|
|
|
|
{ "\b", "\\b" },
|
|
|
|
{ "\f", "\\f" },
|
|
|
|
{ "\n", "\\n" },
|
|
|
|
{ "\r", "\\r" },
|
|
|
|
{ "\t", "\\t" },
|
|
|
|
{ "\v", "\\v" },
|
|
|
|
};
|
|
|
|
|
|
|
|
source = fmt::replace_all(source, escape_list);
|
|
|
|
|
|
|
|
for (char c = 0; c < 32; c++)
|
|
|
|
{
|
|
|
|
source = fmt::replace_all(source, std::string(1, c), fmt::Format("\\x%02X", c));
|
|
|
|
}
|
|
|
|
|
|
|
|
return source;
|
|
|
|
}
|