mirror of
https://github.com/CDAGaming/blizzget
synced 2025-11-09 19:15:58 +03:00
166 lines
4.5 KiB
C++
166 lines
4.5 KiB
C++
#include "string.h"
|
|
|
|
#include <stdarg.h>
|
|
#include <clocale>
|
|
#include <algorithm>
|
|
#include "types.h"
|
|
#include "error.h"
|
|
|
|
std::string strlower(std::string const& str) {
|
|
std::string dest(str.size(), ' ');
|
|
std::transform(str.begin(), str.end(), dest.begin(), std::tolower);
|
|
return dest;
|
|
}
|
|
|
|
std::vector<std::string> split(std::string const& str, char sep) {
|
|
std::vector<std::string> res;
|
|
std::string cur;
|
|
for (char c : str) {
|
|
if (c == sep) {
|
|
res.push_back(cur);
|
|
cur.clear();
|
|
} else {
|
|
cur.push_back(c);
|
|
}
|
|
}
|
|
res.push_back(cur);
|
|
return res;
|
|
}
|
|
|
|
std::vector<std::string> split_multiple(std::string const& str, char const* sep) {
|
|
std::vector<std::string> res;
|
|
std::string cur;
|
|
for (char c : str) {
|
|
if (strchr(sep, c)) {
|
|
res.push_back(cur);
|
|
cur.clear();
|
|
} else {
|
|
cur.push_back(c);
|
|
}
|
|
}
|
|
res.push_back(cur);
|
|
return res;
|
|
}
|
|
|
|
std::vector<std::string> split(std::string const& str, char const* sep) {
|
|
size_t sep_length = strlen(sep);
|
|
std::vector<std::string> res;
|
|
size_t pos = 0, next;
|
|
while ((next = str.find(sep, pos)) != std::string::npos) {
|
|
res.push_back(str.substr(pos, next - pos));
|
|
pos = next + sep_length;
|
|
}
|
|
res.push_back(str.substr(pos));
|
|
return res;
|
|
}
|
|
|
|
std::string join(std::vector<std::string> const& list, char sep) {
|
|
std::string res;
|
|
for (auto& str : list) {
|
|
if (!res.empty()) res.push_back(' ');
|
|
res.append(str);
|
|
}
|
|
return res;
|
|
}
|
|
std::string join(std::vector<std::string> const& list, std::string const& sep) {
|
|
std::string res;
|
|
for (auto& str : list) {
|
|
if (!res.empty()) res.append(sep);
|
|
res.append(str);
|
|
}
|
|
return res;
|
|
}
|
|
std::string fmtstring(char const* fmt, ...) {
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
std::string res = varfmtstring(fmt, ap);
|
|
va_end(ap);
|
|
return res;
|
|
}
|
|
std::string varfmtstring(char const* fmt, va_list list) {
|
|
uint32 len = _vscprintf(fmt, list);
|
|
std::string dst;
|
|
dst.resize(len + 1);
|
|
vsprintf(&dst[0], fmt, list);
|
|
dst.resize(len);
|
|
return dst;
|
|
}
|
|
|
|
std::wstring utf8_to_utf16(std::string const& str) {
|
|
std::wstring dst;
|
|
for (size_t i = 0; i < str.size();) {
|
|
uint32 cp = (unsigned char) str[i++];
|
|
size_t next = 0;
|
|
if (cp <= 0x7F) {
|
|
// do nothing
|
|
} else if (cp <= 0xBF) {
|
|
throw Exception("not a valid utf-8 string");
|
|
} else if (cp <= 0xDF) {
|
|
cp &= 0x1F;
|
|
next = 1;
|
|
} else if (cp <= 0xEF) {
|
|
cp &= 0x0F;
|
|
next = 2;
|
|
} else if (cp <= 0xF7) {
|
|
cp &= 0x07;
|
|
next = 3;
|
|
} else {
|
|
throw Exception("not a valid utf-8 string");
|
|
}
|
|
while (next--) {
|
|
if (i >= str.size() || str[i] < 0x80 || str[i] > 0xBF) {
|
|
throw Exception("not a valid utf-8 string");
|
|
}
|
|
cp = (cp << 6) | (str[i++] & 0x3F);
|
|
}
|
|
if ((cp >= 0xD800 && cp <= 0xDFFF) || cp > 0x10FFFF) {
|
|
throw Exception("not a valid utf-8 string");
|
|
}
|
|
|
|
if (cp <= 0xFFFF) {
|
|
dst.push_back(cp);
|
|
} else {
|
|
cp -= 0x10000;
|
|
dst.push_back((cp >> 10) + 0xD800);
|
|
dst.push_back((cp & 0x3FF) + 0xDC00);
|
|
}
|
|
}
|
|
return dst;
|
|
}
|
|
|
|
std::string utf16_to_utf8(std::wstring const& str) {
|
|
std::string dst;
|
|
for (size_t i = 0; i < str.size();) {
|
|
uint32 cp = str[i++];
|
|
if (cp >= 0xD800 && cp <= 0xDFFF) {
|
|
if (cp >= 0xDC00) throw Exception("not a valid utf-16 string");
|
|
if (i >= str.size() || str[i] < 0xDC00 || str[i] > 0xDFFF) throw Exception("not a valid utf-16 string");
|
|
cp = 0x10000 + ((cp - 0xD800) << 10) + (str[i++] - 0xDC00);
|
|
}
|
|
if (cp >= 0x10FFFF) throw Exception("not a valid utf-16 string");
|
|
if (cp <= 0x7F) {
|
|
dst.push_back(cp);
|
|
} else if (cp <= 0x7FF) {
|
|
dst.push_back((cp >> 6) | 0xC0);
|
|
dst.push_back((cp & 0x3F) | 0x80);
|
|
} else if (cp <= 0xFFFF) {
|
|
dst.push_back((cp >> 12) | 0xE0);
|
|
dst.push_back(((cp >> 6) & 0x3F) | 0x80);
|
|
dst.push_back((cp & 0x3F) | 0x80);
|
|
} else {
|
|
dst.push_back((cp >> 18) | 0xF0);
|
|
dst.push_back(((cp >> 12) & 0x3F) | 0x80);
|
|
dst.push_back(((cp >> 6) & 0x3F) | 0x80);
|
|
dst.push_back((cp & 0x3F) | 0x80);
|
|
}
|
|
}
|
|
return dst;
|
|
}
|
|
|
|
std::string trim(std::string const& str) {
|
|
size_t left = 0, right = str.size();
|
|
while (left < str.length() && isspace((unsigned char) str[left])) ++left;
|
|
while (right > left && isspace((unsigned char) str[right - 1])) --right;
|
|
return str.substr(left, right - left);
|
|
}
|