ReactOS 0.4.16-dev-835-gd769f56
mbstowcs.cpp
Go to the documentation of this file.
1/***
2*mbstowcs.c - Convert multibyte char string to wide char string.
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* Convert a multibyte char string into the equivalent wide char string.
8*
9*******************************************************************************/
13#include <ctype.h>
14#include <errno.h>
15#include <locale.h>
16#include <stdlib.h>
17
18using namespace __crt_mbstring;
19
20/***
21*size_t mbstowcs() - Convert multibyte char string to wide char string.
22*
23*Purpose:
24* Convert a multi-byte char string into the equivalent wide char string,
25* according to the LC_CTYPE category of the current locale.
26* [ANSI].
27*
28*Entry:
29* wchar_t *pwcs = pointer to destination wide character string buffer
30* const char *s = pointer to source multibyte character string
31* size_t n = maximum number of wide characters to store
32*
33*Exit:
34* If pwcs != nullptr returns the number of words modified (<=n): note that
35* if the return value == n, then no destination string is not 0 terminated.
36* If pwcs == nullptr returns the length (not size) needed for the destination buffer.
37*
38*Exceptions:
39* Returns (size_t)-1 if s is nullptr or invalid mbcs character encountered
40* and errno is set to EILSEQ.
41*
42*******************************************************************************/
43
44/* Helper shared by secure and non-secure functions */
45
47 _Out_writes_opt_z_(n) wchar_t * pwcs,
48 _In_reads_or_z_(n) _Pre_z_ const char * s,
49 _In_ size_t n,
50 _In_opt_ __crt_cached_ptd_host& ptd
51 ) throw()
52{
53 size_t count = 0;
54
55 if (pwcs && n == 0)
56 {
57 /* dest string exists, but 0 bytes converted */
58 return (size_t) 0;
59 }
60
61 if (pwcs && n > 0)
62 {
63 *pwcs = '\0';
64 }
65
66 /* validation section */
67 _UCRT_VALIDATE_RETURN(ptd, s != nullptr, EINVAL, (size_t) - 1);
68
69 _locale_t const locale = ptd.get_locale();
70
71 if (locale->locinfo->_public._locale_lc_codepage == CP_UTF8)
72 {
74 return __mbsrtowcs_utf8(pwcs, &s, n, &state, ptd);
75 }
76
77 /* if destination string exists, fill it in */
78 if (pwcs)
79 {
80 if (locale->locinfo->locale_name[LC_CTYPE] == nullptr)
81 {
82 /* C locale: easy and fast */
83 while (count < n)
84 {
85 *pwcs = (wchar_t) ((unsigned char) s[count]);
86 if (!s[count])
87 {
88 return count;
89 }
90 count++;
91 pwcs++;
92 }
93 return count;
94
95 }
96 else {
97 int bytecnt, charcnt;
98 unsigned char *p;
99
100 /* Assume that the buffer is large enough */
101 if ((count = __acrt_MultiByteToWideChar(locale->locinfo->_public._locale_lc_codepage,
104 s,
105 -1,
106 pwcs,
107 (int) n)) != 0)
108 {
109 return count - 1; /* don't count NUL */
110 }
111
113 {
114 ptd.get_errno().set(EILSEQ);
115 *pwcs = '\0';
116 return (size_t) - 1;
117 }
118
119 /* User-supplied buffer not large enough. */
120
121 /* How many bytes are in n characters of the string? */
122 charcnt = (int) n;
123 for (p = (unsigned char *) s; (charcnt-- && *p); p++)
124 {
126 {
127 if (p[1] == '\0')
128 {
129 /* this is a leadbyte followed by EOS -- a dud MBCS string
130 We choose not to assert here because this
131 function is defined to deal with dud strings on
132 input and return a known value
133 */
134 ptd.get_errno().set(EILSEQ);
135 *pwcs = '\0';
136 return (size_t) - 1;
137 }
138 else
139 {
140 p++;
141 }
142 }
143 }
144 bytecnt = ((int) ((char *) p - (char *) s));
145
146 if ((count = __acrt_MultiByteToWideChar(locale->locinfo->_public._locale_lc_codepage,
148 s,
149 bytecnt,
150 pwcs,
151 (int) n)) == 0)
152 {
153 ptd.get_errno().set(EILSEQ);
154 *pwcs = '\0';
155 return (size_t) - 1;
156 }
157
158 return count; /* no NUL in string */
159 }
160 }
161 else {
162 /* pwcs == nullptr, get size only, s must be NUL-terminated */
163 if (locale->locinfo->locale_name[LC_CTYPE] == nullptr)
164 {
165 return strlen(s);
166 }
167 else if ((count = __acrt_MultiByteToWideChar(locale->locinfo->_public._locale_lc_codepage,
169 s,
170 -1,
171 nullptr,
172 0)) == 0)
173 {
174 ptd.get_errno().set(EILSEQ);
175 return (size_t) - 1;
176 }
177 else
178 {
179 return count - 1;
180 }
181 }
182
183}
184
185extern "C" size_t __cdecl _mbstowcs_l(
186 wchar_t *pwcs,
187 const char *s,
188 size_t n,
190 )
191{
192 /* Call a non-deprecated helper to do the work. */
193 __crt_cached_ptd_host ptd(plocinfo);
194 return _mbstowcs_l_helper(pwcs, s, n, ptd);
195}
196
197extern "C" size_t __cdecl mbstowcs(
198 wchar_t *pwcs,
199 const char *s,
200 size_t n
201 )
202{
203 __crt_cached_ptd_host ptd;
204 return _mbstowcs_l_helper(pwcs, s, n, ptd);
205}
206
207/***
208*errno_t mbstowcs_s() - Convert multibyte char string to wide char string.
209*
210*Purpose:
211* Convert a multi-byte char string into the equivalent wide char string,
212* according to the LC_CTYPE category of the current locale.
213* Same as mbstowcs(), but the destination is ensured to be null terminated.
214* If there's not enough space, we return EINVAL.
215*
216*Entry:
217* size_t *pConvertedChars = Number of bytes modified including the terminating nullptr
218* This pointer can be nullptr.
219* wchar_t *pwcs = pointer to destination wide character string buffer
220* size_t sizeInWords = size of the destination buffer
221* const char *s = pointer to source multibyte character string
222* size_t n = maximum number of wide characters to store (not including the terminating nullptr)
223*
224*Exit:
225* The error code.
226*
227*Exceptions:
228* Input parameters are validated. Refer to the validation section of the function.
229*
230*******************************************************************************/
231
233 size_t * pConvertedChars,
234 wchar_t * pwcs,
235 size_t sizeInWords,
236 const char * s,
237 size_t n,
238 __crt_cached_ptd_host& ptd
239 )
240{
241 size_t retsize;
242 errno_t retvalue = 0;
243
244 /* validation section */
245 _UCRT_VALIDATE_RETURN_ERRCODE(ptd, (pwcs == nullptr && sizeInWords == 0) || (pwcs != nullptr && sizeInWords > 0), EINVAL);
246
247 if (pwcs != nullptr)
248 {
249 _RESET_STRING(pwcs, sizeInWords);
250 }
251
252 if (pConvertedChars != nullptr)
253 {
254 *pConvertedChars = 0;
255 }
256
257 size_t bufferSize = n > sizeInWords ? sizeInWords : n;
258 /* n must fit into an int for MultiByteToWideChar */
260
261 /* Call a non-deprecated helper to do the work. */
262
263 retsize = _mbstowcs_l_helper(pwcs, s, bufferSize, ptd);
264
265 if (retsize == (size_t) - 1)
266 {
267 if (pwcs != nullptr)
268 {
269 _RESET_STRING(pwcs, sizeInWords);
270 }
271 return ptd.get_errno().value_or(0);
272 }
273
274 /* count the null terminator */
275 retsize++;
276
277 if (pwcs != nullptr)
278 {
279 /* return error if the string does not fit, unless n == _TRUNCATE */
280 if (retsize > sizeInWords)
281 {
282 if (n != _TRUNCATE)
283 {
284 _RESET_STRING(pwcs, sizeInWords);
285 _UCRT_VALIDATE_RETURN_ERRCODE(ptd, retsize <= sizeInWords, ERANGE);
286 }
287 retsize = sizeInWords;
288 retvalue = STRUNCATE;
289 }
290
291 /* ensure the string is null terminated */
292 pwcs[retsize - 1] = '\0';
293 }
294
295 if (pConvertedChars != nullptr)
296 {
297 *pConvertedChars = retsize;
298 }
299
300 return retvalue;
301}
302
304 size_t * pConvertedChars,
305 wchar_t * pwcs,
306 size_t sizeInWords,
307 const char * s,
308 size_t n,
310 )
311{
312 __crt_cached_ptd_host ptd(plocinfo);
313 return _mbstowcs_internal(pConvertedChars, pwcs, sizeInWords, s, n, ptd);
314}
315
317 size_t *pConvertedChars,
318 wchar_t *pwcs,
319 size_t sizeInWords,
320 const char *s,
321 size_t n
322 )
323{
324 __crt_cached_ptd_host ptd;
325 return _mbstowcs_internal(pConvertedChars, pwcs, sizeInWords, s, n, ptd);
326}
#define EINVAL
Definition: acclib.h:90
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ERANGE
Definition: acclib.h:92
#define __cdecl
Definition: accygwin.h:79
static int state
Definition: maze.c:121
Definition: _locale.h:75
_Check_return_ __forceinline unsigned short __cdecl _isleadbyte_fast_internal(_In_ unsigned char const c, _In_ _locale_t const locale)
#define _UCRT_VALIDATE_RETURN(ptd, expr, errorcode, retexpr)
#define _UCRT_VALIDATE_RETURN_ERRCODE(ptd, expr, errorcode)
#define _RESET_STRING(_String, _Size)
_In_ size_t const _In_ int _In_ bool const _In_ unsigned const _In_ __acrt_rounding_mode const _Inout_ __crt_cached_ptd_host & ptd
Definition: cvt.cpp:355
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
size_t bufferSize
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLdouble n
Definition: glext.h:7729
GLfloat GLfloat p
Definition: glext.h:8902
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
#define LC_CTYPE
Definition: locale.h:19
_mbstowcs_s_l
Definition: stdlib.h:951
_mbstowcs_l
Definition: stdlib.h:951
mbstowcs
Definition: stdlib.h:925
#define INT_MAX
Definition: intsafe.h:150
_locale_t plocinfo
Definition: ismbbyte.cpp:75
static errno_t __cdecl _mbstowcs_internal(size_t *pConvertedChars, wchar_t *pwcs, size_t sizeInWords, const char *s, size_t n, __crt_cached_ptd_host &ptd)
Definition: mbstowcs.cpp:232
errno_t __cdecl mbstowcs_s(size_t *pConvertedChars, wchar_t *pwcs, size_t sizeInWords, const char *s, size_t n)
Definition: mbstowcs.cpp:316
static size_t __cdecl _mbstowcs_l_helper(_Out_writes_opt_z_(n) wchar_t *pwcs, _In_reads_or_z_(n) _Pre_z_ const char *s, _In_ size_t n, _In_opt_ __crt_cached_ptd_host &ptd)
Definition: mbstowcs.cpp:46
size_t __cdecl __mbsrtowcs_utf8(wchar_t *dst, const char **src, size_t len, mbstate_t *ps, __crt_cached_ptd_host &ptd)
#define _In_reads_or_z_(s)
Definition: no_sal2.h:174
#define _Out_writes_opt_z_(s)
Definition: no_sal2.h:230
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Pre_z_
Definition: no_sal2.h:506
#define STRUNCATE
Definition: errno.h:110
#define EILSEQ
Definition: errno.h:109
#define CP_UTF8
Definition: nls.h:20
#define wchar_t
Definition: wchar.h:102
#define _TRUNCATE
Definition: corecrt.h:278
int errno_t
Definition: corecrt.h:615
_In_z_ const wchar_t * pwcs
Definition: wcstombs.cpp:85
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define MB_PRECOMPOSED
Definition: winnls.h:283