~ubuntu-branches/ubuntu/vivid/freerdp/vivid

« back to all changes in this revision

Viewing changes to winpr/libwinpr/crt/test/TestUnicodeConversion.c

  • Committer: Package Import Robot
  • Author(s): Iain Lane
  • Date: 2014-11-11 12:20:50 UTC
  • mfrom: (1.1.9) (9.1.17 sid)
  • Revision ID: package-import@ubuntu.com-20141111122050-wyr8hrnwco9fcmum
Tags: 1.1.0~git20140921.1.440916e+dfsg1-2ubuntu1
* Merge with Debian unstable, remaining changes
  - Disable ffmpeg support
* Disable gstreamer support, this relies on gstreamer 0.10 and we don't want
  to add any more deps on that.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
#include <stdio.h>
 
3
#include <winpr/crt.h>
 
4
#include <winpr/error.h>
 
5
#include <winpr/windows.h>
 
6
 
 
7
#if defined(WIN32) || defined(WIN64)
 
8
  #ifndef __LITTLE_ENDIAN
 
9
    #define __LITTLE_ENDIAN 1234
 
10
    #define __BIG_ENDIAN    4321
 
11
  #endif
 
12
  #ifndef __BYTE_ORDER
 
13
    #define __BYTE_ORDER __LITTLE_ENDIAN
 
14
  #endif
 
15
#else
 
16
  #include <endian.h>
 
17
#endif
 
18
 
 
19
/* Letters */
 
20
 
 
21
static BYTE c_cedilla_UTF8[] = "\xC3\xA7\x00";
 
22
static BYTE c_cedilla_UTF16[] = "\xE7\x00\x00\x00";
 
23
static int c_cedilla_cchWideChar = 2;
 
24
static int c_cedilla_cbMultiByte = 3;
 
25
 
 
26
/* English */
 
27
 
 
28
static BYTE en_Hello_UTF8[] = "Hello\0";
 
29
static BYTE en_Hello_UTF16[] = "\x48\x00\x65\x00\x6C\x00\x6C\x00\x6F\x00\x00\x00";
 
30
static int en_Hello_cchWideChar = 6;
 
31
static int en_Hello_cbMultiByte = 6;
 
32
 
 
33
static BYTE en_HowAreYou_UTF8[] = "How are you?\0";
 
34
static BYTE en_HowAreYou_UTF16[] = "\x48\x00\x6F\x00\x77\x00\x20\x00\x61\x00\x72\x00\x65\x00\x20\x00"
 
35
                "\x79\x00\x6F\x00\x75\x00\x3F\x00\x00\x00";
 
36
static int en_HowAreYou_cchWideChar = 13;
 
37
static int en_HowAreYou_cbMultiByte = 13;
 
38
 
 
39
/* French */
 
40
 
 
41
static BYTE fr_Hello_UTF8[] = "Allo\0";
 
42
static BYTE fr_Hello_UTF16[] = "\x41\x00\x6C\x00\x6C\x00\x6F\x00\x00\x00";
 
43
static int fr_Hello_cchWideChar = 5;
 
44
static int fr_Hello_cbMultiByte = 5;
 
45
 
 
46
static BYTE fr_HowAreYou_UTF8[] = "\x43\x6F\x6D\x6D\x65\x6E\x74\x20\xC3\xA7\x61\x20\x76\x61\x3F\x00";
 
47
static BYTE fr_HowAreYou_UTF16[] = "\x43\x00\x6F\x00\x6D\x00\x6D\x00\x65\x00\x6E\x00\x74\x00\x20\x00"
 
48
                "\xE7\x00\x61\x00\x20\x00\x76\x00\x61\x00\x3F\x00\x00\x00";
 
49
static int fr_HowAreYou_cchWideChar = 15;
 
50
static int fr_HowAreYou_cbMultiByte = 16;
 
51
 
 
52
/* Russian */
 
53
 
 
54
static BYTE ru_Hello_UTF8[] = "\xD0\x97\xD0\xB4\xD0\xBE\xD1\x80\xD0\xBE\xD0\xB2\xD0\xBE\x00";
 
55
static BYTE ru_Hello_UTF16[] = "\x17\x04\x34\x04\x3E\x04\x40\x04\x3E\x04\x32\x04\x3E\x04\x00\x00";
 
56
static int ru_Hello_cchWideChar = 8;
 
57
static int ru_Hello_cbMultiByte = 15;
 
