#include "precompile.h" #include "SpUtility.h" #include "charset.h" #include "dbgutil.h" #define TAG SPBASE_TAG("SpUtility") namespace SP { namespace Utility { namespace { enum CPType { ACP = 0, OEMCP = 1, MACCP = 2, THREAD_ACP = 3, SYMBOL = 42, UTF7 = 65000, UTF8 = 65001 }; static std::wstring LocaleToWStr(const std::string& str, const char* locale_name, CPType cp_type) { #ifdef _MSC_VER wchar_t* wstr = NULL; int n = ::MultiByteToWideChar((UINT)cp_type, 0, str.c_str(), -1, NULL, 0); if (n > 0) { wstr = new wchar_t[n + 1]; if (wstr == NULL) { return std::wstring(); } std::memset(wstr, 0, (n + 1) * sizeof(wchar_t)); ::MultiByteToWideChar((UINT)cp_type, 0, str.c_str(), -1, &wstr[0], n); std::wstring strr(wstr); delete wstr; return strr; } return std::wstring(); #else if (str.empty()) { return L""; } unsigned len = str.size() + 1; const char* origin = setlocale(LC_CTYPE, NULL); if (NULL == setlocale(LC_CTYPE, locale_name)) { printf("setlocale with \"%s\" failed!\n", locale_name); } wchar_t* p = new wchar_t[len]; mbstowcs(p, str.c_str(), len); std::wstring w_str(p); delete[] p; setlocale(LC_CTYPE, origin); return w_str; #endif } static std::string WStrToLocale(const std::wstring wstr, const char* locale_name, CPType cp_type) { #ifdef _MSC_VER char* str = NULL; int n = ::WideCharToMultiByte((UINT)cp_type, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL); if (n > 0) { str = new char[n + 1]; if (str == NULL) { return std::string(); } std::memset(str, 0, sizeof(char) * (n + 1)); ::WideCharToMultiByte((UINT)cp_type, 0, wstr.c_str(), -1, &str[0], n, NULL, NULL); std::string strr(str); delete str; return strr; } return std::string(); #else if (wstr.empty()) { return ""; } const char* origin = setlocale(LC_CTYPE, NULL); if (NULL == setlocale(LC_CTYPE, locale_name)) { printf("setlocale with \"%s\" failed!\n", locale_name); } unsigned len = wcstombs(NULL, wstr.c_str(), 0) + 1; char* p = new char[len]; wcstombs(p, wstr.c_str(), len); TOOLKIT_ASSERT(len >= 1); p[len - 1] = '\0'; std::string str(p); delete[] p; setlocale(LC_CTYPE, origin); return str; #endif } } std::string GBK2UTF8(const std::string str) { std::string result(""); if (str.empty()) return result; if (toolkit_detect_utf8_str(str.c_str())) { result = str; } else { auto ret = toolkit_gbk2utf8((char*)str.c_str(), str.length(), NULL, 0); if (ret <= 0) return result; char* arr = new char[ret]; ret = toolkit_gbk2utf8((char*)str.c_str(), str.length(), arr, ret); if (ret > 0) { result = arr; } delete[] arr; } return result; } std::string UTF8ToGBK(const std::string str) { std::string result(""); if (str.empty()) return result; if (!toolkit_detect_utf8_str(str.c_str())) { result = str; } else { auto ret = toolkit_utf82gbk((char*)str.c_str(), str.length(), NULL, 0); if (ret <= 0) return result; char* arr = new char[ret]; ret = toolkit_utf82gbk((char*)str.c_str(), str.length(), arr, ret); if (ret > 0) { result = arr; } delete[] arr; } return result; } std::string W2S(const std::wstring wstr) { std::string result(""); if (wstr.empty()) return result; auto ret = toolkit_wcs2mbs(wstr.c_str(), NULL, 0); if (ret <= 0) return result; char* arr = new char[ret]; ret = toolkit_wcs2mbs(wstr.c_str(), arr, ret); if (ret <= 0) { delete[] arr; return result; } result = arr; delete[] arr; return result; } std::wstring S2W(const std::string str) { std::wstring result(L""); if (str.empty()) return result; auto ret = toolkit_mbs2wcs(str.c_str(), NULL, 0); if (ret <= 0) return result; wchar_t* arr = new wchar_t[ret]; ret = toolkit_mbs2wcs(str.c_str(), arr, ret); if (ret <= 0) { delete[] arr; return result; } result = arr; delete[] arr; return result; } } }