// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdmisc.h" #include "nel/misc/string_common.h" #include "nel/misc/sstring.h" using namespace std; #ifdef DEBUG_NEW #define new DEBUG_NEW #endif namespace NLMISC { string addSlashR(const string &str) { string formatedStr; // replace \n with \r\n for (uint i = 0; i < str.size(); i++) { if (str[i] == '\n' && i > 0 && str[i - 1] != '\r') { formatedStr += '\r'; } formatedStr += str[i]; } return formatedStr; } string removeSlashR(const string &str) { string formatedStr; // remove \r for (uint i = 0; i < str.size(); i++) { if (str[i] != '\r') formatedStr += str[i]; } return formatedStr; } bool fromString(const std::string &str, bool &val) { if (str.length() == 1) { const char c = str[0]; switch (c) { case '1': case 't': case 'T': case 'y': case 'Y': val = true; break; case '0': case 'f': case 'F': case 'n': case 'N': val = false; break; default: val = false; return false; } } else { std::string strl = toLower(str); if (strl == "true" || strl == "yes") { val = true; } else if (strl == "false" || strl == "no") { val = false; } else { val = false; return false; } } return true; } #if defined(NL_OS_WINDOWS) std::string winWideToCp(const wchar_t *str, size_t len, UINT cp) { if (!len) len = wcslen(str); if (!len) return std::string(); // Convert from wide to codepage char *tmp = (char *)_malloca((len + 1) * 4); if (!tmp) return std::string(); int tmpLen = WideCharToMultiByte(cp, 0, str, (int)(len + 1), tmp, (int)((len + 1) * 4), NULL, NULL); if (tmpLen <= 1) { _freea(tmp); return std::string(); } std::string res = tmp; _freea(tmp); return res; } std::string winCpToCp(const char *str, size_t len, UINT srcCp, UINT dstCp) { if (!len) len = strlen(str); if (!len) return std::string(); // First convert from codepage to wide wchar_t *tmp = (wchar_t *)_malloca((len + 1) * 4); if (!tmp) return std::string(); int tmpLen = MultiByteToWideChar(srcCp, 0, str, (int)(len + 1), /* include null-termination */ tmp, (int)((len + 1) * 4)); if (tmpLen <= 1) { _freea(tmp); return std::string(); } // Then convert from wide to codepage std::string res = winWideToCp(tmp, (size_t)tmpLen - 1, dstCp); /* tmpLen includes null-term */ _freea(tmp); return res; } std::wstring winCpToWide(const char *str, size_t len, UINT cp) { if (!len) len = strlen(str); if (!len) return std::wstring(); // Convert from codepage to wide wchar_t *tmp = (wchar_t *)_malloca((len + 1) * 4); if (!tmp) return std::wstring(); int tmpLen = MultiByteToWideChar(cp, MB_PRECOMPOSED, str, (int)(len + 1), /* include null-termination */ tmp, (int)((len + 1) * 4)); if (tmpLen <= 1) { _freea(tmp); return std::wstring(); } std::wstring res = tmp; _freea(tmp); return res; } #endif // Convert local codepage to UTF-8 // On Windows, the local codepage is undetermined // On Linux, the local codepage is always UTF-8 (no-op) std::string mbcsToUtf8(const char *str, size_t len) { #if defined(NL_OS_WINDOWS) UINT codePage = GetACP(); // Windows 10 allows setting the local codepage to UTF-8 if (codePage == CP_UTF8) /* 65001 */ return str; return winCpToCp(str, len, CP_ACP, CP_UTF8); #else return str; /* no-op */ #endif } std::string mbcsToUtf8(const std::string &str) { #if defined(NL_OS_WINDOWS) if (str.empty()) return str; UINT codePage = GetACP(); // Windows 10 allows setting the local codepage to UTF-8 if (codePage == CP_UTF8) /* 65001 */ return str; return winCpToCp(str.c_str(), str.size(), CP_ACP, CP_UTF8); #else return str; /* no-op */ #endif } // Convert wide codepage to UTF-8 // On Windows, the wide codepage is UTF-16 // On Linux, the wide codepage is UTF-32 std::string wideToUtf8(const wchar_t *str, size_t len) { #if defined(NL_OS_WINDOWS) return winWideToCp(str, len, CP_UTF8); #else // TODO: UTF-32 to UTF-8 nlassert(false); #endif } std::string wideToUtf8(const std::wstring &str) { return wideToUtf8(str.c_str(), str.size()); } // Convert UTF-8 to wide character set std::wstring utf8ToWide(const char *str, size_t len) { #if defined(NL_OS_WINDOWS) return winCpToWide(str, len, CP_UTF8); #else // TODO: UTF-32 to UTF-8 nlassert(false); #endif } std::wstring utf8ToWide(const std::string &str) { return utf8ToWide(str.c_str(), str.size()); } // Convert UTF-8 to local multibyte character set std::string utf8ToMbcs(const char *str, size_t len) { #if defined(NL_OS_WINDOWS) UINT codePage = GetACP(); // Windows 10 allows setting the local codepage to UTF-8 if (codePage == CP_UTF8) /* 65001 */ return str; return winCpToCp(str, len, CP_UTF8, CP_ACP); #else return str; /* no-op */ #endif } std::string utf8ToMbcs(const std::string &str) { #if defined(NL_OS_WINDOWS) if (str.empty()) return str; UINT codePage = GetACP(); // Windows 10 allows setting the local codepage to UTF-8 if (codePage == CP_UTF8) /* 65001 */ return str; return winCpToCp(str.c_str(), str.size(), CP_UTF8, CP_ACP); #else return str; /* no-op */ #endif } // Convert wide to local multibyte character set std::string wideToMbcs(const wchar_t *str, size_t len) { #if defined(NL_OS_WINDOWS) return winWideToCp(str, len, CP_ACP); #else return wideToUtf8(str, len); #endif } std::string wideToMbcs(const std::wstring &str) { #if defined(NL_OS_WINDOWS) return winWideToCp(str.c_str(), str.size(), CP_ACP); #else return wideToUtf8(str); #endif } // Convert local multibyte to wide character set std::wstring mbcsToWide(const char *str, size_t len) { #if defined(NL_OS_WINDOWS) return winCpToWide(str, len, CP_ACP); #else return utf8ToWide(str, len); #endif } std::wstring mbcsToWide(const std::string &str) { #if defined(NL_OS_WINDOWS) return winCpToWide(str.c_str(), str.size(), CP_ACP); #else return utf8ToWide(str); #endif } }