58
 
 
59
static BYTE ru_HowAreYou_UTF8[] = "\xD0\x9A\xD0\xB0\xD0\xBA\x20\xD0\xB4\xD0\xB5\xD0\xBB\xD0\xB0\x3F\x00";
 
60
static BYTE ru_HowAreYou_UTF16[] = "\x1A\x04\x30\x04\x3A\x04\x20\x00\x34\x04\x35\x04\x3B\x04\x30\x04"
 
61
                "\x3F\x00\x00\x00";
 
62
static int ru_HowAreYou_cchWideChar = 10;
 
63
static int ru_HowAreYou_cbMultiByte = 17;
 
64
 
 
65
/* Arabic */
 
66
 
 
67
static BYTE ar_Hello_UTF8[] = "\xD8\xA7\xD9\x84\xD8\xB3\xD9\x84\xD8\xA7\xD9\x85\x20\xD8\xB9\xD9"
 
68
                "\x84\xD9\x8A\xD9\x83\xD9\x85\x00";
 
69
static BYTE ar_Hello_UTF16[] = "\x27\x06\x44\x06\x33\x06\x44\x06\x27\x06\x45\x06\x20\x00\x39\x06"
 
70
                "\x44\x06\x4A\x06\x43\x06\x45\x06\x00\x00";
 
71
static int ar_Hello_cchWideChar = 13;
 
72
static int ar_Hello_cbMultiByte = 24;
 
73
 
 
74
static BYTE ar_HowAreYou_UTF8[] = "\xD9\x83\xD9\x8A\xD9\x81\x20\xD8\xAD\xD8\xA7\xD9\x84\xD9\x83\xD8"
 
75
                "\x9F\x00";
 
76
static BYTE ar_HowAreYou_UTF16[] = "\x43\x06\x4A\x06\x41\x06\x20\x00\x2D\x06\x27\x06\x44\x06\x43\x06"
 
77
                "\x1F\x06\x00\x00";
 
78
static int ar_HowAreYou_cchWideChar = 10;
 
79
static int ar_HowAreYou_cbMultiByte = 18;
 
80
 
 
81
/* Chinese */
 
82
 
 
83
static BYTE ch_Hello_UTF8[] = "\xE4\xBD\xA0\xE5\xA5\xBD\x00";
 
84
static BYTE ch_Hello_UTF16[] = "\x60\x4F\x7D\x59\x00\x00";
 
85
static int ch_Hello_cchWideChar = 3;
 
86
static int ch_Hello_cbMultiByte = 7;
 
87
 
 
88
static BYTE ch_HowAreYou_UTF8[] = "\xE4\xBD\xA0\xE5\xA5\xBD\xE5\x90\x97\x00";
 
89
static BYTE ch_HowAreYou_UTF16[] = "\x60\x4F\x7D\x59\x17\x54\x00\x00";
 
90
static int ch_HowAreYou_cchWideChar = 4;
 
91
static int ch_HowAreYou_cbMultiByte = 10;
 
92
 
 
93
void string_hexdump(BYTE* data, int length)
 
94
{
 
95
        BYTE* p = data;
 
96
        int i, line, offset = 0;
 
97
 
 
98
        while (offset < length)
 
99
        {
 
100
                printf("%04x ", offset);
 
101
 
 
102
                line = length - offset;
 
103
 
 
104
                if (line > 16)
 
105
                        line = 16;
 
106
 
 
107
                for (i = 0; i < line; i++)
 
108
                        printf("%02x ", p[i]);
 
109
 
 
110
                for (; i < 16; i++)
 
111
                        printf("   ");
 
112
 
 
113
                for (i = 0; i < line; i++)
 
114
                        printf("%c", (p[i] >= 0x20 && p[i] < 0x7F) ? p[i] : '.');
 
115
 
 
116
                printf("\n");
 
117
 
 
118
                offset += line;
 
119
                p += line;
 
120
        }
 
121
}
 
122
 
 
123
void utf16_le_to_ne(BYTE *data, int length)
 
124
{
 
125
#if __BYTE_ORDER == __BIG_ENDIAN
 
126
        int i;
 
127
 
 
128
        for (i = 0; i < length / 2; i++)
 
129
        {
 
130
                BYTE c;
 
131
 
 
132
                c = data[i * 2];
 
133
                data[i * 2] = data[i * 2 + 1];
 
134
                data[i * 2 + 1] = c;
 
135
        }
 
136
#endif
 
137
}
 
