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 */
74 assert(ch
<= 0x10ffff);
78 utf8_ch
[0] = ch
& 0x7f;
83 utf8_ch
[0] = 0xc0 | (ch
>> 6 & 0x1f);
84 utf8_ch
[1] = 0x80 | (ch
>> 0 & 0x3f);
87 else if (ch
< 0x10000)
89 utf8_ch
[0] = 0xe0 | (ch
>> 12 & 0x0f);
90 utf8_ch
[1] = 0x80 | (ch
>> 6 & 0x3f);
91 utf8_ch
[2] = 0x80 | (ch
>> 0 & 0x3f);
94 else if (ch
< 0x200000)
96 utf8_ch
[0] = 0xf0 | (ch
>> 18 & 0x07);
97 utf8_ch
[1] = 0x80 | (ch
>> 12 & 0x3f);
98 utf8_ch
[2] = 0x80 | (ch
>> 6 & 0x3f);
99 utf8_ch
[3] = 0x80 | (ch
>> 0 & 0x3f);
105 written
+= utf8_ch_len
;
109 if (utf8_bytes_max
>= utf8_ch_len
)
111 memcpy(utf8_dest
, utf8_ch
, utf8_ch_len
);
112 utf8_dest
+= utf8_ch_len
;
113 utf8_bytes_max
-= utf8_ch_len
;
114 written
+= utf8_ch_len
;
119 status
= STATUS_BUFFER_TOO_SMALL
;
123 *utf8_bytes_written
= written
;
128 /******************************************************************************
129 * RtlUTF8ToUnicodeN [NTDLL.@]
131 NTSTATUS NTAPI
RtlUTF8ToUnicodeN(WCHAR
*uni_dest
, ULONG uni_bytes_max
,
132 ULONG
*uni_bytes_written
,
133 const CHAR
*utf8_src
, ULONG utf8_bytes
)
139 ULONG utf8_trail_bytes
;
144 return STATUS_INVALID_PARAMETER_4
;
145 if (!uni_bytes_written
)
146 return STATUS_INVALID_PARAMETER
;
149 status
= STATUS_SUCCESS
;
151 for (i
= 0; i
< utf8_bytes
; i
++)
153 /* read UTF-8 lead byte */
154 ch
= (BYTE
)utf8_src
[i
];
155 utf8_trail_bytes
= 0;
159 status
= STATUS_SOME_NOT_MAPPED
;
164 utf8_trail_bytes
= 3;
169 utf8_trail_bytes
= 2;
174 utf8_trail_bytes
= 1;
178 /* overlong or trail byte */
180 status
= STATUS_SOME_NOT_MAPPED
;
183 /* read UTF-8 trail bytes */
184 if (i
+ utf8_trail_bytes
< utf8_bytes
)
186 for (j
= 0; j
< utf8_trail_bytes
; j
++)
188 if ((utf8_src
[i
+ 1] & 0xc0) == 0x80)
191 ch
|= utf8_src
[i
+ 1] & 0x3f;
197 utf8_trail_bytes
= 0;
198 status
= STATUS_SOME_NOT_MAPPED
;
206 utf8_trail_bytes
= 0;
207 status
= STATUS_SOME_NOT_MAPPED
;
211 /* encode ch as UTF-16 */
212 if ((ch
> 0x10ffff) ||
213 (ch
>= 0xd800 && ch
<= 0xdfff) ||
214 (utf8_trail_bytes
== 2 && ch
< 0x00800) ||
215 (utf8_trail_bytes
== 3 && ch
< 0x10000))
217 /* invalid codepoint or overlong encoding */
218 utf16_ch
[0] = 0xfffd;
219 utf16_ch
[1] = 0xfffd;
220 utf16_ch
[2] = 0xfffd;
221 utf16_ch_len
= utf8_trail_bytes
;
222 status
= STATUS_SOME_NOT_MAPPED
;
224 else if (ch
>= 0x10000)
228 utf16_ch
[0] = 0xd800 + (ch
>> 10 & 0x3ff);
229 utf16_ch
[1] = 0xdc00 + (ch
>> 0 & 0x3ff);
241 written
+= utf16_ch_len
;
245 for (j
= 0; j
< utf16_ch_len
; j
++)
247 if (uni_bytes_max
>= sizeof(WCHAR
))
249 *uni_dest
++ = utf16_ch
[j
];
250 uni_bytes_max
-= sizeof(WCHAR
);
256 status
= STATUS_BUFFER_TOO_SMALL
;
261 *uni_bytes_written
= written
* sizeof(WCHAR
);