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 ()) ;
60+ size_t Offset = 0 ;
5461 for (size_t i = 0 ; i < Len; ++i)
55- NarrowStr[i] = ctfacet.narrow (WideStr[i], 0 );
62+ {
63+ char mb[4 ];
64+ int n = wctomb (mb, WideStr[i]);
65+ if (n > 0 )
66+ {
67+ Offset += n;
68+ NarrowStr.append (mb, mb + n);
69+ }
70+ }
5671
5772 return NarrowStr;
5873}
@@ -62,18 +77,31 @@ inline std::string NarrowString(const std::wstring& WideStr)
6277 return NarrowString (WideStr.c_str (), WideStr.length ());
6378}
6479
80+ // See also: https://en.cppreference.com/w/cpp/string/multibyte/mbtowc
6581inline std::wstring WidenString (const char * Str, size_t Len = 0 )
6682{
6783 if (Len == 0 )
6884 Len = strlen (Str);
6985 else
7086 VERIFY_EXPR (Len <= strlen (Str));
7187
72- std::wstring WideStr (Len, L' \0 ' );
88+ std::wstring WideStr;
89+ WideStr.reserve (Len);
7390
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]);
91+ for (size_t Offset = 0 ; Offset < Len;)
92+ {
93+ wchar_t wc;
94+ int n = mbtowc (&wc, Str + Offset, Len - Offset);
95+ if (n > 0 )
96+ {
97+ WideStr += wc;
98+ Offset += n;
99+ }
100+ else
101+ {
102+ break ;
103+ }
104+ }
77105
78106 return WideStr;
79107}
@@ -294,3 +322,7 @@ size_t GetPrintWidth(Type Num, Type Base = 10)
294322}
295323
296324} // namespace Diligent
325+
326+ #ifdef _MSC_VER
327+ # pragma warning(pop)
328+ #endif
0 commit comments