summaryrefslogtreecommitdiff
path: root/Source/Core/Common/StringUtil.cpp
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2016-06-24 10:43:46 +0200
committerPierre Bourdon <delroth@gmail.com>2016-06-24 10:43:46 +0200
commit3570c7f03a2aa90aa634f96c0af1969af610f14d (patch)
tree4252e03c0e853ba7cffe022937698c854ad0eaa9 /Source/Core/Common/StringUtil.cpp
parent2115e8a4a6814e32107b5205ff5c95bbd3c6e99c (diff)
Reformat all the things. Have fun with merge conflicts.
Diffstat (limited to 'Source/Core/Common/StringUtil.cpp')
-rw-r--r--Source/Core/Common/StringUtil.cpp590
1 files changed, 298 insertions, 292 deletions
diff --git a/Source/Core/Common/StringUtil.cpp b/Source/Core/Common/StringUtil.cpp
index 007da2685a..1e3eab1c4b 100644
--- a/Source/Core/Common/StringUtil.cpp
+++ b/Source/Core/Common/StringUtil.cpp
@@ -17,197 +17,197 @@
#include "Common/CommonFuncs.h"
#include "Common/CommonPaths.h"
#include "Common/CommonTypes.h"
-#include "Common/StringUtil.h"
#include "Common/Logging/Log.h"
+#include "Common/StringUtil.h"
#ifdef _WIN32
- #include <Windows.h>
+#include <Windows.h>
#else
- #include <iconv.h>
- #include <locale.h>
- #include <errno.h>
+#include <iconv.h>
+#include <locale.h>
+#include <errno.h>
#endif
#if !defined(_WIN32) && !defined(ANDROID)
static locale_t GetCLocale()
{
- static locale_t c_locale = newlocale(LC_ALL_MASK, "C", nullptr);
- return c_locale;
+ static locale_t c_locale = newlocale(LC_ALL_MASK, "C", nullptr);
+ return c_locale;
}
#endif
std::string HexDump(const u8* data, size_t size)
{
- constexpr size_t BYTES_PER_LINE = 16;
-
- std::string out;
- for (size_t row_start = 0; row_start < size; row_start += BYTES_PER_LINE)
- {
- out += StringFromFormat("%06zx: ", row_start);
- for (size_t i = 0; i < BYTES_PER_LINE; ++i)
- {
- if (row_start + i < size)
- {
- out += StringFromFormat("%02hhx ", data[row_start + i]);
- }
- else
- {
- out += " ";
- }
- }
- out += " ";
- for (size_t i = 0; i < BYTES_PER_LINE; ++i)
- {
- if (row_start + i < size)
- {
- char c = static_cast<char>(data[row_start + i]);
- out += StringFromFormat("%c", isprint(c) ? c : '.');
- }
- }
- out += "\n";
- }
- return out;
+ constexpr size_t BYTES_PER_LINE = 16;
+
+ std::string out;
+ for (size_t row_start = 0; row_start < size; row_start += BYTES_PER_LINE)
+ {
+ out += StringFromFormat("%06zx: ", row_start);
+ for (size_t i = 0; i < BYTES_PER_LINE; ++i)
+ {
+ if (row_start + i < size)
+ {
+ out += StringFromFormat("%02hhx ", data[row_start + i]);
+ }
+ else
+ {
+ out += " ";
+ }
+ }
+ out += " ";
+ for (size_t i = 0; i < BYTES_PER_LINE; ++i)
+ {
+ if (row_start + i < size)
+ {
+ char c = static_cast<char>(data[row_start + i]);
+ out += StringFromFormat("%c", isprint(c) ? c : '.');
+ }
+ }
+ out += "\n";
+ }
+ return out;
}
// faster than sscanf
bool AsciiToHex(const std::string& _szValue, u32& result)
{
- // Set errno to a good state.
- errno = 0;
+ // Set errno to a good state.
+ errno = 0;
- char* endptr = nullptr;
- const u32 value = strtoul(_szValue.c_str(), &endptr, 16);
+ char* endptr = nullptr;
+ const u32 value = strtoul(_szValue.c_str(), &endptr, 16);
- if (!endptr || *endptr)
- return false;
+ if (!endptr || *endptr)
+ return false;
- if (errno == ERANGE)
- return false;
+ if (errno == ERANGE)
+ return false;
- result = value;
- return true;
+ result = value;
+ return true;
}
bool CharArrayFromFormatV(char* out, int outsize, const char* format, va_list args)
{
- int writtenCount;
+ int writtenCount;
#ifdef _WIN32
- // You would think *printf are simple, right? Iterate on each character,
- // if it's a format specifier handle it properly, etc.
- //
- // Nooooo. Not according to the C standard.
- //
- // According to the C99 standard (7.19.6.1 "The fprintf function")
- // The format shall be a multibyte character sequence
- //
- // Because some character encodings might have '%' signs in the middle of
- // a multibyte sequence (SJIS for example only specifies that the first
- // byte of a 2 byte sequence is "high", the second byte can be anything),
- // printf functions have to decode the multibyte sequences and try their
- // best to not screw up.
- //
- // Unfortunately, on Windows, the locale for most languages is not UTF-8
- // as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the
- // locale, and completely fails when trying to decode UTF-8 as EUC-CN.
- //
- // On the other hand, the fix is simple: because we use UTF-8, no such
- // multibyte handling is required as we can simply assume that no '%' char
- // will be present in the middle of a multibyte sequence.
- //
- // This is why we look up the default C locale here and use _vsnprintf_l.
- static _locale_t c_locale = nullptr;
- if (!c_locale)
- c_locale = _create_locale(LC_ALL, "C");
- writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args);
+ // You would think *printf are simple, right? Iterate on each character,
+ // if it's a format specifier handle it properly, etc.
+ //
+ // Nooooo. Not according to the C standard.
+ //
+ // According to the C99 standard (7.19.6.1 "The fprintf function")
+ // The format shall be a multibyte character sequence
+ //
+ // Because some character encodings might have '%' signs in the middle of
+ // a multibyte sequence (SJIS for example only specifies that the first
+ // byte of a 2 byte sequence is "high", the second byte can be anything),
+ // printf functions have to decode the multibyte sequences and try their
+ // best to not screw up.
+ //
+ // Unfortunately, on Windows, the locale for most languages is not UTF-8
+ // as we would need. Notably, for zh_TW, Windows chooses EUC-CN as the
+ // locale, and completely fails when trying to decode UTF-8 as EUC-CN.
+ //
+ // On the other hand, the fix is simple: because we use UTF-8, no such
+ // multibyte handling is required as we can simply assume that no '%' char
+ // will be present in the middle of a multibyte sequence.
+ //
+ // This is why we look up the default C locale here and use _vsnprintf_l.
+ static _locale_t c_locale = nullptr;
+ if (!c_locale)
+ c_locale = _create_locale(LC_ALL, "C");
+ writtenCount = _vsnprintf_l(out, outsize, format, c_locale, args);
#else
- #if !defined(ANDROID)
- locale_t previousLocale = uselocale(GetCLocale());
- #endif
- writtenCount = vsnprintf(out, outsize, format, args);
- #if !defined(ANDROID)
- uselocale(previousLocale);
- #endif
+#if !defined(ANDROID)
+ locale_t previousLocale = uselocale(GetCLocale());
+#endif
+ writtenCount = vsnprintf(out, outsize, format, args);
+#if !defined(ANDROID)
+ uselocale(previousLocale);
+#endif
#endif
- if (writtenCount > 0 && writtenCount < outsize)
- {
- out[writtenCount] = '\0';
- return true;
- }
- else
- {
- out[outsize - 1] = '\0';
- return false;
- }
+ if (writtenCount > 0 && writtenCount < outsize)
+ {
+ out[writtenCount] = '\0';
+ return true;
+ }
+ else
+ {
+ out[outsize - 1] = '\0';
+ return false;
+ }
}
std::string StringFromFormat(const char* format, ...)
{
- va_list args;
- va_start(args, format);
- std::string res = StringFromFormatV(format, args);
- va_end(args);
- return res;
+ va_list args;
+ va_start(args, format);
+ std::string res = StringFromFormatV(format, args);
+ va_end(args);
+ return res;
}
std::string StringFromFormatV(const char* format, va_list args)
{
- char* buf = nullptr;
+ char* buf = nullptr;
#ifdef _WIN32
- int required = _vscprintf(format, args);
- buf = new char[required + 1];
- CharArrayFromFormatV(buf, required + 1, format, args);
+ int required = _vscprintf(format, args);
+ buf = new char[required + 1];
+ CharArrayFromFormatV(buf, required + 1, format, args);
- std::string temp = buf;
- delete[] buf;
+ std::string temp = buf;
+ delete[] buf;
#else
- #if !defined(ANDROID)
- locale_t previousLocale = uselocale(GetCLocale());
- #endif
- if (vasprintf(&buf, format, args) < 0)
- ERROR_LOG(COMMON, "Unable to allocate memory for string");
- #if !defined(ANDROID)
- uselocale(previousLocale);
- #endif
-
- std::string temp = buf;
- free(buf);
+#if !defined(ANDROID)
+ locale_t previousLocale = uselocale(GetCLocale());
+#endif
+ if (vasprintf(&buf, format, args) < 0)
+ ERROR_LOG(COMMON, "Unable to allocate memory for string");
+#if !defined(ANDROID)
+ uselocale(previousLocale);
+#endif
+
+ std::string temp = buf;
+ free(buf);
#endif
- return temp;
+ return temp;
}
// For Debugging. Read out an u8 array.
std::string ArrayToString(const u8* data, u32 size, int line_len, bool spaces)
{
- std::ostringstream oss;
- oss << std::setfill('0') << std::hex;
-
- for (int line = 0; size; ++data, --size)
- {
- oss << std::setw(2) << (int)*data;
-
- if (line_len == ++line)
- {
- oss << '\n';
- line = 0;
- }
- else if (spaces)
- oss << ' ';
- }
-
- return oss.str();
+ std::ostringstream oss;
+ oss << std::setfill('0') << std::hex;
+
+ for (int line = 0; size; ++data, --size)
+ {
+ oss << std::setw(2) << (int)*data;
+
+ if (line_len == ++line)
+ {
+ oss << '\n';
+ line = 0;
+ }
+ else if (spaces)
+ oss << ' ';
+ }
+
+ return oss.str();
}
// Turns " hej " into "hej". Also handles tabs.
std::string StripSpaces(const std::string& str)
{
- const size_t s = str.find_first_not_of(" \t\r\n");
+ const size_t s = str.find_first_not_of(" \t\r\n");
- if (str.npos != s)
- return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1);
- else
- return "";
+ if (str.npos != s)
+ return str.substr(s, str.find_last_not_of(" \t\r\n") - s + 1);
+ else
+ return "";
}
// "\"hello\"" is turned to "hello"
@@ -215,189 +215,195 @@ std::string StripSpaces(const std::string& str)
// ends, as done by StripSpaces above, for example.
std::string StripQuotes(const std::string& s)
{
- if (s.size() && '\"' == s[0] && '\"' == *s.rbegin())
- return s.substr(1, s.size() - 2);
- else
- return s;
+ if (s.size() && '\"' == s[0] && '\"' == *s.rbegin())
+ return s.substr(1, s.size() - 2);
+ else
+ return s;
}
bool TryParse(const std::string& str, u32* const output)
{
- char* endptr = nullptr;
+ char* endptr = nullptr;
- // Reset errno to a value other than ERANGE
- errno = 0;
+ // Reset errno to a value other than ERANGE
+ errno = 0;
- unsigned long value = strtoul(str.c_str(), &endptr, 0);
+ unsigned long value = strtoul(str.c_str(), &endptr, 0);
- if (!endptr || *endptr)
- return false;
+ if (!endptr || *endptr)
+ return false;
- if (errno == ERANGE)
- return false;
+ if (errno == ERANGE)
+ return false;
#if ULONG_MAX > UINT_MAX
- if (value >= 0x100000000ull &&
- value <= 0xFFFFFFFF00000000ull)
- return false;
+ if (value >= 0x100000000ull && value <= 0xFFFFFFFF00000000ull)
+ return false;
#endif
- *output = static_cast<u32>(value);
- return true;
+ *output = static_cast<u32>(value);
+ return true;
}
bool TryParse(const std::string& str, bool* const output)
{
- if ("1" == str || !strcasecmp("true", str.c_str()))
- *output = true;
- else if ("0" == str || !strcasecmp("false", str.c_str()))
- *output = false;
- else
- return false;
-
- return true;
+ if ("1" == str || !strcasecmp("true", str.c_str()))
+ *output = true;
+ else if ("0" == str || !strcasecmp("false", str.c_str()))
+ *output = false;
+ else
+ return false;
+
+ return true;
}
std::string StringFromInt(int value)
{
- char temp[16];
- sprintf(temp, "%i", value);
- return temp;
+ char temp[16];
+ sprintf(temp, "%i", value);
+ return temp;
}
std::string StringFromBool(bool value)
{
- return value ? "True" : "False";
+ return value ? "True" : "False";
}
-bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename, std::string* _pExtension)
+bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _pFilename,
+ std::string* _pExtension)
{
- if (full_path.empty())
- return false;
+ if (full_path.empty())
+ return false;
- size_t dir_end = full_path.find_last_of("/"
- // Windows needs the : included for something like just "C:" to be considered a directory
+ size_t dir_end = full_path.find_last_of("/"
+// Windows needs the : included for something like just "C:" to be considered a directory
#ifdef _WIN32
- ":"
+ ":"
#endif
- );
- if (std::string::npos == dir_end)
- dir_end = 0;
- else
- dir_end += 1;
+ );
+ if (std::string::npos == dir_end)
+ dir_end = 0;
+ else
+ dir_end += 1;
- size_t fname_end = full_path.rfind('.');
- if (fname_end < dir_end || std::string::npos == fname_end)
- fname_end = full_path.size();
+ size_t fname_end = full_path.rfind('.');
+ if (fname_end < dir_end || std::string::npos == fname_end)
+ fname_end = full_path.size();
- if (_pPath)
- *_pPath = full_path.substr(0, dir_end);
+ if (_pPath)
+ *_pPath = full_path.substr(0, dir_end);
- if (_pFilename)
- *_pFilename = full_path.substr(dir_end, fname_end - dir_end);
+ if (_pFilename)
+ *_pFilename = full_path.substr(dir_end, fname_end - dir_end);
- if (_pExtension)
- *_pExtension = full_path.substr(fname_end);
+ if (_pExtension)
+ *_pExtension = full_path.substr(fname_end);
- return true;
+ return true;
}
-void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path, const std::string& _Filename)
+void BuildCompleteFilename(std::string& _CompleteFilename, const std::string& _Path,
+ const std::string& _Filename)
{
- _CompleteFilename = _Path;
+ _CompleteFilename = _Path;
- // check for seperator
- if (DIR_SEP_CHR != *_CompleteFilename.rbegin())
- _CompleteFilename += DIR_SEP_CHR;
+ // check for seperator
+ if (DIR_SEP_CHR != *_CompleteFilename.rbegin())
+ _CompleteFilename += DIR_SEP_CHR;
- // add the filename
- _CompleteFilename += _Filename;
+ // add the filename
+ _CompleteFilename += _Filename;
}
void SplitString(const std::string& str, const char delim, std::vector<std::string>& output)
{
- std::istringstream iss(str);
- output.resize(1);
+ std::istringstream iss(str);
+ output.resize(1);
- while (std::getline(iss, *output.rbegin(), delim))
- output.push_back("");
+ while (std::getline(iss, *output.rbegin(), delim))
+ output.push_back("");
- output.pop_back();
+ output.pop_back();
}
std::string TabsToSpaces(int tab_size, const std::string& in)
{
- const std::string spaces(tab_size, ' ');
- std::string out(in);
+ const std::string spaces(tab_size, ' ');
+ std::string out(in);
- size_t i = 0;
- while (out.npos != (i = out.find('\t')))
- out.replace(i, 1, spaces);
+ size_t i = 0;
+ while (out.npos != (i = out.find('\t')))
+ out.replace(i, 1, spaces);
- return out;
+ return out;
}
std::string ReplaceAll(std::string result, const std::string& src, const std::string& dest)
{
- size_t pos = 0;
+ size_t pos = 0;
- if (src == dest)
- return result;
+ if (src == dest)
+ return result;
- while ((pos = result.find(src, pos)) != std::string::npos)
- {
- result.replace(pos, src.size(), dest);
- pos += dest.length();
- }
+ while ((pos = result.find(src, pos)) != std::string::npos)
+ {
+ result.replace(pos, src.size(), dest);
+ pos += dest.length();
+ }
- return result;
+ return result;
}
#ifdef _WIN32
std::string UTF16ToUTF8(const std::wstring& input)
{
- auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), (int)input.size(), nullptr, 0, nullptr, nullptr);
+ auto const size = WideCharToMultiByte(CP_UTF8, 0, input.data(), (int)input.size(), nullptr, 0,
+ nullptr, nullptr);
- std::string output;
- output.resize(size);
+ std::string output;
+ output.resize(size);
- if (size == 0 || size != WideCharToMultiByte(CP_UTF8, 0, input.data(), (int)input.size(), &output[0], (int)output.size(), nullptr, nullptr))
- {
- output.clear();
- }
+ if (size == 0 ||
+ size != WideCharToMultiByte(CP_UTF8, 0, input.data(), (int)input.size(), &output[0],
+ (int)output.size(), nullptr, nullptr))
+ {
+ output.clear();
+ }
- return output;
+ return output;
}
std::wstring CPToUTF16(u32 code_page, const std::string& input)
{
- auto const size = MultiByteToWideChar(code_page, 0, input.data(), (int)input.size(), nullptr, 0);
+ auto const size = MultiByteToWideChar(code_page, 0, input.data(), (int)input.size(), nullptr, 0);
- std::wstring output;
- output.resize(size);
+ std::wstring output;
+ output.resize(size);
- if (size == 0 || size != MultiByteToWideChar(code_page, 0, input.data(), (int)input.size(), &output[0], (int)output.size()))
- {
- output.clear();
- }
+ if (size == 0 ||
+ size != MultiByteToWideChar(code_page, 0, input.data(), (int)input.size(), &output[0],
+ (int)output.size()))
+ {
+ output.clear();
+ }
- return output;
+ return output;
}
std::wstring UTF8ToUTF16(const std::string& input)
{
- return CPToUTF16(CP_UTF8, input);
+ return CPToUTF16(CP_UTF8, input);
}
std::string SHIFTJISToUTF8(const std::string& input)
{
- return UTF16ToUTF8(CPToUTF16(932, input));
+ return UTF16ToUTF8(CPToUTF16(932, input));
}
std::string CP1252ToUTF8(const std::string& input)
{
- return UTF16ToUTF8(CPToUTF16(1252, input));
+ return UTF16ToUTF8(CPToUTF16(1252, input));
}
#else
@@ -405,79 +411,79 @@ std::string CP1252ToUTF8(const std::string& input)
template <typename T>
std::string CodeToUTF8(const char* fromcode, const std::basic_string<T>& input)
{
- std::string result;
-
- iconv_t const conv_desc = iconv_open("UTF-8", fromcode);
- if ((iconv_t)-1 == conv_desc)
- {
- ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno));
- }
- else
- {
- size_t const in_bytes = sizeof(T) * input.size();
- size_t const out_buffer_size = 4 * in_bytes;
-
- std::string out_buffer;
- out_buffer.resize(out_buffer_size);
-
- auto src_buffer = &input[0];
- size_t src_bytes = in_bytes;
- auto dst_buffer = &out_buffer[0];
- size_t dst_bytes = out_buffer.size();
-
- while (src_bytes != 0)
- {
- size_t const iconv_result = iconv(conv_desc, (char**)(&src_buffer), &src_bytes,
- &dst_buffer, &dst_bytes);
-
- if ((size_t)-1 == iconv_result)
- {
- if (EILSEQ == errno || EINVAL == errno)
- {
- // Try to skip the bad character
- if (src_bytes != 0)
- {
- --src_bytes;
- ++src_buffer;
- }
- }
- else
- {
- ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno));
- break;
- }
- }
- }
-
- out_buffer.resize(out_buffer_size - dst_bytes);
- out_buffer.swap(result);
-
- iconv_close(conv_desc);
- }
-
- return result;
+ std::string result;
+
+ iconv_t const conv_desc = iconv_open("UTF-8", fromcode);
+ if ((iconv_t)-1 == conv_desc)
+ {
+ ERROR_LOG(COMMON, "Iconv initialization failure [%s]: %s", fromcode, strerror(errno));
+ }
+ else
+ {
+ size_t const in_bytes = sizeof(T) * input.size();
+ size_t const out_buffer_size = 4 * in_bytes;
+
+ std::string out_buffer;
+ out_buffer.resize(out_buffer_size);
+
+ auto src_buffer = &input[0];
+ size_t src_bytes = in_bytes;
+ auto dst_buffer = &out_buffer[0];
+ size_t dst_bytes = out_buffer.size();
+
+ while (src_bytes != 0)
+ {
+ size_t const iconv_result =
+ iconv(conv_desc, (char**)(&src_buffer), &src_bytes, &dst_buffer, &dst_bytes);
+
+ if ((size_t)-1 == iconv_result)
+ {
+ if (EILSEQ == errno || EINVAL == errno)
+ {
+ // Try to skip the bad character
+ if (src_bytes != 0)
+ {
+ --src_bytes;
+ ++src_buffer;
+ }
+ }
+ else
+ {
+ ERROR_LOG(COMMON, "iconv failure [%s]: %s", fromcode, strerror(errno));
+ break;
+ }
+ }
+ }
+
+ out_buffer.resize(out_buffer_size - dst_bytes);
+ out_buffer.swap(result);
+
+ iconv_close(conv_desc);
+ }
+
+ return result;
}
std::string CP1252ToUTF8(const std::string& input)
{
- //return CodeToUTF8("CP1252//TRANSLIT", input);
- //return CodeToUTF8("CP1252//IGNORE", input);
- return CodeToUTF8("CP1252", input);
+ // return CodeToUTF8("CP1252//TRANSLIT", input);
+ // return CodeToUTF8("CP1252//IGNORE", input);
+ return CodeToUTF8("CP1252", input);
}
std::string SHIFTJISToUTF8(const std::string& input)
{
- //return CodeToUTF8("CP932", input);
- return CodeToUTF8("SJIS", input);
+ // return CodeToUTF8("CP932", input);
+ return CodeToUTF8("SJIS", input);
}
std::string UTF16ToUTF8(const std::wstring& input)
{
- std::string result = CodeToUTF8("UTF-16LE", input);
+ std::string result = CodeToUTF8("UTF-16LE", input);
- // TODO: why is this needed?
- result.erase(std::remove(result.begin(), result.end(), 0x00), result.end());
- return result;
+ // TODO: why is this needed?
+ result.erase(std::remove(result.begin(), result.end(), 0x00), result.end());
+ return result;
}
#endif