3838#include " StringTools.h"
3939#include " ParsingTools.hpp"
4040
41+ #ifdef _MSC_VER
42+ # pragma warning(push)
43+ # pragma warning(disable : 4996) // 'This function or variable may be unsafe': mbtowc, wctomb
44+ #endif
45+
4146namespace Diligent
4247{
4348
49+ // See also: https://en.cppreference.com/w/cpp/string/multibyte/wctomb
4450inline std::string NarrowString (const wchar_t * WideStr, size_t Len = 0 )
4551{
4652 if (Len == 0 )
4753 Len = wcslen (WideStr);
4854 else
4955 VERIFY_EXPR (Len <= wcslen (WideStr));
5056
51- std::string NarrowStr (Len, ' \0 ' );
57+ std::string NarrowStr;
58+ NarrowStr.reserve (Len * 4 ); /* MB_CUR_MAX = 4 */
5259
53- const std::ctype<wchar_t >& ctfacet = std::use_facet<std::ctype<wchar_t >>(std::wstringstream ().getloc ());
5460 for (size_t i = 0 ; i < Len; ++i)
55- NarrowStr[i] = ctfacet.narrow (WideStr[i], 0 );
61+ {
62+ char mb[4 ];
63+ int n = wctomb (mb, WideStr[i]);
64+ if (n > 0 )
65+ {
66+ NarrowStr.append (mb, mb + n);
67+ }
68+ }
5669
5770 return NarrowStr;
5871}
@@ -62,18 +75,31 @@ inline std::string NarrowString(const std::wstring& WideStr)
6275 return NarrowString (WideStr.c_str (), WideStr.length ());
6376}
6477
78+ // See also: https://en.cppreference.com/w/cpp/string/multibyte/mbtowc
6579inline std::wstring WidenString (const char * Str, size_t Len = 0 )
6680{
6781 if (Len == 0 )
6882 Len = strlen (Str);
6983 else
7084 VERIFY_EXPR (Len <= strlen (Str));
7185
72- std::wstring WideStr (Len, L' \0 ' );
86+ std::wstring WideStr;
87+ WideStr.reserve (Len);
7388
74- const std::ctype<wchar_t >& ctfacet = std::use_facet<std::ctype<wchar_t >>(std::wstringstream ().getloc ());
75- for (size_t i = 0 ; i < Len; ++i)
76- WideStr[i] = ctfacet.widen (Str[i]);
89+ for (size_t Offset = 0 ; Offset < Len;)
90+ {
91+ wchar_t wc;
92+ int n = mbtowc (&wc, Str + Offset, Len - Offset);
93+ if (n > 0 )
94+ {
95+ WideStr += wc;
96+ Offset += n;
97+ }
98+ else
99+ {
100+ break ;
101+ }
102+ }
77103
78104 return WideStr;
79105}
@@ -294,3 +320,7 @@ size_t GetPrintWidth(Type Num, Type Base = 10)
294320}
295321
296322} // namespace Diligent
323+
324+ #ifdef _MSC_VER
325+ # pragma warning(pop)
326+ #endif
0 commit comments