@@ -50,8 +50,8 @@ static bool parseNamedColorString(const std::string &value, video::SColor &color
50
50
51
51
#ifndef _WIN32
52
52
53
- bool convert (const char *to, const char *from, char *outbuf,
54
- size_t outbuf_size, char *inbuf, size_t inbuf_size)
53
+ static bool convert (const char *to, const char *from, char *outbuf,
54
+ size_t * outbuf_size, char *inbuf, size_t inbuf_size)
55
55
{
56
56
iconv_t cd = iconv_open (to, from);
57
57
@@ -60,15 +60,14 @@ bool convert(const char *to, const char *from, char *outbuf,
60
60
#else
61
61
char *inbuf_ptr = inbuf;
62
62
#endif
63
-
64
63
char *outbuf_ptr = outbuf;
65
64
66
65
size_t *inbuf_left_ptr = &inbuf_size;
67
- size_t *outbuf_left_ptr = &outbuf_size;
68
66
67
+ const size_t old_outbuf_size = *outbuf_size;
69
68
size_t old_size = inbuf_size;
70
69
while (inbuf_size > 0 ) {
71
- iconv (cd, &inbuf_ptr, inbuf_left_ptr, &outbuf_ptr, outbuf_left_ptr );
70
+ iconv (cd, &inbuf_ptr, inbuf_left_ptr, &outbuf_ptr, outbuf_size );
72
71
if (inbuf_size == old_size) {
73
72
iconv_close (cd);
74
73
return false ;
@@ -77,70 +76,65 @@ bool convert(const char *to, const char *from, char *outbuf,
77
76
}
78
77
79
78
iconv_close (cd);
79
+ *outbuf_size = old_outbuf_size - *outbuf_size;
80
80
return true ;
81
81
}
82
82
83
83
#ifdef __ANDROID__
84
- // Android need manual caring to support the full character set possible with wchar_t
84
+ // On Android iconv disagrees how big a wchar_t is for whatever reason
85
85
const char *DEFAULT_ENCODING = " UTF-32LE" ;
86
86
#else
87
87
const char *DEFAULT_ENCODING = " WCHAR_T" ;
88
88
#endif
89
89
90
90
std::wstring utf8_to_wide (const std::string &input)
91
91
{
92
- size_t inbuf_size = input.length () + 1 ;
92
+ const size_t inbuf_size = input.length ();
93
93
// maximum possible size, every character is sizeof(wchar_t) bytes
94
- size_t outbuf_size = ( input.length () + 1 ) * sizeof (wchar_t );
94
+ size_t outbuf_size = input.length () * sizeof (wchar_t );
95
95
96
- char *inbuf = new char [inbuf_size];
96
+ char *inbuf = new char [inbuf_size]; // intentionally NOT null-terminated
97
97
memcpy (inbuf, input.c_str (), inbuf_size);
98
- char *outbuf = new char [outbuf_size] ;
99
- memset (outbuf, 0 , outbuf_size );
98
+ std::wstring out ;
99
+ out. resize (outbuf_size / sizeof ( wchar_t ) );
100
100
101
101
#ifdef __ANDROID__
102
- // Android need manual caring to support the full character set possible with wchar_t
103
102
SANITY_CHECK (sizeof (wchar_t ) == 4 );
104
103
#endif
105
104
106
- if (!convert (DEFAULT_ENCODING, " UTF-8" , outbuf, outbuf_size, inbuf, inbuf_size)) {
105
+ char *outbuf = reinterpret_cast <char *>(&out[0 ]);
106
+ if (!convert (DEFAULT_ENCODING, " UTF-8" , outbuf, &outbuf_size, inbuf, inbuf_size)) {
107
107
infostream << " Couldn't convert UTF-8 string 0x" << hex_encode (input)
108
108
<< " into wstring" << std::endl;
109
109
delete[] inbuf;
110
- delete[] outbuf;
111
110
return L" <invalid UTF-8 string>" ;
112
111
}
113
- std::wstring out ((wchar_t *)outbuf);
114
-
115
112
delete[] inbuf;
116
- delete[] outbuf;
117
113
114
+ out.resize (outbuf_size / sizeof (wchar_t ));
118
115
return out;
119
116
}
120
117
121
118
std::string wide_to_utf8 (const std::wstring &input)
122
119
{
123
- size_t inbuf_size = ( input.length () + 1 ) * sizeof (wchar_t );
124
- // maximum possible size: utf-8 encodes codepoints using 1 up to 6 bytes
125
- size_t outbuf_size = ( input.length () + 1 ) * 6 ;
120
+ const size_t inbuf_size = input.length () * sizeof (wchar_t );
121
+ // maximum possible size: utf-8 encodes codepoints using 1 up to 4 bytes
122
+ size_t outbuf_size = input.length () * 4 ;
126
123
127
- char *inbuf = new char [inbuf_size];
124
+ char *inbuf = new char [inbuf_size]; // intentionally NOT null-terminated
128
125
memcpy (inbuf, input.c_str (), inbuf_size);
129
- char *outbuf = new char [outbuf_size] ;
130
- memset (outbuf, 0 , outbuf_size);
126
+ std::string out ;
127
+ out. resize ( outbuf_size);
131
128
132
- if (!convert (" UTF-8" , DEFAULT_ENCODING, outbuf, outbuf_size, inbuf, inbuf_size)) {
129
+ if (!convert (" UTF-8" , DEFAULT_ENCODING, &out[ 0 ], & outbuf_size, inbuf, inbuf_size)) {
133
130
infostream << " Couldn't convert wstring 0x" << hex_encode (inbuf, inbuf_size)
134
131
<< " into UTF-8 string" << std::endl;
135
132
delete[] inbuf;
136
- delete[] outbuf;
137
- return " <invalid wstring>" ;
133
+ return " <invalid wide string>" ;
138
134
}
139
- std::string out (outbuf);
140
-
141
135
delete[] inbuf;
142
- delete[] outbuf;
143
136
137
+ out.resize (outbuf_size);
144
138
return out;
145
139
}
146
140
@@ -172,15 +166,12 @@ std::string wide_to_utf8(const std::wstring &input)
172
166
173
167
#endif // _WIN32
174
168
175
- // You must free the returned string!
176
- // The returned string is allocated using new
177
169
wchar_t *utf8_to_wide_c (const char *str)
178
170
{
179
171
std::wstring ret = utf8_to_wide (std::string (str));
180
172
size_t len = ret.length ();
181
173
wchar_t *ret_c = new wchar_t [len + 1 ];
182
- memset (ret_c, 0 , (len + 1 ) * sizeof (wchar_t ));
183
- memcpy (ret_c, ret.c_str (), len * sizeof (wchar_t ));
174
+ memcpy (ret_c, ret.c_str (), (len + 1 ) * sizeof (wchar_t ));
184
175
return ret_c;
185
176
}
186
177
0 commit comments