2 * PROJECT: ReactOS Kernel - Vista+ APIs
3 * LICENSE: GPL v2 - See COPYING in the top level directory
4 * FILE: lib/drivers/ntoskrnl_vista/rtl.c
5 * PURPOSE: Rtl functions of Vista+
6 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org>
14 /******************************************************************************
15 * RtlUnicodeToUTF8N [NTDLL.@]
17 NTSTATUS NTAPI
RtlUnicodeToUTF8N(CHAR
*utf8_dest
, ULONG utf8_bytes_max
,
18 ULONG
*utf8_bytes_written
,
19 const WCHAR
*uni_src
, ULONG uni_bytes
)
29 return STATUS_INVALID_PARAMETER_4
;
30 if (!utf8_bytes_written
)
31 return STATUS_INVALID_PARAMETER
;
32 if (utf8_dest
&& uni_bytes
% sizeof(WCHAR
))
33 return STATUS_INVALID_PARAMETER_5
;
36 status
= STATUS_SUCCESS
;
38 for (i
= 0; i
< uni_bytes
/ sizeof(WCHAR
); i
++)
40 /* decode UTF-16 into ch */
42 if (ch
>= 0xdc00 && ch
<= 0xdfff)
45 status
= STATUS_SOME_NOT_MAPPED
;
47 else if (ch
>= 0xd800 && ch
<= 0xdbff)
49 if (i
+ 1 < uni_bytes
/ sizeof(WCHAR
))
53 if (uni_src
[i
+ 1] >= 0xdc00 && uni_src
[i
+ 1] <= 0xdfff)
55 ch
|= uni_src
[i
+ 1] - 0xdc00;
62 status
= STATUS_SOME_NOT_MAPPED
;
68 status
= STATUS_SOME_NOT_MAPPED
;
72 /* encode ch as UTF-8 */
73 ASSERT(ch
<= 0x10ffff);
76 utf8_ch
[0] = ch
& 0x7f;
81 utf8_ch
[0] = 0xc0 | (ch
>> 6 & 0x1f);
82 utf8_ch
[1] = 0x80 | (ch
>> 0 & 0x3f);
85 else if (ch
< 0x10000)
87 utf8_ch
[0] = 0xe0 | (ch
>> 12 & 0x0f);
88 utf8_ch
[1] = 0x80 | (ch
>> 6 & 0x3f);
89 utf8_ch
[2] = 0x80 | (ch
>> 0 & 0x3f);
92 else if (ch
< 0x200000)
94 utf8_ch
[0] = 0xf0 | (ch
>> 18 & 0x07);
95 utf8_ch
[1] = 0x80 | (ch
>> 12 & 0x3f);
96 utf8_ch
[2] = 0x80 | (ch
>> 6 & 0x3f);
97 utf8_ch
[3] = 0x80 | (ch
>> 0 & 0x3f);
103 written
+= utf8_ch_len
;
107 if (utf8_bytes_max
>= utf8_ch_len
)
109 memcpy(utf8_dest
, utf8_ch
, utf8_ch_len
);
110 utf8_dest
+= utf8_ch_len
;
111 utf8_bytes_max
-= utf8_ch_len
;
112 written
+= utf8_ch_len
;
117 status
= STATUS_BUFFER_TOO_SMALL
;
121 *utf8_bytes_written
= written
;
126 /******************************************************************************
127 * RtlUTF8ToUnicodeN [NTDLL.@]
129 NTSTATUS NTAPI
RtlUTF8ToUnicodeN(WCHAR
*uni_dest
, ULONG uni_bytes_max
,
130 ULONG
*uni_bytes_written
,
131 const CHAR
*utf8_src
, ULONG utf8_bytes
)
137 ULONG utf8_trail_bytes
;
142 return STATUS_INVALID_PARAMETER_4
;
143 if (!uni_bytes_written
)
144 return STATUS_INVALID_PARAMETER
;
147 status
= STATUS_SUCCESS
;
149 for (i
= 0; i
< utf8_bytes
; i
++)
151 /* read UTF-8 lead byte */
152 ch
= (BYTE
)utf8_src
[i
];
153 utf8_trail_bytes
= 0;
157 status
= STATUS_SOME_NOT_MAPPED
;
162 utf8_trail_bytes
= 3;
167 utf8_trail_bytes
= 2;
172 utf8_trail_bytes
= 1;
176 /* overlong or trail byte */
178 status
= STATUS_SOME_NOT_MAPPED
;
181 /* read UTF-8 trail bytes */
182 if (i
+ utf8_trail_bytes
< utf8_bytes
)
184 for (j
= 0; j
< utf8_trail_bytes
; j
++)
186 if ((utf8_src
[i
+ 1] & 0xc0) == 0x80)
189 ch
|= utf8_src
[i
+ 1] & 0x3f;
195 utf8_trail_bytes
= 0;
196 status
= STATUS_SOME_NOT_MAPPED
;
204 utf8_trail_bytes
= 0;
205 status
= STATUS_SOME_NOT_MAPPED
;
209 /* encode ch as UTF-16 */
210 if ((ch
> 0x10ffff) ||
211 (ch
>= 0xd800 && ch
<= 0xdfff) ||
212 (utf8_trail_bytes
== 2 && ch
< 0x00800) ||
213 (utf8_trail_bytes
== 3 && ch
< 0x10000))
215 /* invalid codepoint or overlong encoding */
216 utf16_ch
[0] = 0xfffd;
217 utf16_ch
[1] = 0xfffd;
218 utf16_ch
[2] = 0xfffd;
219 utf16_ch_len
= utf8_trail_bytes
;
220 status
= STATUS_SOME_NOT_MAPPED
;
222 else if (ch
>= 0x10000)
226 utf16_ch
[0] = 0xd800 + (ch
>> 10 & 0x3ff);
227 utf16_ch
[1] = 0xdc00 + (ch
>> 0 & 0x3ff);
239 written
+= utf16_ch_len
;
243 for (j
= 0; j
< utf16_ch_len
; j
++)
245 if (uni_bytes_max
>= sizeof(WCHAR
))
247 *uni_dest
++ = utf16_ch
[j
];
248 uni_bytes_max
-= sizeof(WCHAR
);
254 status
= STATUS_BUFFER_TOO_SMALL
;
259 *uni_bytes_written
= written
* sizeof(WCHAR
);