138
 
 
139
int convert_utf8_to_utf16(BYTE* lpMultiByteStr, BYTE* expected_lpWideCharStr, int expected_cchWideChar)
 
140
{
 
141
        int length;
 
142
        int cbMultiByte;
 
143
        int cchWideChar;
 
144
        LPWSTR lpWideCharStr;
 
145
 
 
146
        cbMultiByte = strlen((char*) lpMultiByteStr);
 
147
        cchWideChar = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) lpMultiByteStr, -1, NULL, 0);
 
148
 
 
149
        printf("MultiByteToWideChar Input UTF8 String:\n");
 
150
        string_hexdump(lpMultiByteStr, cbMultiByte + 1);
 
151
 
 
152
        printf("MultiByteToWideChar required cchWideChar: %d\n", cchWideChar);
 
153
 
 
154
        if (cchWideChar != expected_cchWideChar)
 
155
        {
 
156
                printf("MultiByteToWideChar unexpected cchWideChar: actual: %d expected: %d\n",
 
157
                        cchWideChar, expected_cchWideChar);
 
158
                return -1;
 
159
        }
 
160
 
 
161
        lpWideCharStr = (LPWSTR) malloc(cchWideChar * sizeof(WCHAR));
 
162
        lpWideCharStr[cchWideChar - 1] = 0xFFFF; /* should be overwritten if null terminator is inserted properly */
 
163
        length = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR) lpMultiByteStr, cbMultiByte + 1, lpWideCharStr, cchWideChar);
 
164
 
 
165
        printf("MultiByteToWideChar converted length (WCHAR): %d\n", length);
 
166
 
 
167
        if (!length)
 
168
        {
 
169
                DWORD error = GetLastError();
 
170
                printf("MultiByteToWideChar error: 0x%08lX\n", error);
 
171
                return -1;
 
172
        }
 
173
 
 
174
        if (length != expected_cchWideChar)
 
175
        {
 
176
                printf("MultiByteToWideChar unexpected converted length (WCHAR): actual: %d expected: %d\n",
 
177
                        length, expected_cchWideChar);
 
178
                return -1;
 
179
        }
 
180
 
 
181
        if (_wcscmp(lpWideCharStr, (WCHAR*) expected_lpWideCharStr) != 0)
 
182
        {
 
183
                printf("MultiByteToWideChar unexpected string:\n");
 
184
 
 
185
                printf("UTF8 String:\n");
 
186
                string_hexdump(lpMultiByteStr, cbMultiByte + 1);
 
187
 
 
188
                printf("UTF16 String (actual):\n");
 
189
                string_hexdump((BYTE*) lpWideCharStr, length * sizeof(WCHAR));
 
190
 
 
191
                printf("UTF16 String (expected):\n");
 
192
                string_hexdump((BYTE*) expected_lpWideCharStr, expected_cchWideChar * sizeof(WCHAR));
 
193
 
 
194
                return -1;
 
195
        }
 
196
 
 
197
        printf("MultiByteToWideChar Output UTF16 String:\n");
 
198
        string_hexdump((BYTE*) lpWideCharStr, length * sizeof(WCHAR));
 
199
        printf("\n");
 
200
 
 
201
        free(lpWideCharStr);
 
202
 
 
203
        return length;
 
204
}
 
205
 
 
206
int convert_utf16_to_utf8(BYTE* lpWideCharStr, BYTE* expected_lpMultiByteStr, int expected_cbMultiByte)
 
207
{
 
208
        int length;
 
209
        int cchWideChar;
 
210
        int cbMultiByte;
 
211
        LPSTR lpMultiByteStr = NULL;
 
212
 
 
213
        cchWideChar = _wcslen((WCHAR*) lpWideCharStr);
 
214
        cbMultiByte = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) lpWideCharStr, -1, NULL, 0, NULL, NULL);
 
215
 
 
216
        printf("WideCharToMultiByte Input UTF16 String:\n");
 
217
        string_hexdump(lpWideCharStr, (cchWideChar + 1) * sizeof(WCHAR));
 
218
 
 
219
        printf("WideCharToMultiByte required cbMultiByte: %d\n", cbMultiByte);
 
220
 
 
221
        if (cbMultiByte != expected_cbMultiByte)
 
