Merge branch '138-toggle-free-look-with-hotkey' into 'main/atys-live'
[ryzomcore.git] / nel / src / misc / string_common.cpp
blobbb39c747bb0754b29d5b95e756b3ff747371199b
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdmisc.h"
22 #include "nel/misc/string_common.h"
23 #include "nel/misc/sstring.h"
24 #include "nel/misc/utf_string_view.h"
26 using namespace std;
28 #ifdef DEBUG_NEW
29 #define new DEBUG_NEW
30 #endif
32 namespace NLMISC
35 string addSlashR(const string &str)
37 string formatedStr;
38 // replace \n with \r\n
39 for (uint i = 0; i < str.size(); i++)
41 if (str[i] == '\n' && i > 0 && str[i - 1] != '\r')
43 formatedStr += '\r';
45 formatedStr += str[i];
47 return formatedStr;
50 string removeSlashR(const string &str)
52 string formatedStr;
53 // remove \r
54 for (uint i = 0; i < str.size(); i++)
56 if (str[i] != '\r')
57 formatedStr += str[i];
59 return formatedStr;
62 bool fromString(const std::string &str, bool &val)
64 if (str.length() == 1)
66 const char c = str[0];
68 switch (c)
70 case '1':
71 case 't':
72 case 'T':
73 case 'y':
74 case 'Y':
75 val = true;
76 break;
78 case '0':
79 case 'f':
80 case 'F':
81 case 'n':
82 case 'N':
83 val = false;
84 break;
86 default:
87 val = false;
88 return false;
91 else
93 std::string strl = toLowerAscii(str);
94 if (strl == "true" || strl == "yes")
96 val = true;
98 else if (strl == "false" || strl == "no")
100 val = false;
102 else
104 val = false;
105 return false;
109 return true;
112 #if defined(NL_OS_WINDOWS)
114 std::string winWideToCp(const wchar_t *str, size_t len, UINT cp)
116 if (!len)
117 len = wcslen(str);
118 if (!len)
119 return std::string();
121 // Convert from wide to codepage
122 char *tmp = (char *)_malloca((len + 1) * 4);
123 if (!tmp)
124 return std::string();
125 int tmpLen = WideCharToMultiByte(cp, 0,
126 str, (int)(len + 1),
127 tmp, (int)((len + 1) * 4),
128 NULL, NULL);
129 if (tmpLen <= 1)
131 _freea(tmp);
132 return std::string();
135 std::string res = tmp;
136 _freea(tmp);
137 return res;
140 std::string winCpToCp(const char *str, size_t len, UINT srcCp, UINT dstCp)
142 if (!len)
143 len = strlen(str);
144 if (!len)
145 return std::string();
147 // First convert from codepage to wide
148 wchar_t *tmp = (wchar_t *)_malloca((len + 1) * 4);
149 if (!tmp)
150 return std::string();
151 int tmpLen = MultiByteToWideChar(srcCp, 0,
152 str, (int)(len + 1), /* include null-termination */
153 tmp, (int)((len + 1) * 2));
154 if (tmpLen <= 1)
156 _freea(tmp);
157 return std::string();
160 // Then convert from wide to codepage
161 std::string res = winWideToCp(tmp, (size_t)tmpLen - 1, dstCp); /* tmpLen includes null-term */
162 _freea(tmp);
163 return res;
166 std::wstring winCpToWide(const char *str, size_t len, UINT cp)
168 if (!len)
169 len = strlen(str);
170 if (!len)
171 return std::wstring();
173 // Convert from codepage to wide
174 wchar_t *tmp = (wchar_t *)_malloca((len + 1) * 4);
175 if (!tmp)
176 return std::wstring();
177 int tmpLen = MultiByteToWideChar(cp, 0,
178 str, (int)(len + 1), /* include null-termination */
179 tmp, (int)((len + 1) * 2));
180 if (tmpLen <= 1)
182 _freea(tmp);
183 return std::wstring();
186 std::wstring res = tmp;
187 _freea(tmp);
188 return res;
191 #endif
193 // Convert local codepage to UTF-8
194 // On Windows, the local codepage is undetermined
195 // On Linux, the local codepage is always UTF-8 (no-op)
196 std::string mbcsToUtf8(const char *str, size_t len)
198 #if defined(NL_OS_WINDOWS)
199 UINT codePage = GetACP();
200 // Windows 10 allows setting the local codepage to UTF-8
201 if (codePage == CP_UTF8) /* 65001 */
202 return str;
203 return winCpToCp(str, len, CP_ACP, CP_UTF8);
204 #else
205 return str; /* no-op */
206 #endif
209 std::string mbcsToUtf8(const std::string &str)
211 #if defined(NL_OS_WINDOWS)
212 if (str.empty())
213 return str;
214 UINT codePage = GetACP();
215 // Windows 10 allows setting the local codepage to UTF-8
216 if (codePage == CP_UTF8) /* 65001 */
217 return str;
218 return winCpToCp(str.c_str(), str.size(), CP_ACP, CP_UTF8);
219 #else
220 return str; /* no-op */
221 #endif
224 // Convert wide codepage to UTF-8
225 // On Windows, the wide codepage is UTF-16
226 // On Linux, the wide codepage is UTF-32
227 std::string wideToUtf8(const wchar_t *str, size_t len)
229 #if defined(NL_OS_WINDOWS)
230 return winWideToCp(str, len, CP_UTF8);
231 #else
232 return CUtfStringView(str, len).toUtf8();
233 #endif
236 std::string wideToUtf8(const std::wstring &str)
238 return wideToUtf8(str.c_str(), str.size());
241 // Convert UTF-8 to wide character set
242 std::wstring utf8ToWide(const char *str, size_t len)
244 #if defined(NL_OS_WINDOWS)
245 return winCpToWide(str, len, CP_UTF8); // UTF-16
246 #else
247 return CUtfStringView(str, len).toWide(); // UTF-32
248 #endif
251 std::wstring utf8ToWide(const std::string &str)
253 return utf8ToWide(str.c_str(), str.size());
256 // Convert UTF-8 to local multibyte character set
257 std::string utf8ToMbcs(const char *str, size_t len)
259 #if defined(NL_OS_WINDOWS)
260 UINT codePage = GetACP();
261 // Windows 10 allows setting the local codepage to UTF-8
262 if (codePage == CP_UTF8) /* 65001 */
263 return str;
264 return winCpToCp(str, len, CP_UTF8, CP_ACP);
265 #else
266 return str; /* no-op */
267 #endif
270 std::string utf8ToMbcs(const std::string &str)
272 #if defined(NL_OS_WINDOWS)
273 if (str.empty())
274 return str;
275 UINT codePage = GetACP();
276 // Windows 10 allows setting the local codepage to UTF-8
277 if (codePage == CP_UTF8) /* 65001 */
278 return str;
279 return winCpToCp(str.c_str(), str.size(), CP_UTF8, CP_ACP);
280 #else
281 return str; /* no-op */
282 #endif
285 // Convert wide to local multibyte character set
286 std::string wideToMbcs(const wchar_t *str, size_t len)
288 #if defined(NL_OS_WINDOWS)
289 return winWideToCp(str, len, CP_ACP);
290 #else
291 return wideToUtf8(str, len);
292 #endif
295 std::string wideToMbcs(const std::wstring &str)
297 #if defined(NL_OS_WINDOWS)
298 return winWideToCp(str.c_str(), str.size(), CP_ACP);
299 #else
300 return wideToUtf8(str);
301 #endif
304 // Convert local multibyte to wide character set
305 std::wstring mbcsToWide(const char *str, size_t len)
307 #if defined(NL_OS_WINDOWS)
308 return winCpToWide(str, len, CP_ACP);
309 #else
310 return utf8ToWide(str, len);
311 #endif
314 std::wstring mbcsToWide(const std::string &str)
316 #if defined(NL_OS_WINDOWS)
317 return winCpToWide(str.c_str(), str.size(), CP_ACP);
318 #else
319 return utf8ToWide(str);
320 #endif