]>
Commit | Line | Data |
---|---|---|
a7a8363d | 1 | /** @file\r |
450ea6d5 | 2 | Copyright (c) 2016, Daryl McDaniel. All rights reserved.<BR>\r |
a7a8363d | 3 | Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>\r |
4 | This program and the accompanying materials\r | |
5 | are licensed and made available under the terms and conditions of the BSD License\r | |
6 | which accompanies this distribution. The full text of the license may be found at\r | |
7 | http://opensource.org/licenses/bsd-license.php\r | |
8 | \r | |
9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r | |
10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r | |
11 | **/\r | |
12 | #include <assert.h>\r | |
13 | #include <string.h>\r | |
14 | #include <errno.h>\r | |
15 | #include <stdlib.h>\r | |
16 | #include <wchar.h>\r | |
17 | #include <sys/types.h>\r | |
05c7d5f6 | 18 | #include <limits.h>\r |
a7a8363d | 19 | \r |
450ea6d5 | 20 | typedef int ch_UCS4;\r |
a7a8363d | 21 | \r |
c42c9cac | 22 | static mbstate_t LocalConvState = {0};\r |
a7a8363d | 23 | \r |
24 | /** Map a UTF-8 encoded prefix byte to a sequence length.\r | |
25 | Zero means illegal prefix, but valid surrogate if < 0xC0.\r | |
26 | One indicates an ASCII-7 equivalent character.\r | |
27 | Two, three, and four are the first byte for 2, 3, and 4 byte sequences, respectively.\r | |
28 | See RFC 3629 for details.\r | |
29 | \r | |
30 | TABLE ENCODING:\r | |
31 | Low Nibble decodes the first byte into the number of bytes in the sequence.\r | |
32 | A value of zero indicates an invalid byte.\r | |
33 | The High Nibble encodes a bit mask to be used to match against the high nibble of the second byte.\r | |
34 | \r | |
35 | example:\r | |
36 | SequenceLength = code[c0] & 0x0F;\r | |
37 | Mask = 0x80 | code[c0];\r | |
38 | \r | |
39 | Surrogate bytes are valid if: code[cX] & Mask > 0x80;\r | |
40 | \r | |
41 | */\r | |
42 | static\r | |
43 | UINT8 utf8_code_length[256] = {\r | |
44 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* 00-0F */\r | |
45 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\r | |
46 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\r | |
47 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\r | |
48 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\r | |
49 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\r | |
50 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\r | |
51 | 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* 70-7F */\r | |
52 | 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, /* 80-8F */\r | |
53 | 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, /* 90-9F */\r | |
54 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, /* A0-AF */\r | |
55 | 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, /* B0-BF */\r | |
56 | 0x00, 0x00, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, /* C0-C1 + C2-CF */\r | |
57 | 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, /* D0-DF */\r | |
58 | 0x43, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x33, 0x73, 0x73, /* E0-EF */\r | |
59 | 0x64, 0x74, 0x74, 0x74, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* F0-F4 + F5-FF */\r | |
60 | };\r | |
61 | \r | |
62 | /** Process one byte of a multibyte character.\r | |
63 | \r | |
c42c9cac | 64 | @param[in] ch One byte of a multibyte character.\r |
65 | @param[in,out] ps Pointer to a conversion state object.\r | |
a7a8363d | 66 | \r |
c42c9cac | 67 | @retval -2 ch is an incomplete but potentially valid character.\r |
68 | @retval -1 ch is not valid in this context.\r | |
69 | @retval 1:4 The length, in bytes, of the character ch just completed.\r | |
a7a8363d | 70 | **/\r |
71 | static\r | |
72 | int\r | |
73 | ProcessOneByte(unsigned char ch, mbstate_t *ps)\r | |
74 | {\r | |
75 | UINT32 Mask;\r | |
76 | UINT32 Length;\r | |
77 | int RetVal = 0;\r | |
78 | \r | |
79 | if(ps->A > 3) {\r | |
80 | // We are in an invalid state\r | |
81 | ps->A = 0; // Initial State\r | |
82 | }\r | |
450ea6d5 | 83 | ps->C[ps->A] = ch; // Save the current byte\r |
a7a8363d | 84 | Mask = utf8_code_length[ch];\r |
85 | \r | |
86 | if(ps->A == 0) { // Initial State. First byte of sequence.\r | |
87 | ps->E = Mask | 0x80;\r | |
88 | Length = Mask & 0xF;\r | |
89 | switch(Length) {\r | |
90 | case 0: // State 0, Code 0\r | |
91 | errno = EILSEQ;\r | |
92 | RetVal = -1;\r | |
450ea6d5 | 93 | ps->E = 1; // Consume this byte\r |
a7a8363d | 94 | break;\r |
95 | case 1: // State 0, Code 1\r | |
96 | // ASCII-7 Character\r | |
97 | ps->B = ps->D[0] = ch;\r | |
98 | RetVal = 1;\r | |
99 | break;\r | |
100 | default: // State 0, Code 2, 3, 4\r | |
101 | ps->A = 1; // Next state is State-1\r | |
102 | RetVal = -2; // Incomplete but potentially valid character\r | |
103 | break;\r | |
104 | }\r | |
105 | }\r | |
106 | else {\r | |
107 | // We are in state 1, 2, or 3 and processing a surrogate byte\r | |
108 | Length = ps->E & 0xF;\r | |
109 | if((Mask & ps->E) > 0x80) {\r | |
110 | // This byte is valid\r | |
111 | switch(ps->A) { // Process based upon our current state\r | |
112 | case 1: // Second byte of the sequence.\r | |
113 | if(Length == 2) { // State 1, Code 2\r | |
114 | Length = ((ps->C[0] & 0x1f) << 6) + (ps->C[1] & 0x3f);\r | |
115 | assert ((Length > 0x007F) && (Length <= 0x07FF));\r | |
116 | ps->B = ps->D[0] = (UINT16)Length;\r | |
117 | ps->A = 0; // Next state is State-0\r | |
118 | RetVal = 2;\r | |
119 | }\r | |
450ea6d5 | 120 | else { // This isn't the last byte, get more. State 1, Code 3 or 4\r |
a7a8363d | 121 | ps->A = 2;\r |
122 | RetVal = -2;\r | |
123 | }\r | |
124 | break;\r | |
125 | case 2: // Third byte of the sequence\r | |
126 | if(Length == 3) {\r | |
127 | Length = ((ps->C[0] & 0x0f) << 12) + ((ps->C[1] & 0x3f) << 6) + (ps->C[2] & 0x3f);\r | |
128 | assert ((Length > 0x07FF) && (Length <= 0xFFFF));\r | |
129 | ps->B = ps->D[0] = (UINT16)Length;\r | |
130 | ps->A = 0; // Next state is State-0\r | |
131 | RetVal = 3;\r | |
132 | }\r | |
133 | else {\r | |
134 | ps->A = 3;\r | |
135 | RetVal = -2;\r | |
136 | }\r | |
137 | break;\r | |
138 | case 3: // Fourth byte of the sequence\r | |
139 | if(Length == 4) {\r | |
140 | Length = ((ps->C[0] & 0x7) << 18) + ((ps->C[1] & 0x3f) << 12) +\r | |
141 | ((ps->C[2] & 0x3f) << 6) + (ps->C[3] & 0x3f);\r | |
142 | ps->B = Length;\r | |
143 | assert ((Length > 0xFFFF) && (Length <= 0x10ffff));\r | |
144 | \r | |
145 | /* compute and append the two surrogates: */\r | |
146 | \r | |
147 | /* translate from 10000..10FFFF to 0..FFFF */\r | |
148 | Length -= 0x10000;\r | |
149 | \r | |
150 | /* high surrogate = top 10 bits added to D800 */\r | |
151 | ps->D[0] = (UINT16)(0xD800 + (Length >> 10));\r | |
152 | \r | |
153 | /* low surrogate = bottom 10 bits added to DC00 */\r | |
154 | ps->D[1] = (UINT16)(0xDC00 + (Length & 0x03FF));\r | |
155 | ps->A = 0; // Next state is State-0\r | |
156 | RetVal = 4;\r | |
157 | }\r | |
158 | else {\r | |
159 | errno = EILSEQ;\r | |
160 | ps->A = 0;\r | |
161 | RetVal = -1;\r | |
450ea6d5 | 162 | ps->E = 4; // Can't happen, but consume this byte anyway\r |
a7a8363d | 163 | }\r |
164 | break;\r | |
165 | }\r | |
166 | }\r | |
450ea6d5 | 167 | else { // Invalid surrogate byte\r |
a7a8363d | 168 | errno = EILSEQ;\r |
169 | ps->A = 0; // Next is State-0\r | |
170 | RetVal = -1;\r | |
171 | ps->E = 0; // Don't Consume, it may be an initial byte\r | |
172 | }\r | |
173 | }\r | |
174 | return RetVal;\r | |
175 | }\r | |
176 | \r | |
177 | /** Convert one Multibyte sequence.\r | |
178 | \r | |
c42c9cac | 179 | @param[out] Dest Pointer to output location, or NULL\r |
180 | @param[in] Src Multibyte Source (UTF8)\r | |
181 | @param[in] Len Max Number of bytes to convert\r | |
182 | @param[in] pS Pointer to State struct., or NULL\r | |
a7a8363d | 183 | \r |
184 | @retval -2 Bytes processed comprise an incomplete, but potentially valid, character.\r | |
185 | @retval -1 An encoding error was encountered. ps->E indicates the number of bytes consumed.\r | |
186 | @retval 0 Either Src is NULL or it points to a NUL character.\r | |
187 | @retval 1:N N bytes were consumed producing a valid wide character.\r | |
188 | **/\r | |
189 | int\r | |
190 | DecodeOneStateful(\r | |
191 | wchar_t *Dest, // Pointer to output location, or NULL\r | |
192 | const char *Src, // Multibyte Source (UTF8)\r | |
193 | ssize_t Len, // Max Number of bytes to convert\r | |
194 | mbstate_t *pS // Pointer to State struct., or NULL\r | |
195 | )\r | |
196 | {\r | |
197 | const char *SrcEnd;\r | |
198 | int NumConv;\r | |
199 | unsigned char ch;\r | |
200 | \r | |
a7a8363d | 201 | if(pS == NULL) {\r |
202 | pS = &LocalConvState;\r | |
203 | }\r | |
a7a8363d | 204 | NumConv = 0;\r |
5a522112 | 205 | if(Src != NULL) {\r |
206 | if(*Src != 0) {\r | |
207 | SrcEnd = Src + Len;\r | |
208 | while(Src < SrcEnd) {\r | |
209 | ch = (unsigned char)*Src++;\r | |
210 | NumConv = ProcessOneByte(ch, pS);\r | |
211 | if(NumConv != -2) {\r | |
212 | break;\r | |
213 | }\r | |
214 | }\r | |
215 | }\r | |
216 | else if(Dest != NULL) {\r | |
217 | *Dest = 0;\r | |
218 | }\r | |
a7a8363d | 219 | }\r |
220 | if((NumConv > 0) && (Dest != NULL)) {\r | |
221 | Dest[0] = pS->D[0];\r | |
222 | if(NumConv == 4) {\r | |
223 | Dest[1] = pS->D[1];\r | |
224 | }\r | |
225 | }\r | |
226 | return NumConv;\r | |
227 | }\r | |
228 | \r | |
c42c9cac | 229 | /* Determine the number of bytes needed to represent a Wide character\r |
230 | as a MBCS character.\r | |
231 | \r | |
232 | A single wide character may convert into a one, two, three, or four byte\r | |
233 | narrow (MBCS or UTF-8) character. The number of MBCS bytes can be determined\r | |
234 | as follows.\r | |
235 | \r | |
236 | If WCS char < 0x00000080 One Byte\r | |
237 | Else if WCS char < 0x0000D800 Two Bytes\r | |
238 | Else Three Bytes\r | |
239 | \r | |
240 | Since UEFI only supports the Unicode Base Multilingual Plane (BMP),\r | |
241 | Four-byte characters are not supported.\r | |
242 | \r | |
243 | @param[in] InCh Wide character to test.\r | |
244 | \r | |
245 | @retval -1 Improperly formed character\r | |
246 | @retval 0 InCh is 0x0000\r | |
247 | @retval >0 Number of bytes needed for the MBCS character\r | |
248 | */\r | |
249 | int\r | |
250 | EFIAPI\r | |
251 | OneWcToMcLen(const wchar_t InCh)\r | |
252 | {\r | |
253 | ssize_t NumBytes;\r | |
254 | \r | |
255 | if(InCh == 0) { // Is this a NUL, 0x0000 ?\r | |
256 | NumBytes = 0;\r | |
257 | }\r | |
258 | else if(InCh < 0x0080) { // Is this a 1-byte character?\r | |
259 | NumBytes = 1;\r | |
260 | }\r | |
261 | else if(InCh < 0x0800) { // Is this a 2-byte character?\r | |
262 | NumBytes = 2;\r | |
263 | }\r | |
264 | else if((InCh >= 0xD800) && (InCh < 0xE000)) { // Is this a surrogate?\r | |
265 | NumBytes = -1;\r | |
266 | }\r | |
267 | else {\r | |
268 | NumBytes = 3; // Otherwise, it must be a 3-byte character.\r | |
269 | }\r | |
270 | return (int)NumBytes; // Return extimate of required bytes.\r | |
271 | }\r | |
272 | \r | |
273 | /* Determine the number of bytes needed to represent a Wide character string\r | |
274 | as a MBCS string of given maximum length. Will optionally return the number\r | |
275 | of wide characters that would be consumed.\r | |
276 | \r | |
277 | A single wide character may convert into a one, two, three, or four byte\r | |
278 | narrow (MBCS or UTF-8) character. The number of MBCS bytes can be determined\r | |
279 | as follows.\r | |
280 | \r | |
281 | If WCS char < 0x00000080 One Byte\r | |
282 | Else if WCS char < 0x00000800 Two Bytes\r | |
283 | Else if WCS char < 0x00010000 Three Bytes\r | |
284 | Else Four Bytes\r | |
285 | \r | |
286 | Since UEFI only supports the Unicode Base Multilingual Plane (BMP),\r | |
287 | Four-byte characters should not be encountered.\r | |
288 | \r | |
289 | @param[in] Src Pointer to a wide character string.\r | |
290 | @param[in] Limit Maximum number of bytes the converted string may occupy.\r | |
450ea6d5 DM |
291 | @param[out] NumChar Pointer to where to store the number of wide characters\r |
292 | consumed, or NULL.\r | |
c42c9cac | 293 | \r |
294 | @return The number of bytes required to convert Src to MBCS,\r | |
295 | not including the terminating NUL. If NumChar is not NULL, the number\r | |
296 | of characters represented by the return value will be written to\r | |
297 | where it points.\r | |
298 | */\r | |
299 | size_t\r | |
300 | EFIAPI\r | |
301 | EstimateWtoM(const wchar_t * Src, size_t Limit, size_t *NumChar)\r | |
302 | {\r | |
303 | ssize_t Estimate;\r | |
304 | size_t CharCount;\r | |
305 | ssize_t NumBytes;\r | |
306 | wchar_t EChar;\r | |
307 | \r | |
308 | Estimate = 0;\r | |
309 | CharCount = 0;\r | |
310 | EChar = *Src++; // Get the initial character and point to next\r | |
311 | while(((NumBytes = OneWcToMcLen(EChar)) > 0) &&\r | |
312 | ((size_t)(Estimate + NumBytes) < Limit))\r | |
313 | { // Until one of the source characters is NUL\r | |
314 | ++CharCount; // Count this character.\r | |
315 | Estimate += NumBytes; // Count the Bytes for this character\r | |
316 | EChar = *Src++; // Get the next source character and point to the next.\r | |
317 | }\r | |
318 | if(NumChar != NULL) {\r | |
319 | *NumChar = CharCount;\r | |
320 | }\r | |
321 | return (size_t)Estimate; // Return esimate of required bytes.\r | |
322 | }\r | |
323 | \r | |
324 | /* Determine the number of characters in a MBCS string.\r | |
325 | MBCS characters are one to four bytes long. By examining the first byte\r | |
326 | of a MBCS character, one can determine the number of bytes comprising the\r | |
327 | character.\r | |
328 | \r | |
329 | 0x00 - 0x7F One\r | |
330 | 0xC0 - 0xDF Two\r | |
331 | 0xE0 - 0xEF Three\r | |
332 | 0xF0 - 0xF7 Four\r | |
333 | \r | |
334 | Since UEFI only supports the Unicode Base Multilingual Plane (BMP),\r | |
335 | Four-byte characters should not be encountered.\r | |
336 | \r | |
337 | @param[in] Src The string to examine\r | |
338 | \r | |
339 | @return The number of characters represented by the MBCS string.\r | |
340 | **/\r | |
341 | size_t\r | |
342 | EFIAPI\r | |
343 | CountMbcsChars(const char *Src)\r | |
344 | {\r | |
345 | size_t Count;\r | |
346 | char EChar;\r | |
347 | \r | |
348 | Count = 0;\r | |
349 | EChar = *Src++;\r | |
350 | while(EChar != 0) {\r | |
351 | if(EChar < 0x80) {\r | |
352 | ++Count;\r | |
353 | }\r | |
354 | else if(EChar < 0xE0) {\r | |
355 | Count += 2;\r | |
356 | ++Src;\r | |
357 | }\r | |
358 | else if(EChar < 0xF0) {\r | |
359 | Count += 3;\r | |
360 | Src += 2;\r | |
361 | }\r | |
362 | else {\r | |
363 | // Ill-formed character\r | |
364 | break;\r | |
365 | }\r | |
366 | }\r | |
367 | return Count;\r | |
368 | }\r | |
369 | \r | |
370 | /** Convert a wide character (UTF16) into a multibyte character (UTF8)\r | |
371 | \r | |
372 | Converts a wide character into a corresponding multibyte character that\r | |
373 | begins in the conversion state described by the object pointed to by ps.\r | |
374 | If dst is not a null pointer, the converted character is then stored into\r | |
375 | the array pointed to by dst.\r | |
376 | \r | |
377 | It is the caller's responsibility to ensure that Dest is large enough to\r | |
378 | hold the resulting MBCS sequence.\r | |
a7a8363d | 379 | \r |
380 | @param s Pointer to the wide-character string to convert\r | |
c42c9cac | 381 | @param Dest Pointer to the buffer in which to place the converted sequence, or NULL.\r |
a7a8363d | 382 | \r |
c42c9cac | 383 | @retval -1 An error occurred. The error reason is in errno.\r |
384 | @retval >=0 The number of bytes stored into Dest.\r | |
a7a8363d | 385 | **/\r |
386 | ssize_t\r | |
c42c9cac | 387 | EncodeUtf8(char *Dest, wchar_t ch)\r |
a7a8363d | 388 | {\r |
389 | char *p; /* next free byte in build buffer */\r | |
a7a8363d | 390 | int NumInBuff; // number of bytes in Buff\r |
391 | char Buff[4]; // Buffer into which each character is built\r | |
392 | \r | |
a7a8363d | 393 | p = Buff;\r |
394 | \r | |
c42c9cac | 395 | NumInBuff = 0;\r |
396 | if (ch < 0x80) {\r | |
397 | /* Encode ASCII -- One Byte */\r | |
398 | *p++ = (char) ch;\r | |
399 | NumInBuff = 1;\r | |
400 | }\r | |
401 | else if (ch < 0x0800) {\r | |
402 | /* Encode Latin-1 -- Two Byte */\r | |
403 | *p++ = (char)(0xc0 | (ch >> 6));\r | |
404 | *p++ = (char)(0x80 | (ch & 0x3f));\r | |
405 | NumInBuff = 2;\r | |
406 | }\r | |
407 | else {\r | |
a7a8363d | 408 | /* Encode UCS2 Unicode ordinals -- Three Byte */\r |
c42c9cac | 409 | /* Special case: check for surrogate -- Shouldn't happen in UEFI */\r |
410 | if (0xD800 <= ch && ch < 0xE000) {\r | |
411 | errno = EILSEQ;\r | |
412 | return -1;\r | |
a7a8363d | 413 | }\r |
c42c9cac | 414 | else {\r |
a7a8363d | 415 | *p++ = (char)(0xe0 | (ch >> 12));\r |
416 | *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));\r | |
417 | *p++ = (char)(0x80 | (ch & 0x3f));\r | |
c42c9cac | 418 | NumInBuff = 3;\r |
a7a8363d | 419 | }\r |
a7a8363d | 420 | }\r |
c42c9cac | 421 | /* At this point, Buff holds the converted character which is NumInBuff bytes long.\r |
422 | NumInBuff is the value 1, 2, 3, or 4\r | |
423 | */\r | |
424 | if(Dest != NULL) { // Save character if Dest is not NULL\r | |
425 | memcpy(Dest, Buff, NumInBuff);\r | |
a7a8363d | 426 | }\r |
c42c9cac | 427 | return NumInBuff; // Tell the caller\r |
a7a8363d | 428 | }\r |
429 | \r | |
430 | // ######################## Narrow to Wide Conversions #######################\r | |
431 | \r | |
432 | /** If ps is not a null pointer, the mbsinit function determines whether the\r | |
433 | pointed-to mbstate_t object describes an initial conversion state.\r | |
434 | \r | |
c42c9cac | 435 | @param[in] ps Pointer to the conversion state object to test.\r |
436 | \r | |
a7a8363d | 437 | @return The mbsinit function returns nonzero if ps is a null pointer\r |
438 | or if the pointed-to object describes an initial conversion\r | |
439 | state; otherwise, it returns zero.\r | |
440 | \r | |
441 | Declared in: wchar.h\r | |
442 | **/\r | |
443 | int\r | |
444 | mbsinit(const mbstate_t *ps)\r | |
445 | {\r | |
446 | if((ps == NULL) || (ps->A == 0)) {\r | |
447 | return 1;\r | |
448 | }\r | |
449 | return 0;\r | |
450 | }\r | |
451 | \r | |
452 | /** The mbrlen function is equivalent to the call:<BR>\r | |
453 | @verbatim\r | |
454 | mbrtowc(NULL, s, n, ps != NULL ? ps : &internal)\r | |
455 | @endverbatim\r | |
456 | where internal is the mbstate_t object for the mbrlen function, except that\r | |
457 | the expression designated by ps is evaluated only once.\r | |
458 | \r | |
c42c9cac | 459 | @param[in] s Pointer to a multibyte character sequence.\r |
460 | @param[in] n Maximum number of bytes to examine.\r | |
461 | @param[in] pS Pointer to the conversion state object.\r | |
462 | \r | |
463 | @retval 0 The next n or fewer characters complete a NUL.\r | |
464 | @retval 1..n The number of bytes that complete the multibyte character.\r | |
465 | @retval -2 The next n bytes contribute to an incomplete (but potentially valid) multibyte character.\r | |
466 | @retval -1 An encoding error occurred.\r | |
a7a8363d | 467 | \r |
468 | Declared in: wchar.h\r | |
469 | **/\r | |
470 | size_t\r | |
471 | mbrlen(\r | |
472 | const char *s,\r | |
473 | size_t n,\r | |
c42c9cac | 474 | mbstate_t *pS\r |
a7a8363d | 475 | )\r |
476 | {\r | |
c42c9cac | 477 | return mbrtowc(NULL, s, n, pS);\r |
a7a8363d | 478 | }\r |
479 | \r | |
480 | /** Determine the number of bytes comprising a multibyte character.\r | |
481 | \r | |
482 | If S is not a null pointer, the mblen function determines the number of bytes\r | |
483 | contained in the multibyte character pointed to by S. Except that the\r | |
484 | conversion state of the mbtowc function is not affected, it is equivalent to\r | |
485 | mbtowc((wchar_t *)0, S, N);\r | |
486 | \r | |
487 | @param[in] S NULL to query whether multibyte characters have\r | |
488 | state-dependent encodings. Otherwise, points to a\r | |
489 | multibyte character.\r | |
490 | @param[in] N The maximum number of bytes in a multibyte character.\r | |
491 | \r | |
492 | @return If S is a null pointer, the mblen function returns a nonzero or\r | |
493 | zero value, if multibyte character encodings, respectively, do\r | |
494 | or do not have state-dependent encodings. If S is not a null\r | |
495 | pointer, the mblen function either returns 0 (if S points to the\r | |
496 | null character), or returns the number of bytes that are contained\r | |
497 | in the multibyte character (if the next N or fewer bytes form a\r | |
498 | valid multibyte character), or returns -1 (if they do not form a\r | |
499 | valid multibyte character).\r | |
500 | \r | |
501 | Declared in: stdlib.h\r | |
502 | **/\r | |
503 | int\r | |
504 | mblen(\r | |
505 | const char *s,\r | |
506 | size_t n\r | |
507 | )\r | |
508 | {\r | |
509 | return (int)mbrlen(s, n, NULL);\r | |
510 | }\r | |
511 | \r | |
512 | /**\r | |
513 | If S is a null pointer, the mbrtowc function is equivalent to the call:<BR>\r | |
514 | @verbatim\r | |
515 | mbrtowc(NULL, "", 1, ps)\r | |
516 | @endverbatim\r | |
517 | \r | |
518 | In this case, the values of the parameters pwc and n are ignored.\r | |
519 | \r | |
520 | If S is not a null pointer, the mbrtowc function inspects at most n bytes beginning with\r | |
521 | the byte pointed to by S to determine the number of bytes needed to complete the next\r | |
522 | multibyte character (including any shift sequences). If the function determines that the\r | |
523 | next multibyte character is complete and valid, it determines the value of the\r | |
524 | corresponding wide character and then, if pwc is not a null pointer, stores that value in\r | |
525 | the object pointed to by pwc. If the corresponding wide character is the null wide\r | |
526 | character, the resulting state described is the initial conversion state.\r | |
527 | \r | |
c42c9cac | 528 | @param[out] pwc Pointer to where the resulting wide character is to be stored.\r |
529 | @param[in] s Pointer to a multibyte character "string".\r | |
530 | @param[in] n The maximum number of bytes to inspect.\r | |
531 | @param[in] ps Pointer to a conversion state object.\r | |
532 | \r | |
a7a8363d | 533 | @retval 0 if the next n or fewer bytes complete the multibyte\r |
534 | character that corresponds to the null wide\r | |
535 | character (which is the value stored).\r | |
536 | @retval between_1_and_n_inclusive if the next n or fewer bytes complete\r | |
537 | a valid multibyte character (which is the value\r | |
538 | stored); the value returned is the number of bytes\r | |
539 | that complete the multibyte character.\r | |
540 | @retval (size_t)(-2) if the next n bytes contribute to an incomplete\r | |
541 | (but potentially valid) multibyte character, and\r | |
542 | all n bytes have been processed (no value is stored).\r | |
543 | @retval (size_t)(-1) if an encoding error occurs, in which case the next\r | |
544 | n or fewer bytes do not contribute to a complete and\r | |
545 | valid multibyte character (no value is stored); the\r | |
546 | value of the macro EILSEQ is stored in errno, and\r | |
547 | the conversion state is unspecified.\r | |
548 | \r | |
549 | Declared in: wchar.h\r | |
550 | **/\r | |
551 | size_t\r | |
552 | mbrtowc(\r | |
553 | wchar_t *pwc,\r | |
554 | const char *s,\r | |
555 | size_t n,\r | |
556 | mbstate_t *ps\r | |
557 | )\r | |
558 | {\r | |
559 | int RetVal;\r | |
560 | \r | |
561 | RetVal = DecodeOneStateful(pwc, s, (ssize_t)n, ps);\r | |
562 | return (size_t)RetVal;\r | |
563 | }\r | |
564 | \r | |
565 | /** Convert a multibyte character into a wide character.\r | |
566 | \r | |
567 | If S is not a null pointer, the mbtowc function inspects at most N bytes\r | |
568 | beginning with the byte pointed to by S to determine the number of bytes\r | |
569 | needed to complete the next multibyte character (including any shift\r | |
570 | sequences). If the function determines that the next multibyte character\r | |
571 | is complete and valid, it determines the value of the corresponding wide\r | |
572 | character and then, if Pwc is not a null pointer, stores that value in\r | |
573 | the object pointed to by Pwc. If the corresponding wide character is the\r | |
574 | null wide character, the function is left in the initial conversion state.\r | |
575 | \r | |
576 | @param[out] Pwc Pointer to a wide-character object to receive the converted character.\r | |
577 | @param[in] S Pointer to a multibyte character to convert.\r | |
578 | @param[in] N Maximum number of bytes in a multibyte character.\r | |
579 | \r | |
580 | @return If S is a null pointer, the mbtowc function returns a nonzero or\r | |
581 | zero value, if multibyte character encodings, respectively, do\r | |
582 | or do not have state-dependent encodings. If S is not a null\r | |
583 | pointer, the mbtowc function either returns 0 (if S points to\r | |
584 | the null character), or returns the number of bytes that are\r | |
585 | contained in the converted multibyte character (if the next N or\r | |
586 | fewer bytes form a valid multibyte character), or returns -1\r | |
587 | (if they do not form a valid multibyte character).\r | |
588 | \r | |
589 | In no case will the value returned be greater than N or the value\r | |
590 | of the MB_CUR_MAX macro.\r | |
591 | \r | |
592 | Declared in: stdlib.h\r | |
593 | **/\r | |
594 | int\r | |
595 | mbtowc(\r | |
596 | wchar_t *pwc,\r | |
597 | const char *s,\r | |
598 | size_t n\r | |
599 | )\r | |
600 | {\r | |
601 | return (int)mbrtowc(pwc, s, n, NULL);\r | |
602 | }\r | |
603 | \r | |
604 | /**\r | |
605 | The mbsrtowcs function converts a sequence of multibyte characters that begins in the\r | |
606 | conversion state described by the object pointed to by ps, from the array indirectly\r | |
607 | pointed to by src into a sequence of corresponding wide characters. If dst is not a null\r | |
608 | pointer, the converted characters are stored into the array pointed to by dst. Conversion\r | |
609 | continues up to and including a terminating null character, which is also stored.\r | |
610 | Conversion stops earlier in two cases: when a sequence of bytes is encountered that does\r | |
611 | not form a valid multibyte character, or (if dst is not a null pointer) when len wide\r | |
612 | characters have been stored into the array pointed to by dst. Each conversion takes\r | |
613 | place as if by a call to the mbrtowc function.\r | |
614 | \r | |
615 | If dst is not a null pointer, the pointer object pointed to by src is assigned either a null\r | |
616 | pointer (if conversion stopped due to reaching a terminating null character) or the address\r | |
617 | just past the last multibyte character converted (if any). If conversion stopped due to\r | |
618 | reaching a terminating null character and if dst is not a null pointer, the resulting state\r | |
619 | described is the initial conversion state.\r | |
620 | \r | |
c42c9cac | 621 | @param[out] dst Pointer to where the resulting wide character sequence is stored.\r |
622 | @param[in] src Pointer to a pointer to the multibyte character sequence to convert.\r | |
623 | @param[in] len Maximum number of wide characters to be stored into dst.\r | |
624 | @param[in] ps Pointer to a conversion state object.\r | |
625 | \r | |
a7a8363d | 626 | @return If the input conversion encounters a sequence of bytes that do\r |
627 | not form a valid multibyte character, an encoding error occurs:\r | |
628 | the mbsrtowcs function stores the value of the macro EILSEQ in\r | |
629 | errno and returns (size_t)(-1); the conversion state is\r | |
630 | unspecified. Otherwise, it returns the number of multibyte\r | |
631 | characters successfully converted, not including the terminating\r | |
632 | null character (if any).\r | |
633 | \r | |
634 | Declared in: wchar.h\r | |
635 | **/\r | |
636 | size_t\r | |
637 | mbsrtowcs(\r | |
638 | wchar_t *dst,\r | |
639 | const char **src,\r | |
640 | size_t len,\r | |
641 | mbstate_t *ps\r | |
642 | )\r | |
643 | {\r | |
644 | int x;\r | |
645 | size_t RetVal = 0;\r | |
646 | const char *MySrc;\r | |
647 | \r | |
5a522112 | 648 | if((src == NULL) || (*src == NULL)) {\r |
a7a8363d | 649 | return 0;\r |
650 | }\r | |
651 | \r | |
652 | MySrc = *src;\r | |
653 | for(x = 1 ; (len != 0) && (x > 0); --len) {\r | |
654 | x = DecodeOneStateful(dst, MySrc, MB_LEN_MAX, ps);\r | |
655 | switch(x) {\r | |
656 | case -2: // Incomplete character\r | |
657 | case -1: // Encoding error\r | |
658 | RetVal = (size_t)x;\r | |
659 | break;\r | |
660 | case 0: // Encountered NUL character: done.\r | |
661 | if(dst != NULL) {\r | |
662 | *dst = 0;\r | |
663 | *src = NULL;\r | |
664 | }\r | |
665 | break;\r | |
666 | default: // Successfully decoded a character, continue with next\r | |
667 | MySrc += x;\r | |
668 | if(dst != NULL) {\r | |
669 | ++dst;\r | |
670 | if(x == 4) {\r | |
671 | ++dst;\r | |
672 | }\r | |
673 | *src = MySrc;\r | |
674 | }\r | |
675 | ++RetVal;\r | |
676 | break;\r | |
677 | }\r | |
678 | }\r | |
679 | return RetVal;\r | |
680 | }\r | |
681 | \r | |
682 | /** Convert a multibyte character string into a wide-character string.\r | |
683 | \r | |
684 | The mbstowcs function converts a sequence of multibyte characters that\r | |
685 | begins in the initial shift state from the array pointed to by Src into\r | |
686 | a sequence of corresponding wide characters and stores not more than limit\r | |
687 | wide characters into the array pointed to by Dest. No multibyte\r | |
688 | characters that follow a null character (which is converted into a null\r | |
689 | wide character) will be examined or converted. Each multibyte character\r | |
690 | is converted as if by a call to the mbtowc function, except that the\r | |
691 | conversion state of the mbtowc function is not affected.\r | |
692 | \r | |
693 | No more than Limit elements will be modified in the array pointed to by Dest.\r | |
694 | If copying takes place between objects that overlap,\r | |
695 | the behavior is undefined.\r | |
696 | \r | |
697 | @param[out] Dest Pointer to the array to receive the converted string.\r | |
698 | @param[in] Src Pointer to the string to be converted.\r | |
699 | @param[in] Limit Maximum number of elements to be written to Dest.\r | |
700 | \r | |
701 | @return If an invalid multibyte character is encountered, the mbstowcs\r | |
702 | function returns (size_t)(-1). Otherwise, the mbstowcs function\r | |
703 | returns the number of array elements modified, not including a\r | |
704 | terminating null wide character, if any.\r | |
705 | \r | |
706 | Declared in: stdlib.h\r | |
707 | **/\r | |
708 | size_t\r | |
709 | mbstowcs(\r | |
c42c9cac | 710 | wchar_t *Dest,\r |
711 | const char *Src,\r | |
712 | size_t Limit\r | |
a7a8363d | 713 | )\r |
714 | {\r | |
715 | \r | |
c42c9cac | 716 | /* Dest may be NULL */\r |
717 | /* Src may be NULL */\r | |
a7a8363d | 718 | \r |
c42c9cac | 719 | return mbsrtowcs(Dest, &Src, Limit, NULL);\r |
a7a8363d | 720 | }\r |
721 | \r | |
722 | /** The btowc function determines whether C constitutes a valid single-byte\r | |
723 | character in the initial shift state.\r | |
724 | \r | |
c42c9cac | 725 | @param[in] C A narrow character to test or convert to wide.\r |
726 | \r | |
a7a8363d | 727 | @return The btowc function returns WEOF if c has the value EOF or if\r |
728 | (unsigned char)C does not constitute a valid single-byte\r | |
729 | character in the initial shift state. Otherwise, it returns the\r | |
730 | wide character representation of that character.\r | |
731 | \r | |
732 | Declared in: wchar.h\r | |
733 | **/\r | |
734 | wint_t\r | |
735 | btowc(int c)\r | |
736 | {\r | |
737 | int x;\r | |
738 | wchar_t Dest;\r | |
739 | wint_t RetVal = WEOF;\r | |
740 | \r | |
741 | if (c == EOF)\r | |
742 | return WEOF;\r | |
743 | x = DecodeOneStateful(&Dest, (const char *)&c, 1, NULL);\r | |
744 | if(x == 0) {\r | |
745 | RetVal = 0;\r | |
746 | }\r | |
747 | else if(x == 1) {\r | |
748 | RetVal = (wint_t)Dest;\r | |
749 | }\r | |
750 | return RetVal;\r | |
751 | }\r | |
752 | \r | |
753 | // ######################## Wide to Narrow Conversions #######################\r | |
754 | \r | |
755 | /**\r | |
756 | If S is a null pointer, the wcrtomb function is equivalent to the call:<BR>\r | |
757 | @verbatim\r | |
758 | wcrtomb(buf, L'\0', ps)\r | |
759 | @endverbatim\r | |
760 | where buf is an internal buffer.\r | |
761 | \r | |
762 | If S is not a null pointer, the wcrtomb function determines the number of bytes needed\r | |
763 | to represent the multibyte character that corresponds to the wide character given by wc\r | |
764 | (including any shift sequences), and stores the multibyte character representation in the\r | |
765 | array whose first element is pointed to by S. At most MB_CUR_MAX bytes are stored. If\r | |
766 | wc is a null wide character, a null byte is stored, preceded by any shift sequence needed\r | |
767 | to restore the initial shift state; the resulting state described is the initial conversion state.\r | |
768 | \r | |
c42c9cac | 769 | @param[out] Dest Pointer to the location in which to store the resulting\r |
770 | multibyte character. Otherwise, NULL to reset the\r | |
771 | conversion state.\r | |
772 | @param[in] wchar The wide character to convert.\r | |
773 | @param[in,out] pS Pointer to a conversion state object, or NULL.\r | |
774 | \r | |
a7a8363d | 775 | @return The wcrtomb function returns the number of bytes stored in the\r |
776 | array object (including any shift sequences). When wc is not a\r | |
777 | valid wide character, an encoding error occurs: the function\r | |
778 | stores the value of the macro EILSEQ in errno and\r | |
779 | returns (size_t)(-1); the conversion state is unspecified.\r | |
780 | \r | |
781 | Declared in: wchar.h\r | |
782 | **/\r | |
783 | size_t\r | |
784 | wcrtomb(\r | |
c42c9cac | 785 | char *Dest,\r |
a7a8363d | 786 | wchar_t wchar,\r |
c42c9cac | 787 | mbstate_t *pS\r |
a7a8363d | 788 | )\r |
789 | {\r | |
790 | size_t RetVal;\r | |
791 | \r | |
c42c9cac | 792 | /* Dest may be NULL */\r |
793 | if (Dest == NULL) {\r | |
a7a8363d | 794 | RetVal = 1;\r |
795 | }\r | |
796 | else {\r | |
797 | if (wchar == L'\0') {\r | |
c42c9cac | 798 | *Dest = '\0';\r |
a7a8363d | 799 | RetVal = 1;\r |
800 | }\r | |
801 | else {\r | |
c42c9cac | 802 | RetVal = EncodeUtf8(Dest, wchar);\r |
a7a8363d | 803 | }\r |
804 | }\r | |
c42c9cac | 805 | if(pS == NULL) {\r |
806 | pS = &LocalConvState;\r | |
807 | }\r | |
808 | pS->A = 0; // Set ps to the initial conversion state\r | |
809 | \r | |
a7a8363d | 810 | return RetVal;\r |
811 | }\r | |
812 | \r | |
813 | /** Convert a wide character into a multibyte character.\r | |
814 | \r | |
815 | The wctomb function determines the number of bytes needed to represent the\r | |
816 | multibyte character corresponding to the wide character given by WC\r | |
817 | (including any shift sequences), and stores the multibyte character\r | |
818 | representation in the array whose first element is pointed to by S (if S is\r | |
819 | not a null pointer). At most MB_CUR_MAX characters are stored. If WC is a\r | |
820 | null wide character, a null byte is stored, preceded by any shift sequence\r | |
821 | needed to restore the initial shift state, and the function is left in the\r | |
822 | initial conversion state.\r | |
823 | \r | |
824 | @param[out] S Pointer to the object to receive the converted multibyte character.\r | |
825 | @param[in] WC Wide character to be converted.\r | |
826 | \r | |
827 | @return If S is a null pointer, the wctomb function returns a nonzero or\r | |
828 | zero value, if multibyte character encodings, respectively, do or\r | |
829 | do not have state-dependent encodings. If S is not a null pointer,\r | |
830 | the wctomb function returns -1 if the value of WC does not\r | |
831 | correspond to a valid multibyte character, or returns the number\r | |
832 | of bytes that are contained in the multibyte character\r | |
833 | corresponding to the value of WC.\r | |
834 | \r | |
835 | In no case will the value returned be greater than the value of\r | |
836 | the MB_CUR_MAX macro.\r | |
837 | \r | |
838 | Declared in: stdlib.h\r | |
839 | **/\r | |
840 | int\r | |
841 | wctomb(\r | |
842 | char *s,\r | |
843 | wchar_t wchar\r | |
844 | )\r | |
845 | {\r | |
846 | /*\r | |
847 | If s is NULL just return whether MB Characters have state\r | |
848 | dependent encodings -- they don't.\r | |
849 | */\r | |
850 | if (s == NULL)\r | |
851 | return 0;\r | |
852 | \r | |
853 | return (int)wcrtomb(s, wchar, NULL);\r | |
854 | }\r | |
855 | \r | |
856 | /** The wcsrtombs function converts a sequence of wide characters from the array\r | |
5a522112 | 857 | indirectly pointed to by Src into a sequence of corresponding multibyte\r |
a7a8363d | 858 | characters that begins in the conversion state described by the object\r |
859 | pointed to by ps.\r | |
860 | \r | |
c42c9cac | 861 | If Dest is not a null pointer, the converted characters are stored into the\r |
862 | array pointed to by Dest. Conversion continues up to and including a\r | |
863 | terminating null wide character, which is also stored. Conversion stops\r | |
864 | earlier in two cases: when a wide character is reached that does not\r | |
865 | correspond to a valid multibyte character, or (if Dest is not a null\r | |
866 | pointer) when the next multibyte character would exceed the limit of Limit\r | |
867 | total bytes to be stored into the array pointed to by Dest. Each conversion\r | |
868 | takes place as if by a call to the wcrtomb function.)\r | |
869 | \r | |
870 | If Dest is not a null pointer, the pointer object pointed to by Src is\r | |
a7a8363d | 871 | assigned either a null pointer (if conversion stopped due to reaching\r |
872 | a terminating null wide character) or the address just past the last wide\r | |
873 | character converted (if any). If conversion stopped due to reaching a\r | |
874 | terminating null wide character, the resulting state described is the\r | |
875 | initial conversion state.\r | |
876 | \r | |
c42c9cac | 877 | @param[in] Dest\r |
878 | @param[in,out] Src\r | |
879 | @param[in] Limit Max number of bytes to store in Dest.\r | |
880 | @param[in,out] ps\r | |
881 | \r | |
a7a8363d | 882 | @return If conversion stops because a wide character is reached that\r |
883 | does not correspond to a valid multibyte character, an\r | |
884 | encoding error occurs: the wcsrtombs function stores the\r | |
885 | value of the macro EILSEQ in errno and returns (size_t)(-1);\r | |
886 | the conversion state is unspecified. Otherwise, it returns\r | |
887 | the number of bytes in the resulting multibyte character\r | |
888 | sequence, not including the terminating null character (if any).\r | |
889 | \r | |
890 | Declared in: wchar.h\r | |
891 | **/\r | |
892 | size_t\r | |
893 | wcsrtombs(\r | |
c42c9cac | 894 | char *Dest,\r |
895 | const wchar_t **Src,\r | |
896 | size_t Limit,\r | |
897 | mbstate_t *ps\r | |
a7a8363d | 898 | )\r |
899 | {\r | |
c42c9cac | 900 | size_t NumStored;\r |
901 | ssize_t MaxBytes;\r | |
902 | int count;\r | |
903 | wchar_t InCh;\r | |
a7a8363d | 904 | \r |
c42c9cac | 905 | NumStored = 0;\r |
906 | MaxBytes = (ssize_t)Limit;\r | |
907 | \r | |
908 | /* Dest may be NULL */\r | |
909 | /* Src may be NULL */\r | |
a7a8363d | 910 | /* ps appears to be unused */\r |
911 | \r | |
c42c9cac | 912 | if (Src == NULL || *Src == NULL)\r |
a7a8363d | 913 | return (0);\r |
914 | \r | |
c42c9cac | 915 | if (Dest == NULL) {\r |
5a522112 | 916 | NumStored = EstimateWtoM(*Src, ASCII_STRING_MAX, NULL);\r |
a7a8363d | 917 | }\r |
c42c9cac | 918 | else {\r |
5a522112 | 919 | if((MaxBytes < 0) || (MaxBytes > ASCII_STRING_MAX)) {\r |
920 | MaxBytes = ASCII_STRING_MAX;\r | |
921 | }\r | |
922 | while ((MaxBytes > 0) && (OneWcToMcLen(InCh = *(*Src)++) <= MaxBytes)) {\r | |
c42c9cac | 923 | if(InCh == 0) {\r |
924 | *Src = NULL;\r | |
5a522112 | 925 | *Dest = 0; // NUL terminate Dest string, but don't count the NUL\r |
a7a8363d | 926 | break;\r |
927 | }\r | |
c42c9cac | 928 | count = (int)wcrtomb(Dest, InCh, NULL);\r |
929 | if(count >= 0) {\r | |
930 | Dest += count;\r | |
931 | MaxBytes -= count;\r | |
932 | NumStored += count;\r | |
933 | }\r | |
934 | else {\r | |
935 | NumStored = (size_t)(-1);\r | |
936 | }\r | |
937 | }\r | |
a7a8363d | 938 | }\r |
939 | \r | |
c42c9cac | 940 | \r |
941 | return NumStored;\r | |
a7a8363d | 942 | }\r |
943 | \r | |
944 | /** Convert a wide-character string into a multibyte character string.\r | |
945 | \r | |
946 | The wcstombs function converts a sequence of wide characters from the\r | |
947 | array pointed to by Src into a sequence of corresponding multibyte\r | |
948 | characters that begins in the initial shift state, and stores these\r | |
949 | multibyte characters into the array pointed to by Dest, stopping if a\r | |
950 | multibyte character would exceed the limit of Limit total bytes or if a\r | |
951 | null character is stored. Each wide character is converted as if by\r | |
952 | a call to the wctomb function, except that the conversion state of\r | |
953 | the wctomb function is not affected.\r | |
954 | \r | |
955 | No more than Limit bytes will be modified in the array pointed to by Dest.\r | |
956 | If copying takes place between objects that overlap,\r | |
957 | the behavior is undefined.\r | |
958 | \r | |
959 | @param[out] Dest Pointer to the array to receive the converted string.\r | |
960 | @param[in] Src Pointer to the string to be converted.\r | |
961 | @param[in] Limit Maximum number of elements to be written to Dest.\r | |
962 | \r | |
963 | @return If a wide character is encountered that does not correspond to a\r | |
964 | valid multibyte character, the wcstombs function returns\r | |
965 | (size_t)(-1). Otherwise, the wcstombs function returns the number\r | |
450ea6d5 DM |
966 | of bytes in the resulting multibyte character sequence,\r |
967 | not including the terminating null character (if any).\r | |
a7a8363d | 968 | \r |
969 | Declared in: stdlib.h\r | |
970 | **/\r | |
971 | size_t\r | |
972 | wcstombs(\r | |
c42c9cac | 973 | char *Dest,\r |
974 | const wchar_t *Src,\r | |
975 | size_t Limit\r | |
a7a8363d | 976 | )\r |
977 | {\r | |
c42c9cac | 978 | /* Dest may be NULL */\r |
979 | return wcsrtombs(Dest, &Src, Limit, NULL);\r | |
a7a8363d | 980 | }\r |
981 | \r | |
982 | /** The wctob function determines whether C corresponds to a member of the extended\r | |
983 | character set whose multibyte character representation is a single byte when in the initial\r | |
984 | shift state.\r | |
985 | \r | |
c42c9cac | 986 | wctob needs to be consistent with wcrtomb.\r |
987 | If wcrtomb says that a character is representable in 1 byte,\r | |
988 | then wctob needs to also represent the character as 1 byte.\r | |
989 | \r | |
a7a8363d | 990 | @return The wctob function returns EOF if C does not correspond to a multibyte\r |
991 | character with length one in the initial shift state. Otherwise, it\r | |
992 | returns the single-byte representation of that character as an\r | |
993 | unsigned char converted to an int.\r | |
994 | \r | |
995 | Declared in: wchar.h\r | |
996 | **/\r | |
997 | int\r | |
998 | wctob(wint_t c)\r | |
999 | {\r | |
c42c9cac | 1000 | int RetVal;\r |
1001 | \r | |
1002 | RetVal = EOF;\r | |
1003 | if(c == 0) {\r | |
1004 | RetVal = 0;\r | |
1005 | }\r | |
1006 | else if (OneWcToMcLen((const wchar_t)c) == 1) {\r | |
1007 | RetVal = (int)(c & 0xFF);\r | |
a7a8363d | 1008 | }\r |
c42c9cac | 1009 | return RetVal;\r |
a7a8363d | 1010 | }\r |