222
        {
 
223
                printf("WideCharToMultiByte unexpected cbMultiByte: actual: %d expected: %d\n",
 
224
                        cbMultiByte, expected_cbMultiByte);
 
225
                return -1;
 
226
        }
 
227
 
 
228
        lpMultiByteStr = (LPSTR) malloc(cbMultiByte);
 
229
        lpMultiByteStr[cbMultiByte - 1] = 0xFF; /* should be overwritten if null terminator is inserted properly */
 
230
        length = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) lpWideCharStr, cchWideChar + 1, lpMultiByteStr, cbMultiByte, NULL, NULL);
 
231
 
 
232
        printf("WideCharToMultiByte converted length (BYTE): %d\n", length);
 
233
 
 
234
        if (!length)
 
235
        {
 
236
                DWORD error = GetLastError();
 
237
                printf("WideCharToMultiByte error: 0x%08lX\n", error);
 
238
                return -1;
 
239
        }
 
240
 
 
241
        if (length != expected_cbMultiByte)
 
242
        {
 
243
                printf("WideCharToMultiByte unexpected converted length (BYTE): actual: %d expected: %d\n",
 
244
                        length, expected_cbMultiByte);
 
245
                return -1;
 
246
        }
 
247
 
 
248
        if (strcmp(lpMultiByteStr, (char*) expected_lpMultiByteStr) != 0)
 
249
        {
 
250
                printf("WideCharToMultiByte unexpected string:\n");
 
251
 
 
252
                printf("UTF16 String:\n");
 
253
                string_hexdump((BYTE*) lpWideCharStr, (cchWideChar + 1) * sizeof(WCHAR));
 
254
 
 
255
                printf("UTF8 String (actual):\n");
 
256
                string_hexdump((BYTE*) lpMultiByteStr, cbMultiByte);
 
257
 
 
258
                printf("UTF8 String (expected):\n");
 
259
                string_hexdump((BYTE*) expected_lpMultiByteStr, expected_cbMultiByte);
 
260
 
 
261
                return -1;
 
262
        }
 
263
 
 
264
        printf("WideCharToMultiByte Output UTF8 String:\n");
 
265
        string_hexdump((BYTE*) lpMultiByteStr, cbMultiByte);
 
266
        printf("\n");
 
267
 
 
268
        free(lpMultiByteStr);
 
269
 
 
270
        return length;
 
271
}
 
272
 
 
273
int TestUnicodeConversion(int argc, char* argv[])
 
