You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ryzom-core/code/nel/src/misc/string_common.cpp

322 lines
6.5 KiB
C++

// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// 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 <http://www.gnu.org/licenses/>.
#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) * 2));
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, 0,
str, (int)(len + 1), /* include null-termination */
tmp, (int)((len + 1) * 2));
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
6 years ago
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
6 years ago
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
}
}