feat: 移除在非windows上locale的实现 (#9680)

This commit is contained in:
Autumn Sound
2024-09-15 14:17:32 +08:00
committed by GitHub
parent b27df9b509
commit 331bfa11ce
2 changed files with 95 additions and 102 deletions

View File

@@ -14,125 +14,111 @@
#include <locale.h>
#include <io.h>
#include "Platform/SafeWindows.h"
#endif
namespace asst::utils
{
template <typename _ = void>
inline std::string ansi_to_utf8(std::string_view ansi_str)
{
#ifdef _WIN32
const char* src_str = ansi_str.data();
const int byte_len = static_cast<int>(ansi_str.length() * sizeof(char));
int len = MultiByteToWideChar(CP_ACP, 0, src_str, byte_len, nullptr, 0);
const std::size_t wstr_length = static_cast<std::size_t>(len) + 1U;
auto wstr = new wchar_t[wstr_length];
memset(wstr, 0, sizeof(wstr[0]) * wstr_length);
MultiByteToWideChar(CP_ACP, 0, src_str, byte_len, wstr, len);
template <typename _ = void>
inline std::string ansi_to_utf8(std::string_view ansi_str)
{
const char* src_str = ansi_str.data();
const int byte_len = static_cast<int>(ansi_str.length() * sizeof(char));
int len = MultiByteToWideChar(CP_ACP, 0, src_str, byte_len, nullptr, 0);
const std::size_t wstr_length = static_cast<std::size_t>(len) + 1U;
auto wstr = new wchar_t[wstr_length];
memset(wstr, 0, sizeof(wstr[0]) * wstr_length);
MultiByteToWideChar(CP_ACP, 0, src_str, byte_len, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr);
const std::size_t str_length = static_cast<std::size_t>(len) + 1;
auto str = new char[str_length];
memset(str, 0, sizeof(str[0]) * str_length);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, nullptr, nullptr);
std::string strTemp = str;
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr);
const std::size_t str_length = static_cast<std::size_t>(len) + 1;
auto str = new char[str_length];
memset(str, 0, sizeof(str[0]) * str_length);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, nullptr, nullptr);
std::string strTemp = str;
delete[] wstr;
wstr = nullptr;
delete[] str;
str = nullptr;
delete[] wstr;
wstr = nullptr;
delete[] str;
str = nullptr;
return strTemp;
#else // Don't fucking use gbk in linux!
ASST_STATIC_ASSERT_FALSE("Workaround for windows, not implemented in other OS yet.", _);
return std::string(ansi_str);
#endif
}
return strTemp;
}
template <typename _ = void>
inline std::string utf8_to_ansi(std::string_view utf8_str)
{
#ifdef _WIN32
const char* src_str = utf8_str.data();
const int byte_len = static_cast<int>(utf8_str.length() * sizeof(char));
int len = MultiByteToWideChar(CP_UTF8, 0, src_str, byte_len, nullptr, 0);
const std::size_t wsz_ansi_length = static_cast<std::size_t>(len) + 1U;
auto wsz_ansi = new wchar_t[wsz_ansi_length];
memset(wsz_ansi, 0, sizeof(wsz_ansi[0]) * wsz_ansi_length);
MultiByteToWideChar(CP_UTF8, 0, src_str, byte_len, wsz_ansi, len);
template <typename _ = void>
inline std::string utf8_to_ansi(std::string_view utf8_str)
{
const char* src_str = utf8_str.data();
const int byte_len = static_cast<int>(utf8_str.length() * sizeof(char));
int len = MultiByteToWideChar(CP_UTF8, 0, src_str, byte_len, nullptr, 0);
const std::size_t wsz_ansi_length = static_cast<std::size_t>(len) + 1U;
auto wsz_ansi = new wchar_t[wsz_ansi_length];
memset(wsz_ansi, 0, sizeof(wsz_ansi[0]) * wsz_ansi_length);
MultiByteToWideChar(CP_UTF8, 0, src_str, byte_len, wsz_ansi, len);
len = WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, nullptr, 0, nullptr, nullptr);
const std::size_t sz_ansi_length = static_cast<std::size_t>(len) + 1;
auto sz_ansi = new char[sz_ansi_length];
memset(sz_ansi, 0, sizeof(sz_ansi[0]) * sz_ansi_length);
WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, sz_ansi, len, nullptr, nullptr);
std::string strTemp(sz_ansi);
len = WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, nullptr, 0, nullptr, nullptr);
const std::size_t sz_ansi_length = static_cast<std::size_t>(len) + 1;
auto sz_ansi = new char[sz_ansi_length];
memset(sz_ansi, 0, sizeof(sz_ansi[0]) * sz_ansi_length);
WideCharToMultiByte(CP_ACP, 0, wsz_ansi, -1, sz_ansi, len, nullptr, nullptr);
std::string strTemp(sz_ansi);
delete[] wsz_ansi;
wsz_ansi = nullptr;
delete[] sz_ansi;
sz_ansi = nullptr;
delete[] wsz_ansi;
wsz_ansi = nullptr;
delete[] sz_ansi;
sz_ansi = nullptr;
return strTemp;
#else // Don't fucking use gbk in linux!
ASST_STATIC_ASSERT_FALSE("Workaround for windows, not implemented in other OS yet.", _);
return std::string(utf8_str);
#endif
}
return strTemp;
}
template <typename _ = void>
inline std::string utf8_to_unicode_escape(std::string_view utf8_str)
{
#ifdef _WIN32
const char* src_str = utf8_str.data();
int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, nullptr, 0);
const std::size_t wstr_length = static_cast<std::size_t>(len) + 1U;
auto wstr = new wchar_t[wstr_length];
memset(wstr, 0, sizeof(wstr[0]) * wstr_length);
MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wstr, len);
template <typename _ = void>
inline std::string utf8_to_unicode_escape(std::string_view utf8_str)
{
const char* src_str = utf8_str.data();
int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, nullptr, 0);
const std::size_t wstr_length = static_cast<std::size_t>(len) + 1U;
auto wstr = new wchar_t[wstr_length];
memset(wstr, 0, sizeof(wstr[0]) * wstr_length);
MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wstr, len);
std::string unicode_escape_str = {};
constinit static char hexcode[] = "0123456789abcdef";
for (const wchar_t* pchr = wstr; *pchr; ++pchr) {
const wchar_t& chr = *pchr;
if (chr > 255) {
unicode_escape_str += "\\u";
unicode_escape_str.push_back(hexcode[chr >> 12]);
unicode_escape_str.push_back(hexcode[(chr >> 8) & 15]);
unicode_escape_str.push_back(hexcode[(chr >> 4) & 15]);
unicode_escape_str.push_back(hexcode[chr & 15]);
}
else {
unicode_escape_str.push_back(chr & 255);
}
std::string unicode_escape_str = {};
constinit static char hexcode[] = "0123456789abcdef";
for (const wchar_t* pchr = wstr; *pchr; ++pchr) {
const wchar_t& chr = *pchr;
if (chr > 255) {
unicode_escape_str += "\\u";
unicode_escape_str.push_back(hexcode[chr >> 12]);
unicode_escape_str.push_back(hexcode[(chr >> 8) & 15]);
unicode_escape_str.push_back(hexcode[(chr >> 4) & 15]);
unicode_escape_str.push_back(hexcode[chr & 15]);
}
else {
unicode_escape_str.push_back(chr & 255);
}
delete[] wstr;
wstr = nullptr;
return unicode_escape_str;
#else
ASST_STATIC_ASSERT_FALSE("Workaround for windows, not implemented in other OS yet.", _);
return std::string(utf8_str);
#endif
}
inline std::string load_file_without_bom(const std::filesystem::path& path)
{
std::ifstream ifs(path, std::ios::in);
if (!ifs.is_open()) {
return {};
}
std::stringstream iss;
iss << ifs.rdbuf();
ifs.close();
std::string str = iss.str();
delete[] wstr;
wstr = nullptr;
if (str.starts_with("\xEF\xBB\xBF")) {
str.assign(str.begin() + 3, str.end());
}
return str;
return unicode_escape_str;
}
inline std::string load_file_without_bom(const std::filesystem::path& path)
{
std::ifstream ifs(path, std::ios::in);
if (!ifs.is_open()) {
return {};
}
std::stringstream iss;
iss << ifs.rdbuf();
ifs.close();
std::string str = iss.str();
if (str.starts_with("\xEF\xBB\xBF")) {
str.assign(str.begin() + 3, str.end());
}
return str;
}
class utf8_scope
{
@@ -189,4 +175,7 @@ namespace asst::utils
}
#endif
};
} // namespace asst::utils
#endif

View File

@@ -272,6 +272,7 @@ public:
requires has_stream_insertion_operator<std::ostream, T>
console_ostream& operator<<(T&& v)
{
#ifdef _WIN32
if constexpr (std::convertible_to<T, std::string_view>) {
asst::utils::utf8_scope scope(m_ofs.get());
m_ofs.get() << std::forward<T>(v);
@@ -279,6 +280,9 @@ public:
else {
m_ofs.get() << std::forward<T>(v);
}
#else
m_ofs.get() << std::forward<T>(v);
#endif
return *this;
}