ReactOS  0.4.15-dev-1177-g6cb3b62
rtl.c
Go to the documentation of this file.
1 /*
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>
7  */
8 
9 #include <ntdef.h>
10 #include <ntifs.h>
11 
12 typedef UCHAR BYTE;
13 
14 /******************************************************************************
15  * RtlUnicodeToUTF8N [NTDLL.@]
16  */
17 NTSTATUS NTAPI RtlUnicodeToUTF8N(CHAR *utf8_dest, ULONG utf8_bytes_max,
18  ULONG *utf8_bytes_written,
19  const WCHAR *uni_src, ULONG uni_bytes)
20 {
22  ULONG i;
23  ULONG written;
24  ULONG ch;
25  BYTE utf8_ch[4];
26  ULONG utf8_ch_len;
27 
28  if (!uni_src)
30  if (!utf8_bytes_written)
32  if (utf8_dest && uni_bytes % sizeof(WCHAR))
34 
35  written = 0;
37 
38  for (i = 0; i < uni_bytes / sizeof(WCHAR); i++)
39  {
40  /* decode UTF-16 into ch */
41  ch = uni_src[i];
42  if (ch >= 0xdc00 && ch <= 0xdfff)
43  {
44  ch = 0xfffd;
46  }
47  else if (ch >= 0xd800 && ch <= 0xdbff)
48  {
49  if (i + 1 < uni_bytes / sizeof(WCHAR))
50  {
51  ch -= 0xd800;
52  ch <<= 10;
53  if (uni_src[i + 1] >= 0xdc00 && uni_src[i + 1] <= 0xdfff)
54  {
55  ch |= uni_src[i + 1] - 0xdc00;
56  ch += 0x010000;
57  i++;
58  }
59  else
60  {
61  ch = 0xfffd;
63  }
64  }
65  else
66  {
67  ch = 0xfffd;
69  }
70  }
71 
72  /* encode ch as UTF-8 */
73  ASSERT(ch <= 0x10ffff);
74  if (ch < 0x80)
75  {
76  utf8_ch[0] = ch & 0x7f;
77  utf8_ch_len = 1;
78  }
79  else if (ch < 0x800)
80  {
81  utf8_ch[0] = 0xc0 | (ch >> 6 & 0x1f);
82  utf8_ch[1] = 0x80 | (ch >> 0 & 0x3f);
83  utf8_ch_len = 2;
84  }
85  else if (ch < 0x10000)
86  {
87  utf8_ch[0] = 0xe0 | (ch >> 12 & 0x0f);
88  utf8_ch[1] = 0x80 | (ch >> 6 & 0x3f);
89  utf8_ch[2] = 0x80 | (ch >> 0 & 0x3f);
90  utf8_ch_len = 3;
91  }
92  else if (ch < 0x200000)
93  {
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);
98  utf8_ch_len = 4;
99  }
100 
101  if (!utf8_dest)
102  {
103  written += utf8_ch_len;
104  continue;
105  }
106 
107  if (utf8_bytes_max >= utf8_ch_len)
108  {
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;
113  }
114  else
115  {
116  utf8_bytes_max = 0;
118  }
119  }
120 
121  *utf8_bytes_written = written;
122  return status;
123 }
124 
125 
126 /******************************************************************************
127  * RtlUTF8ToUnicodeN [NTDLL.@]
128  */
129 NTSTATUS NTAPI RtlUTF8ToUnicodeN(WCHAR *uni_dest, ULONG uni_bytes_max,
130  ULONG *uni_bytes_written,
131  const CHAR *utf8_src, ULONG utf8_bytes)
132 {
134  ULONG i, j;
135  ULONG written;
136  ULONG ch;
137  ULONG utf8_trail_bytes;
138  WCHAR utf16_ch[3];
139  ULONG utf16_ch_len;
140 
141  if (!utf8_src)
143  if (!uni_bytes_written)
145 
146  written = 0;
148 
149  for (i = 0; i < utf8_bytes; i++)
150  {
151  /* read UTF-8 lead byte */
152  ch = (BYTE)utf8_src[i];
153  utf8_trail_bytes = 0;
154  if (ch >= 0xf5)
155  {
156  ch = 0xfffd;
158  }
159  else if (ch >= 0xf0)
160  {
161  ch &= 0x07;
162  utf8_trail_bytes = 3;
163  }
164  else if (ch >= 0xe0)
165  {
166  ch &= 0x0f;
167  utf8_trail_bytes = 2;
168  }
169  else if (ch >= 0xc2)
170  {
171  ch &= 0x1f;
172  utf8_trail_bytes = 1;
173  }
174  else if (ch >= 0x80)
175  {
176  /* overlong or trail byte */
177  ch = 0xfffd;
179  }
180 
181  /* read UTF-8 trail bytes */
182  if (i + utf8_trail_bytes < utf8_bytes)
183  {
184  for (j = 0; j < utf8_trail_bytes; j++)
185  {
186  if ((utf8_src[i + 1] & 0xc0) == 0x80)
187  {
188  ch <<= 6;
189  ch |= utf8_src[i + 1] & 0x3f;
190  i++;
191  }
192  else
193  {
194  ch = 0xfffd;
195  utf8_trail_bytes = 0;
197  break;
198  }
199  }
200  }
201  else
202  {
203  ch = 0xfffd;
204  utf8_trail_bytes = 0;
206  i = utf8_bytes;
207  }
208 
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))
214  {
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;
221  }
222  else if (ch >= 0x10000)
223  {
224  /* surrogate pair */
225  ch -= 0x010000;
226  utf16_ch[0] = 0xd800 + (ch >> 10 & 0x3ff);
227  utf16_ch[1] = 0xdc00 + (ch >> 0 & 0x3ff);
228  utf16_ch_len = 2;
229  }
230  else
231  {
232  /* single unit */
233  utf16_ch[0] = ch;
234  utf16_ch_len = 1;
235  }
236 
237  if (!uni_dest)
238  {
239  written += utf16_ch_len;
240  continue;
241  }
242 
243  for (j = 0; j < utf16_ch_len; j++)
244  {
245  if (uni_bytes_max >= sizeof(WCHAR))
246  {
247  *uni_dest++ = utf16_ch[j];
248  uni_bytes_max -= sizeof(WCHAR);
249  written++;
250  }
251  else
252  {
253  uni_bytes_max = 0;
255  }
256  }
257  }
258 
259  *uni_bytes_written = written * sizeof(WCHAR);
260  return status;
261 }
NTSTATUS NTAPI RtlUnicodeToUTF8N(CHAR *utf8_dest, ULONG utf8_bytes_max, ULONG *utf8_bytes_written, const WCHAR *uni_src, ULONG uni_bytes)
Definition: rtl.c:17
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
NTSTATUS NTAPI RtlUTF8ToUnicodeN(WCHAR *uni_dest, ULONG uni_bytes_max, ULONG *uni_bytes_written, const CHAR *utf8_src, ULONG utf8_bytes)
Definition: rtl.c:129
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
UCHAR BYTE
Definition: rtl.c:12
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define STATUS_INVALID_PARAMETER_5
Definition: ntstatus.h:479
__wchar_t WCHAR
Definition: xmlstorage.h:180
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: xxhash.c:193
#define STATUS_SOME_NOT_MAPPED
Definition: ntstatus.h:86
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:478
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97