274
{
 
275
        /* Letters */
 
276
 
 
277
        printf("Letters\n");
 
278
        utf16_le_to_ne(c_cedilla_UTF16, sizeof(c_cedilla_UTF16));
 
279
 
 
280
        if (convert_utf8_to_utf16(c_cedilla_UTF8, c_cedilla_UTF16, c_cedilla_cchWideChar) < 1)
 
281
                return -1;
 
282
 
 
283
        if (convert_utf16_to_utf8(c_cedilla_UTF16, c_cedilla_UTF8, c_cedilla_cbMultiByte) < 1)
 
284
                return -1;
 
285
        
 
286
        /* English */
 
287
 
 
288
        printf("English\n");
 
289
        utf16_le_to_ne(en_Hello_UTF16, sizeof(en_Hello_UTF16));
 
290
        utf16_le_to_ne(en_HowAreYou_UTF16, sizeof(en_HowAreYou_UTF16));
 
291
 
 
292
        if (convert_utf8_to_utf16(en_Hello_UTF8, en_Hello_UTF16, en_Hello_cchWideChar) < 1)
 
293
                return -1;
 
294
        if (convert_utf8_to_utf16(en_HowAreYou_UTF8, en_HowAreYou_UTF16, en_HowAreYou_cchWideChar) < 1)
 
295
                return -1;
 
296
 
 
297
        if (convert_utf16_to_utf8(en_Hello_UTF16, en_Hello_UTF8, en_Hello_cbMultiByte) < 1)
 
298
                return -1;
 
299
        if (convert_utf16_to_utf8(en_HowAreYou_UTF16, en_HowAreYou_UTF8, en_HowAreYou_cbMultiByte) < 1)
 
300
                return -1;
 
301
 
 
302
        /* French */
 
303
 
 
304
        printf("French\n");
 
305
        utf16_le_to_ne(fr_Hello_UTF16, sizeof(fr_Hello_UTF16));
 
306
        utf16_le_to_ne(fr_HowAreYou_UTF16, sizeof(fr_HowAreYou_UTF16));
 
307
 
 
308
        if (convert_utf8_to_utf16(fr_Hello_UTF8, fr_Hello_UTF16, fr_Hello_cchWideChar) < 1)
 
309
                return -1;
 
310
        if (convert_utf8_to_utf16(fr_HowAreYou_UTF8, fr_HowAreYou_UTF16, fr_HowAreYou_cchWideChar) < 1)
 
311
                return -1;
 
312
 
 
313
        if (convert_utf16_to_utf8(fr_Hello_UTF16, fr_Hello_UTF8, fr_Hello_cbMultiByte) < 1)
 
314
                return -1;
 
315
        if (convert_utf16_to_utf8(fr_HowAreYou_UTF16, fr_HowAreYou_UTF8, fr_HowAreYou_cbMultiByte) < 1)
 
316
                return -1;
 
317
 
 
318
        /* Russian */
 
319
 
 
320
        printf("Russian\n");
 
321
        utf16_le_to_ne(ru_Hello_UTF16, sizeof(ru_Hello_UTF16));
 
322
        utf16_le_to_ne(ru_HowAreYou_UTF16, sizeof(ru_HowAreYou_UTF16));
 
323
 
 
324
        if (convert_utf8_to_utf16(ru_Hello_UTF8, ru_Hello_UTF16, ru_Hello_cchWideChar) < 1)
 
325
                return -1;
 
326
        if (convert_utf8_to_utf16(ru_HowAreYou_UTF8, ru_HowAreYou_UTF16, ru_HowAreYou_cchWideChar) < 1)
 
327
                return -1;
 
328
 
 
329
        if (convert_utf16_to_utf8(ru_Hello_UTF16, ru_Hello_UTF8, ru_Hello_cbMultiByte) < 1)
 
330
                return -1;
 
331
        if (convert_utf16_to_utf8(ru_HowAreYou_UTF16, ru_HowAreYou_UTF8, ru_HowAreYou_cbMultiByte) < 1)
 
332
                return -1;
 
333
 
 
334
        /* Arabic */
 
335
 
 
336
        printf("Arabic\n");
 
337
        utf16_le_to_ne(ar_Hello_UTF16, sizeof(ar_Hello_UTF16));
 
338
        utf16_le_to_ne(ar_HowAreYou_UTF16, sizeof(ar_HowAreYou_UTF16));
 
339
 
 
340
        if (convert_utf8_to_utf16(ar_Hello_UTF8, ar_Hello_UTF16, ar_Hello_cchWideChar) < 1)
 
341
                return -1;
 
342
        if (convert_utf8_to_utf16(ar_HowAreYou_UTF8, ar_HowAreYou_UTF16, ar_HowAreYou_cchWideChar) < 1)
 
343
                return -1;
 
344
 
 
345
        if (convert_utf16_to_utf8(ar_Hello_UTF16, ar_Hello_UTF8, ar_Hello_cbMultiByte) < 1)
 
346
                return -1;
 
347
        if (convert_utf16_to_utf8(ar_HowAreYou_UTF16, ar_HowAreYou_UTF8, ar_HowAreYou_cbMultiByte) < 1)
 
348
                return -1;
 
349
 
 
350
        /* Chinese */
 
351
 
 
352
        printf("Chinese\n");
 
353
        utf16_le_to_ne(ch_Hello_UTF16, sizeof(ch_Hello_UTF16));
 
354
        utf16_le_to_ne(ch_HowAreYou_UTF16, sizeof(ch_HowAreYou_UTF16));
 
355
 
 
356
        if (convert_utf8_to_utf16(ch_Hello_UTF8, ch_Hello_UTF16, ch_Hello_cchWideChar) < 1)
 
357
                return -1;
 
358
        if (convert_utf8_to_utf16(ch_HowAreYou_UTF8, ch_HowAreYou_UTF16, ch_HowAreYou_cchWideChar) < 1)
 
359
                return -1;
 
360
 
 
361
        if (convert_utf16_to_utf8(ch_Hello_UTF16, ch_Hello_UTF8, ch_Hello_cbMultiByte) < 1)
 
362
                return -1;
 
363
        if (convert_utf16_to_utf8(ch_HowAreYou_UTF16, ch_HowAreYou_UTF8, ch_HowAreYou_cbMultiByte) < 1)
 
364
                return -1;
 
365
 
 
366
        return 0;
 
367
}