ReactOS  0.4.14-dev-342-gdc047f9
WideCharToMultiByte.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS API tests
3  * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE: Test for WideCharToMultiByte
5  * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 #define ntv6(x) (LOBYTE(LOWORD(GetVersion())) >= 6 ? (x) : 0)
11 
12 static
13 VOID
15  _In_ PCWSTR WideString,
16  _In_ PCSTR ExpectedUtf8_2003,
17  _In_ PCSTR ExpectedUtf8_Vista,
18  _In_ BOOL IsInvalid,
19  _In_ PCSTR File,
20  _In_ INT Line)
21 {
22  size_t WideLen;
23  size_t Utf8Len;
24  char Buffer[32];
25  int Ret;
26  ULONG i;
27  ULONG Error;
28  PCSTR ExpectedUtf8;
29 
30  ExpectedUtf8 = ntv6(1) ? ExpectedUtf8_Vista : ExpectedUtf8_2003;
31  WideLen = wcslen(WideString);
32  Utf8Len = strlen(ExpectedUtf8);
33 
34  /* Get length only */
35  Ret = WideCharToMultiByte(CP_UTF8, 0, WideString, WideLen, NULL, 0, NULL, NULL);
36  ok_(File, Line)(Ret == Utf8Len, "Length check: Ret = %d\n", Ret);
37 
38  /* Get length including nul */
39  Ret = WideCharToMultiByte(CP_UTF8, 0, WideString, WideLen + 1, NULL, 0, NULL, NULL);
40  ok_(File, Line)(Ret == Utf8Len + 1, "Length check with null: Ret = %d\n", Ret);
41 
42  /* Convert, excluding null */
43  FillMemory(Buffer, sizeof(Buffer), 0x55);
44  Ret = WideCharToMultiByte(CP_UTF8, 0, WideString, WideLen, Buffer, sizeof(Buffer), NULL, NULL);
45  ok_(File, Line)(Ret == Utf8Len, "Convert: Ret = %d\n", Ret);
46  for (i = 0; i < Utf8Len; i++)
47  {
48  ok_(File, Line)(Buffer[i] == ExpectedUtf8[i], "Convert: Buffer[%lu] = 0x%x, expected 0x%x\n", i, (unsigned char)Buffer[i], (unsigned char)ExpectedUtf8[i]);
49  }
50 
51  /* Convert, including null */
52  FillMemory(Buffer, sizeof(Buffer), 0x55);
53  Ret = WideCharToMultiByte(CP_UTF8, 0, WideString, WideLen + 1, Buffer, sizeof(Buffer), NULL, NULL);
54  ok_(File, Line)(Ret == Utf8Len + 1, "Convert with null: Ret = %d\n", Ret);
55  for (i = 0; i < Utf8Len + 1; i++)
56  {
57  ok_(File, Line)(Buffer[i] == ExpectedUtf8[i], "Convert with null: Buffer[%lu] = 0x%x, expected 0x%x\n", i, (unsigned char)Buffer[i], (unsigned char)ExpectedUtf8[i]);
58  }
59 
60  /* Get length, reject invalid */
61  SetLastError(0xfeedf00d);
62  Ret = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, WideString, WideLen + 1, NULL, 0, NULL, NULL);
63  Error = GetLastError();
64  if (!ntv6(1))
65  {
66  ok_(File, Line)(Ret == 0, "Length check, reject invalid, NT5: Ret = %d\n", Ret);
67  ok_(File, Line)(Error == ERROR_INVALID_FLAGS, "Length check, reject invalid, NT5: Error = %lu\n", Error);
68  }
69  else if (IsInvalid)
70  {
71  ok_(File, Line)(Ret == 0, "Length check, reject invalid: Ret = %d\n", Ret);
72  ok_(File, Line)(Error == ERROR_NO_UNICODE_TRANSLATION, "Length check, reject invalid: Error = %lu\n", Error);
73  }
74  else
75  {
76  ok_(File, Line)(Ret == Utf8Len + 1, "Length check, reject invalid: Ret = %d\n", Ret);
77  }
78 
79  /* Convert, reject invalid */
80  FillMemory(Buffer, sizeof(Buffer), 0x55);
81  SetLastError(0xfeedf00d);
82  Ret = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, WideString, WideLen + 1, Buffer, sizeof(Buffer), NULL, NULL);
83  Error = GetLastError();
84  if (!ntv6(1))
85  {
86  ok_(File, Line)(Ret == 0, "Convert, reject invalid, NT5: Ret = %d\n", Ret);
87  ok_(File, Line)(Error == ERROR_INVALID_FLAGS, "Convert, reject invalid, NT5: Error = %lu\n", Error);
88  }
89  else if (IsInvalid)
90  {
91  ok_(File, Line)(Ret == 0, "Convert, reject invalid: Ret = %d\n", Ret);
92  ok_(File, Line)(Error == ERROR_NO_UNICODE_TRANSLATION, "Convert, reject invalid: Error = %lu\n", Error);
93  for (i = 0; i < Utf8Len + 1; i++)
94  {
95  ok_(File, Line)(Buffer[i] == ExpectedUtf8[i], "Convert, reject invalid: Buffer[%lu] = 0x%x, expected 0x%x\n", i, (unsigned char)Buffer[i], (unsigned char)ExpectedUtf8[i]);
96  }
97  }
98  else
99  {
100  ok_(File, Line)(Ret == Utf8Len + 1, "Convert, reject invalid: Ret = %d\n", Ret);
101  for (i = 0; i < Utf8Len + 1; i++)
102  {
103  ok_(File, Line)(Buffer[i] == ExpectedUtf8[i], "Convert, reject invalid: Buffer[%lu] = 0x%x, expected 0x%x\n", i, (unsigned char)Buffer[i], (unsigned char)ExpectedUtf8[i]);
104  }
105  }
106 }
107 #define Utf8Convert(w, e, i) Utf8Convert_(w, e, e, i, __FILE__, __LINE__)
108 #define Utf8Convert_Vista(w, e, i, e2) Utf8Convert_(w, e, e2, i, __FILE__, __LINE__)
109 
110 static
111 VOID
113 {
114  Utf8Convert(L"", "", FALSE);
115 
116  /* Various character ranges */
117  Utf8Convert(L"A", "A", FALSE);
118  Utf8Convert(L"\x007f", "\x7f", FALSE);
119  Utf8Convert(L"\x0080", "\xc2\x80", FALSE);
120  Utf8Convert(L"\x00ff", "\xc3\xbf", FALSE);
121  Utf8Convert(L"\x0100", "\xc4\x80", FALSE);
122  Utf8Convert(L"\x07ff", "\xdf\xbf", FALSE);
123  Utf8Convert(L"\x0800", "\xe0\xa0\x80", FALSE);
124  Utf8Convert(L"\xd7ff", "\xed\x9f\xbf", FALSE);
125  Utf8Convert(L"\xe000", "\xee\x80\x80", FALSE);
126  Utf8Convert(L"\xffff", "\xef\xbf\xbf", FALSE);
127 
128  /* surrogate pairs */
129  Utf8Convert(L"\xd800\xdc00", "\xf0\x90\x80\x80", FALSE); /* U+10000 */
130  Utf8Convert(L"\xd800\xdfff", "\xf0\x90\x8f\xbf", FALSE); /* U+103ff */
131  Utf8Convert(L"\xd801\xdc00", "\xf0\x90\x90\x80", FALSE); /* U+10400 */
132  Utf8Convert(L"\xdbff\xdfff", "\xf4\x8f\xbf\xbf", FALSE); /* U+10ffff */
133 
134  /* standalone lead surrogate becomes 0xfffd on Vista, goes through verbatim on 2003 */
135  Utf8Convert_Vista(L"\xd800", "\xed\xa0\x80", TRUE,
136  "\xef\xbf\xbd");
137  Utf8Convert_Vista(L"\xd800-", "\xed\xa0\x80-", TRUE,
138  "\xef\xbf\xbd-");
139  Utf8Convert_Vista(L"\xdbff", "\xed\xaf\xbf", TRUE,
140  "\xef\xbf\xbd");
141  Utf8Convert_Vista(L"\xdbff-", "\xed\xaf\xbf-", TRUE,
142  "\xef\xbf\xbd-");
143 
144  /* standalone trail surrogate becomes 0xfffd */
145  Utf8Convert_Vista(L"\xdc00", "\xed\xb0\x80", TRUE,
146  "\xef\xbf\xbd");
147  Utf8Convert_Vista(L"\xdc00-", "\xed\xb0\x80-", TRUE,
148  "\xef\xbf\xbd-");
149  Utf8Convert_Vista(L"\xdfff", "\xed\xbf\xbf", TRUE,
150  "\xef\xbf\xbd");
151  Utf8Convert_Vista(L"\xdfff-", "\xed\xbf\xbf-", TRUE,
152  "\xef\xbf\xbd-");
153 
154  /* Reverse surrogate pair */
155  Utf8Convert_Vista(L"\xdfff\xdbff", "\xed\xbf\xbf\xed\xaf\xbf", TRUE,
156  "\xef\xbf\xbd\xef\xbf\xbd");
157 
158  /* Byte order marks */
159  Utf8Convert(L"\xfeff", "\xef\xbb\xbf", FALSE);
160  Utf8Convert(L"\xfffe", "\xef\xbf\xbe", FALSE);
161 
162  /* canonically equivalent representations -- no normalization should happen */
163  Utf8Convert(L"\x1e09", "\xe1\xb8\x89", FALSE);
164  Utf8Convert(L"\x0107\x0327", "\xc4\x87\xcc\xa7", FALSE);
165  Utf8Convert(L"\x00e7\x0301", "\xc3\xa7\xcc\x81", FALSE);
166  Utf8Convert(L"\x0063\x0327\x0301", "\x63\xcc\xa7\xcc\x81", FALSE);
167  Utf8Convert(L"\x0063\x0301\x0327", "\x63\xcc\x81\xcc\xa7", FALSE);
168 }
169 
171 {
172  TestUtf8();
173 }
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define TRUE
Definition: types.h:120
#define Utf8Convert_Vista(w, e, i, e2)
#define WideCharToMultiByte
Definition: compat.h:101
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ntv6(x)
#define Utf8Convert(w, e, i)
int32_t INT
Definition: typedefs.h:56
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
#define CP_UTF8
Definition: nls.h:20
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
Definition: bufpool.h:45
static VOID Utf8Convert_(_In_ PCWSTR WideString, _In_ PCSTR ExpectedUtf8_2003, _In_ PCSTR ExpectedUtf8_Vista, _In_ BOOL IsInvalid, _In_ PCSTR File, _In_ INT Line)
#define WC_ERR_INVALID_CHARS
Definition: unicode.h:47
#define FillMemory(BUF, SIZ, MASK)
Definition: strucsup.c:31
BOOL Error
Definition: chkdsk.c:66
#define SetLastError(x)
Definition: compat.h:417
static VOID TestUtf8(VOID)
Definition: ncftp.h:79
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
static const WCHAR L[]
Definition: oid.c:1250
START_TEST(WideCharToMultiByte)
#define _In_
Definition: no_sal2.h:204
unsigned int ULONG
Definition: retypes.h:1
const char * PCSTR
Definition: typedefs.h:51
Definition: File.h:15
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define ok_(x1, x2)
Definition: atltest.h:61