ReactOS 0.4.15-dev-7842-g558ab78
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
12static
13VOID
15 _In_ PCWSTR WideString,
16 _In_ PCSTR ExpectedUtf8_2003,
17 _In_ PCSTR ExpectedUtf8_Vista,
18 _In_ BOOL IsInvalid,
21{
22 int WideLen;
23 int Utf8Len;
24 char Buffer[32];
25 int Ret;
26 ULONG i;
28 PCSTR ExpectedUtf8;
29
30 ExpectedUtf8 = ntv6(1) ? ExpectedUtf8_Vista : ExpectedUtf8_2003;
31 WideLen = lstrlenW(WideString);
32 Utf8Len = lstrlenA(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);
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);
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
110static
111VOID
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}
#define Utf8Convert(w, e, i)
#define Utf8Convert_Vista(w, e, i, e2)
#define ntv6(x)
static VOID TestUtf8(VOID)
static VOID Utf8Convert_(_In_ PCWSTR WideString, _In_ PCSTR ExpectedUtf8_2003, _In_ PCSTR ExpectedUtf8_Vista, _In_ BOOL IsInvalid, _In_ PCSTR File, _In_ INT Line)
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
BOOL Error
Definition: chkdsk.c:66
Definition: bufpool.h:45
Definition: File.h:16
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define SetLastError(x)
Definition: compat.h:752
#define WideCharToMultiByte
Definition: compat.h:111
#define lstrlenW
Definition: compat.h:750
unsigned char
Definition: typeof.h:29
#define FillMemory(BUF, SIZ, MASK)
Definition: strucsup.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
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 WC_ERR_INVALID_CHARS
Definition: unicode.h:47
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define _In_
Definition: ms_sal.h:308
#define L(x)
Definition: ntvdm.h:50
#define CP_UTF8
Definition: nls.h:20
Definition: ncftp.h:79
const uint16_t * PCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG
Definition: typedefs.h:59
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583