TestUnicodeConversion.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. #include <stdio.h>
  2. #include <winpr/crt.h>
  3. #include <winpr/error.h>
  4. #include <winpr/windows.h>
  5. /* Letters */
  6. static BYTE c_cedilla_UTF8[] = "\xC3\xA7\x00";
  7. static BYTE c_cedilla_UTF16[] = "\xE7\x00\x00\x00";
  8. static int c_cedilla_cchWideChar = 2;
  9. static int c_cedilla_cbMultiByte = 3;
  10. /* English */
  11. static BYTE en_Hello_UTF8[] = "Hello\0";
  12. static BYTE en_Hello_UTF16[] = "\x48\x00\x65\x00\x6C\x00\x6C\x00\x6F\x00\x00\x00";
  13. static int en_Hello_cchWideChar = 6;
  14. static int en_Hello_cbMultiByte = 6;
  15. static BYTE en_HowAreYou_UTF8[] = "How are you?\0";
  16. static BYTE en_HowAreYou_UTF16[] =
  17. "\x48\x00\x6F\x00\x77\x00\x20\x00\x61\x00\x72\x00\x65\x00\x20\x00"
  18. "\x79\x00\x6F\x00\x75\x00\x3F\x00\x00\x00";
  19. static int en_HowAreYou_cchWideChar = 13;
  20. static int en_HowAreYou_cbMultiByte = 13;
  21. /* French */
  22. static BYTE fr_Hello_UTF8[] = "Allo\0";
  23. static BYTE fr_Hello_UTF16[] = "\x41\x00\x6C\x00\x6C\x00\x6F\x00\x00\x00";
  24. static int fr_Hello_cchWideChar = 5;
  25. static int fr_Hello_cbMultiByte = 5;
  26. static BYTE fr_HowAreYou_UTF8[] =
  27. "\x43\x6F\x6D\x6D\x65\x6E\x74\x20\xC3\xA7\x61\x20\x76\x61\x3F\x00";
  28. static BYTE fr_HowAreYou_UTF16[] =
  29. "\x43\x00\x6F\x00\x6D\x00\x6D\x00\x65\x00\x6E\x00\x74\x00\x20\x00"
  30. "\xE7\x00\x61\x00\x20\x00\x76\x00\x61\x00\x3F\x00\x00\x00";
  31. static int fr_HowAreYou_cchWideChar = 15;
  32. static int fr_HowAreYou_cbMultiByte = 16;
  33. /* Russian */
  34. static BYTE ru_Hello_UTF8[] = "\xD0\x97\xD0\xB4\xD0\xBE\xD1\x80\xD0\xBE\xD0\xB2\xD0\xBE\x00";
  35. static BYTE ru_Hello_UTF16[] = "\x17\x04\x34\x04\x3E\x04\x40\x04\x3E\x04\x32\x04\x3E\x04\x00\x00";
  36. static int ru_Hello_cchWideChar = 8;
  37. static int ru_Hello_cbMultiByte = 15;
  38. static BYTE ru_HowAreYou_UTF8[] =
  39. "\xD0\x9A\xD0\xB0\xD0\xBA\x20\xD0\xB4\xD0\xB5\xD0\xBB\xD0\xB0\x3F\x00";
  40. static BYTE ru_HowAreYou_UTF16[] =
  41. "\x1A\x04\x30\x04\x3A\x04\x20\x00\x34\x04\x35\x04\x3B\x04\x30\x04"
  42. "\x3F\x00\x00\x00";
  43. static int ru_HowAreYou_cchWideChar = 10;
  44. static int ru_HowAreYou_cbMultiByte = 17;
  45. /* Arabic */
  46. static BYTE ar_Hello_UTF8[] = "\xD8\xA7\xD9\x84\xD8\xB3\xD9\x84\xD8\xA7\xD9\x85\x20\xD8\xB9\xD9"
  47. "\x84\xD9\x8A\xD9\x83\xD9\x85\x00";
  48. static BYTE ar_Hello_UTF16[] = "\x27\x06\x44\x06\x33\x06\x44\x06\x27\x06\x45\x06\x20\x00\x39\x06"
  49. "\x44\x06\x4A\x06\x43\x06\x45\x06\x00\x00";
  50. static int ar_Hello_cchWideChar = 13;
  51. static int ar_Hello_cbMultiByte = 24;
  52. static BYTE ar_HowAreYou_UTF8[] = "\xD9\x83\xD9\x8A\xD9\x81\x20\xD8\xAD\xD8\xA7\xD9\x84\xD9\x83\xD8"
  53. "\x9F\x00";
  54. static BYTE ar_HowAreYou_UTF16[] =
  55. "\x43\x06\x4A\x06\x41\x06\x20\x00\x2D\x06\x27\x06\x44\x06\x43\x06"
  56. "\x1F\x06\x00\x00";
  57. static int ar_HowAreYou_cchWideChar = 10;
  58. static int ar_HowAreYou_cbMultiByte = 18;
  59. /* Chinese */
  60. static BYTE ch_Hello_UTF8[] = "\xE4\xBD\xA0\xE5\xA5\xBD\x00";
  61. static BYTE ch_Hello_UTF16[] = "\x60\x4F\x7D\x59\x00\x00";
  62. static int ch_Hello_cchWideChar = 3;
  63. static int ch_Hello_cbMultiByte = 7;
  64. static BYTE ch_HowAreYou_UTF8[] = "\xE4\xBD\xA0\xE5\xA5\xBD\xE5\x90\x97\x00";
  65. static BYTE ch_HowAreYou_UTF16[] = "\x60\x4F\x7D\x59\x17\x54\x00\x00";
  66. static int ch_HowAreYou_cchWideChar = 4;
  67. static int ch_HowAreYou_cbMultiByte = 10;
  68. /* Uppercasing */
  69. static BYTE ru_Administrator_lower[] = "\xd0\x90\xd0\xb4\xd0\xbc\xd0\xb8\xd0\xbd\xd0\xb8\xd1\x81"
  70. "\xd1\x82\xd1\x80\xd0\xb0\xd1\x82\xd0\xbe\xd1\x80\x00";
  71. static BYTE ru_Administrator_upper[] = "\xd0\x90\xd0\x94\xd0\x9c\xd0\x98\xd0\x9d\xd0\x98\xd0\xa1"
  72. "\xd0\xa2\xd0\xa0\xd0\x90\xd0\xa2\xd0\x9e\xd0\xa0\x00";
  73. static void string_hexdump(const BYTE* data, size_t length)
  74. {
  75. const BYTE* p = data;
  76. size_t i, line, offset = 0;
  77. while (offset < length)
  78. {
  79. printf("%04" PRIxz " ", offset);
  80. line = length - offset;
  81. if (line > 16)
  82. line = 16;
  83. for (i = 0; i < line; i++)
  84. printf("%02" PRIx8 " ", p[i]);
  85. for (; i < 16; i++)
  86. printf(" ");
  87. for (i = 0; i < line; i++)
  88. printf("%c", (p[i] >= 0x20 && p[i] < 0x7F) ? (char)p[i] : '.');
  89. printf("\n");
  90. offset += line;
  91. p += line;
  92. }
  93. }
  94. static int convert_utf8_to_utf16(BYTE* lpMultiByteStr, BYTE* expected_lpWideCharStr,
  95. int expected_cchWideChar)
  96. {
  97. int rc = -1;
  98. int length;
  99. size_t cbMultiByte;
  100. int cchWideChar;
  101. LPWSTR lpWideCharStr = NULL;
  102. cbMultiByte = strlen((char*)lpMultiByteStr);
  103. cchWideChar = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)lpMultiByteStr, -1, NULL, 0);
  104. printf("MultiByteToWideChar Input UTF8 String:\n");
  105. string_hexdump(lpMultiByteStr, cbMultiByte + 1);
  106. printf("MultiByteToWideChar required cchWideChar: %d\n", cchWideChar);
  107. if (cchWideChar != expected_cchWideChar)
  108. {
  109. printf("MultiByteToWideChar unexpected cchWideChar: actual: %d expected: %d\n", cchWideChar,
  110. expected_cchWideChar);
  111. goto fail;
  112. }
  113. lpWideCharStr = (LPWSTR)calloc((size_t)cchWideChar, sizeof(WCHAR));
  114. if (!lpWideCharStr)
  115. {
  116. printf("MultiByteToWideChar: unable to allocate memory for test\n");
  117. goto fail;
  118. }
  119. lpWideCharStr[cchWideChar - 1] =
  120. 0xFFFF; /* should be overwritten if null terminator is inserted properly */
  121. length = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)lpMultiByteStr, cbMultiByte + 1, lpWideCharStr,
  122. cchWideChar);
  123. printf("MultiByteToWideChar converted length (WCHAR): %d\n", length);
  124. if (!length)
  125. {
  126. DWORD error = GetLastError();
  127. printf("MultiByteToWideChar error: 0x%08" PRIX32 "\n", error);
  128. goto fail;
  129. }
  130. if (length != expected_cchWideChar)
  131. {
  132. printf("MultiByteToWideChar unexpected converted length (WCHAR): actual: %d expected: %d\n",
  133. length, expected_cchWideChar);
  134. goto fail;
  135. }
  136. if (_wcscmp(lpWideCharStr, (WCHAR*)expected_lpWideCharStr) != 0)
  137. {
  138. printf("MultiByteToWideChar unexpected string:\n");
  139. printf("UTF8 String:\n");
  140. string_hexdump(lpMultiByteStr, cbMultiByte + 1);
  141. printf("UTF16 String (actual):\n");
  142. string_hexdump((BYTE*)lpWideCharStr, length * sizeof(WCHAR));
  143. printf("UTF16 String (expected):\n");
  144. string_hexdump((BYTE*)expected_lpWideCharStr, expected_cchWideChar * sizeof(WCHAR));
  145. goto fail;
  146. }
  147. printf("MultiByteToWideChar Output UTF16 String:\n");
  148. string_hexdump((BYTE*)lpWideCharStr, length * sizeof(WCHAR));
  149. printf("\n");
  150. rc = length;
  151. fail:
  152. free(lpWideCharStr);
  153. return rc;
  154. }
  155. static int convert_utf16_to_utf8(BYTE* lpWideCharStr, BYTE* expected_lpMultiByteStr,
  156. int expected_cbMultiByte)
  157. {
  158. int rc = -1;
  159. int length;
  160. int cchWideChar;
  161. int cbMultiByte;
  162. LPSTR lpMultiByteStr = NULL;
  163. cchWideChar = _wcslen((WCHAR*)lpWideCharStr);
  164. cbMultiByte = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)lpWideCharStr, -1, NULL, 0, NULL, NULL);
  165. printf("WideCharToMultiByte Input UTF16 String:\n");
  166. string_hexdump(lpWideCharStr, (cchWideChar + 1) * sizeof(WCHAR));
  167. printf("WideCharToMultiByte required cbMultiByte: %d\n", cbMultiByte);
  168. if (cbMultiByte != expected_cbMultiByte)
  169. {
  170. printf("WideCharToMultiByte unexpected cbMultiByte: actual: %d expected: %d\n", cbMultiByte,
  171. expected_cbMultiByte);
  172. goto fail;
  173. }
  174. lpMultiByteStr = (LPSTR)malloc(cbMultiByte);
  175. if (!lpMultiByteStr)
  176. {
  177. printf("WideCharToMultiByte: unable to allocate memory for test\n");
  178. goto fail;
  179. }
  180. lpMultiByteStr[cbMultiByte - 1] =
  181. (CHAR)0xFF; /* should be overwritten if null terminator is inserted properly */
  182. length = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)lpWideCharStr, cchWideChar + 1,
  183. lpMultiByteStr, cbMultiByte, NULL, NULL);
  184. printf("WideCharToMultiByte converted length (BYTE): %d\n", length);
  185. if (!length)
  186. {
  187. DWORD error = GetLastError();
  188. printf("WideCharToMultiByte error: 0x%08" PRIX32 "\n", error);
  189. goto fail;
  190. }
  191. if (length != expected_cbMultiByte)
  192. {
  193. printf("WideCharToMultiByte unexpected converted length (BYTE): actual: %d expected: %d\n",
  194. length, expected_cbMultiByte);
  195. goto fail;
  196. }
  197. if (strcmp(lpMultiByteStr, (char*)expected_lpMultiByteStr) != 0)
  198. {
  199. printf("WideCharToMultiByte unexpected string:\n");
  200. printf("UTF16 String:\n");
  201. string_hexdump((BYTE*)lpWideCharStr, (cchWideChar + 1) * sizeof(WCHAR));
  202. printf("UTF8 String (actual):\n");
  203. string_hexdump((BYTE*)lpMultiByteStr, cbMultiByte);
  204. printf("UTF8 String (expected):\n");
  205. string_hexdump((BYTE*)expected_lpMultiByteStr, expected_cbMultiByte);
  206. goto fail;
  207. }
  208. printf("WideCharToMultiByte Output UTF8 String:\n");
  209. string_hexdump((BYTE*)lpMultiByteStr, cbMultiByte);
  210. printf("\n");
  211. rc = length;
  212. fail:
  213. free(lpMultiByteStr);
  214. return rc;
  215. }
  216. static BOOL test_unicode_uppercasing(BYTE* lower, BYTE* upper)
  217. {
  218. WCHAR* lowerW = NULL;
  219. int lowerLength;
  220. WCHAR* upperW = NULL;
  221. int upperLength;
  222. lowerLength = ConvertToUnicode(CP_UTF8, 0, (LPSTR)lower, -1, &lowerW, 0);
  223. upperLength = ConvertToUnicode(CP_UTF8, 0, (LPSTR)upper, -1, &upperW, 0);
  224. CharUpperBuffW(lowerW, lowerLength);
  225. if (_wcscmp(lowerW, upperW) != 0)
  226. {
  227. printf("Lowercase String:\n");
  228. string_hexdump((BYTE*)lowerW, lowerLength * 2);
  229. printf("Uppercase String:\n");
  230. string_hexdump((BYTE*)upperW, upperLength * 2);
  231. return FALSE;
  232. }
  233. free(lowerW);
  234. free(upperW);
  235. printf("success\n\n");
  236. return TRUE;
  237. }
  238. static BOOL test_ConvertFromUnicode_wrapper(void)
  239. {
  240. const BYTE src1[] =
  241. "\x52\x00\x49\x00\x43\x00\x48\x00\x20\x00\x54\x00\x45\x00\x58\x00\x54\x00\x20\x00\x46\x00"
  242. "\x4f\x00\x52\x00\x4d\x00\x41\x00\x54\x00\x40\x00\x40\x00\x40\x00";
  243. const BYTE src2[] = "\x52\x00\x49\x00\x43\x00\x48\x00\x20\x00\x54\x00\x45\x00\x58\x00\x54\x00"
  244. "\x20\x00\x46\x00\x4f\x00\x52\x00\x4d\x00\x41\x00\x54\x00\x00\x00";
  245. /* 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 */
  246. const CHAR cmp0[] = { 'R', 'I', 'C', 'H', ' ', 'T', 'E', 'X', 'T',
  247. ' ', 'F', 'O', 'R', 'M', 'A', 'T', 0 };
  248. CHAR* dst = NULL;
  249. int i;
  250. /* Test unterminated unicode string:
  251. * ConvertFromUnicode must always null-terminate, even if the src string isn't
  252. */
  253. printf("Input UTF16 String:\n");
  254. string_hexdump((BYTE*)src1, 19 * sizeof(WCHAR));
  255. i = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)src1, 16, &dst, 0, NULL, NULL);
  256. if (i != 16)
  257. {
  258. fprintf(stderr, "ConvertFromUnicode failure A1: unexpectedly returned %d instead of 16\n",
  259. i);
  260. goto fail;
  261. }
  262. if (dst == NULL)
  263. {
  264. fprintf(stderr, "ConvertFromUnicode failure A2: destination ist NULL\n");
  265. goto fail;
  266. }
  267. if ((i = strlen(dst)) != 16)
  268. {
  269. fprintf(stderr, "ConvertFromUnicode failure A3: dst length is %d instead of 16\n", i);
  270. goto fail;
  271. }
  272. if (strcmp(dst, cmp0))
  273. {
  274. fprintf(stderr, "ConvertFromUnicode failure A4: data mismatch\n");
  275. goto fail;
  276. }
  277. printf("Output UTF8 String:\n");
  278. string_hexdump((BYTE*)dst, i + 1);
  279. free(dst);
  280. dst = NULL;
  281. /* Test null-terminated string */
  282. printf("Input UTF16 String:\n");
  283. string_hexdump((BYTE*)src2, (_wcslen((WCHAR*)src2) + 1) * sizeof(WCHAR));
  284. i = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*)src2, -1, &dst, 0, NULL, NULL);
  285. if (i != 17)
  286. {
  287. fprintf(stderr, "ConvertFromUnicode failure B1: unexpectedly returned %d instead of 17\n",
  288. i);
  289. goto fail;
  290. }
  291. if (dst == NULL)
  292. {
  293. fprintf(stderr, "ConvertFromUnicode failure B2: destination ist NULL\n");
  294. goto fail;
  295. }
  296. if ((i = strlen(dst)) != 16)
  297. {
  298. fprintf(stderr, "ConvertFromUnicode failure B3: dst length is %d instead of 16\n", i);
  299. goto fail;
  300. }
  301. if (strcmp(dst, cmp0))
  302. {
  303. fprintf(stderr, "ConvertFromUnicode failure B: data mismatch\n");
  304. goto fail;
  305. }
  306. printf("Output UTF8 String:\n");
  307. string_hexdump((BYTE*)dst, i + 1);
  308. free(dst);
  309. dst = NULL;
  310. printf("success\n\n");
  311. return TRUE;
  312. fail:
  313. free(dst);
  314. return FALSE;
  315. }
  316. static BOOL test_ConvertToUnicode_wrapper(void)
  317. {
  318. /* 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 */
  319. const CHAR src1[] = { 'R', 'I', 'C', 'H', ' ', 'T', 'E', 'X', 'T', ' ',
  320. 'F', 'O', 'R', 'M', 'A', 'T', '@', '@', '@' };
  321. const CHAR src2[] = { 'R', 'I', 'C', 'H', ' ', 'T', 'E', 'X', 'T',
  322. ' ', 'F', 'O', 'R', 'M', 'A', 'T', 0 };
  323. const BYTE cmp0[] = "\x52\x00\x49\x00\x43\x00\x48\x00\x20\x00\x54\x00\x45\x00\x58\x00\x54\x00"
  324. "\x20\x00\x46\x00\x4f\x00\x52\x00\x4d\x00\x41\x00\x54\x00\x00\x00";
  325. WCHAR* dst = NULL;
  326. int ii;
  327. size_t i;
  328. /* Test unterminated unicode string:
  329. * ConvertToUnicode must always null-terminate, even if the src string isn't
  330. */
  331. printf("Input UTF8 String:\n");
  332. string_hexdump((const BYTE*)src1, 19);
  333. ii = ConvertToUnicode(CP_UTF8, 0, src1, 16, &dst, 0);
  334. if (ii != 16)
  335. {
  336. fprintf(stderr, "ConvertToUnicode failure A1: unexpectedly returned %d instead of 16\n",
  337. ii);
  338. goto fail;
  339. }
  340. i = (size_t)ii;
  341. if (dst == NULL)
  342. {
  343. fprintf(stderr, "ConvertToUnicode failure A2: destination ist NULL\n");
  344. goto fail;
  345. }
  346. if ((i = _wcslen(dst)) != 16)
  347. {
  348. fprintf(stderr, "ConvertToUnicode failure A3: dst length is %d instead of 16\n", i);
  349. goto fail;
  350. }
  351. if (_wcscmp(dst, (const WCHAR*)cmp0))
  352. {
  353. fprintf(stderr, "ConvertToUnicode failure A4: data mismatch\n");
  354. goto fail;
  355. }
  356. printf("Output UTF16 String:\n");
  357. string_hexdump((const BYTE*)dst, (i + 1) * sizeof(WCHAR));
  358. free(dst);
  359. dst = NULL;
  360. /* Test null-terminated string */
  361. printf("Input UTF8 String:\n");
  362. string_hexdump((const BYTE*)src2, strlen(src2) + 1);
  363. i = ConvertToUnicode(CP_UTF8, 0, src2, -1, &dst, 0);
  364. if (i != 17)
  365. {
  366. fprintf(stderr, "ConvertToUnicode failure B1: unexpectedly returned %d instead of 17\n", i);
  367. goto fail;
  368. }
  369. if (dst == NULL)
  370. {
  371. fprintf(stderr, "ConvertToUnicode failure B2: destination ist NULL\n");
  372. goto fail;
  373. }
  374. if ((i = _wcslen(dst)) != 16)
  375. {
  376. fprintf(stderr, "ConvertToUnicode failure B3: dst length is %d instead of 16\n", i);
  377. goto fail;
  378. }
  379. if (_wcscmp(dst, (WCHAR*)cmp0))
  380. {
  381. fprintf(stderr, "ConvertToUnicode failure B: data mismatch\n");
  382. goto fail;
  383. }
  384. printf("Output UTF16 String:\n");
  385. string_hexdump((BYTE*)dst, (i + 1) * 2);
  386. free(dst);
  387. dst = NULL;
  388. printf("success\n\n");
  389. return TRUE;
  390. fail:
  391. free(dst);
  392. return FALSE;
  393. }
  394. int TestUnicodeConversion(int argc, char* argv[])
  395. {
  396. /* Letters */
  397. printf("Letters\n");
  398. if (convert_utf8_to_utf16(c_cedilla_UTF8, c_cedilla_UTF16, c_cedilla_cchWideChar) < 1)
  399. return -1;
  400. if (convert_utf16_to_utf8(c_cedilla_UTF16, c_cedilla_UTF8, c_cedilla_cbMultiByte) < 1)
  401. return -1;
  402. /* English */
  403. printf("English\n");
  404. if (convert_utf8_to_utf16(en_Hello_UTF8, en_Hello_UTF16, en_Hello_cchWideChar) < 1)
  405. return -1;
  406. if (convert_utf8_to_utf16(en_HowAreYou_UTF8, en_HowAreYou_UTF16, en_HowAreYou_cchWideChar) < 1)
  407. return -1;
  408. if (convert_utf16_to_utf8(en_Hello_UTF16, en_Hello_UTF8, en_Hello_cbMultiByte) < 1)
  409. return -1;
  410. if (convert_utf16_to_utf8(en_HowAreYou_UTF16, en_HowAreYou_UTF8, en_HowAreYou_cbMultiByte) < 1)
  411. return -1;
  412. /* French */
  413. printf("French\n");
  414. if (convert_utf8_to_utf16(fr_Hello_UTF8, fr_Hello_UTF16, fr_Hello_cchWideChar) < 1)
  415. return -1;
  416. if (convert_utf8_to_utf16(fr_HowAreYou_UTF8, fr_HowAreYou_UTF16, fr_HowAreYou_cchWideChar) < 1)
  417. return -1;
  418. if (convert_utf16_to_utf8(fr_Hello_UTF16, fr_Hello_UTF8, fr_Hello_cbMultiByte) < 1)
  419. return -1;
  420. if (convert_utf16_to_utf8(fr_HowAreYou_UTF16, fr_HowAreYou_UTF8, fr_HowAreYou_cbMultiByte) < 1)
  421. return -1;
  422. /* Russian */
  423. printf("Russian\n");
  424. if (convert_utf8_to_utf16(ru_Hello_UTF8, ru_Hello_UTF16, ru_Hello_cchWideChar) < 1)
  425. return -1;
  426. if (convert_utf8_to_utf16(ru_HowAreYou_UTF8, ru_HowAreYou_UTF16, ru_HowAreYou_cchWideChar) < 1)
  427. return -1;
  428. if (convert_utf16_to_utf8(ru_Hello_UTF16, ru_Hello_UTF8, ru_Hello_cbMultiByte) < 1)
  429. return -1;
  430. if (convert_utf16_to_utf8(ru_HowAreYou_UTF16, ru_HowAreYou_UTF8, ru_HowAreYou_cbMultiByte) < 1)
  431. return -1;
  432. /* Arabic */
  433. printf("Arabic\n");
  434. if (convert_utf8_to_utf16(ar_Hello_UTF8, ar_Hello_UTF16, ar_Hello_cchWideChar) < 1)
  435. return -1;
  436. if (convert_utf8_to_utf16(ar_HowAreYou_UTF8, ar_HowAreYou_UTF16, ar_HowAreYou_cchWideChar) < 1)
  437. return -1;
  438. if (convert_utf16_to_utf8(ar_Hello_UTF16, ar_Hello_UTF8, ar_Hello_cbMultiByte) < 1)
  439. return -1;
  440. if (convert_utf16_to_utf8(ar_HowAreYou_UTF16, ar_HowAreYou_UTF8, ar_HowAreYou_cbMultiByte) < 1)
  441. return -1;
  442. /* Chinese */
  443. printf("Chinese\n");
  444. if (convert_utf8_to_utf16(ch_Hello_UTF8, ch_Hello_UTF16, ch_Hello_cchWideChar) < 1)
  445. return -1;
  446. if (convert_utf8_to_utf16(ch_HowAreYou_UTF8, ch_HowAreYou_UTF16, ch_HowAreYou_cchWideChar) < 1)
  447. return -1;
  448. if (convert_utf16_to_utf8(ch_Hello_UTF16, ch_Hello_UTF8, ch_Hello_cbMultiByte) < 1)
  449. return -1;
  450. if (convert_utf16_to_utf8(ch_HowAreYou_UTF16, ch_HowAreYou_UTF8, ch_HowAreYou_cbMultiByte) < 1)
  451. return -1;
  452. /* Uppercasing */
  453. printf("Uppercasing\n");
  454. if (!test_unicode_uppercasing(ru_Administrator_lower, ru_Administrator_upper))
  455. return -1;
  456. /* ConvertFromUnicode */
  457. printf("ConvertFromUnicode\n");
  458. if (!test_ConvertFromUnicode_wrapper())
  459. return -1;
  460. /* ConvertToUnicode */
  461. printf("ConvertToUnicode\n");
  462. if (!test_ConvertToUnicode_wrapper())
  463. return -1;
  464. /*
  465. printf("----------------------------------------------------------\n\n");
  466. if (0)
  467. {
  468. BYTE src[] = { 'R',0,'I',0,'C',0,'H',0,' ',0, 'T',0,'E',0,'X',0,'T',0,'
  469. ',0,'F',0,'O',0,'R',0,'M',0,'A',0,'T',0,'@',0,'@',0 };
  470. //BYTE src[] = { 'R',0,'I',0,'C',0,'H',0,' ',0, 0,0, 'T',0,'E',0,'X',0,'T',0,'
  471. ',0,'F',0,'O',0,'R',0,'M',0,'A',0,'T',0,'@',0,'@',0 };
  472. //BYTE src[] = { 0,0,'R',0,'I',0,'C',0,'H',0,' ',0, 'T',0,'E',0,'X',0,'T',0,'
  473. ',0,'F',0,'O',0,'R',0,'M',0,'A',0,'T',0,'@',0,'@',0 }; char* dst = NULL; int num; num =
  474. ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) src, 16, &dst, 0, NULL, NULL);
  475. printf("ConvertFromUnicode returned %d dst=[%s]\n", num, dst);
  476. string_hexdump((BYTE*)dst, num+1);
  477. }
  478. if (1)
  479. {
  480. char src[] = "RICH TEXT FORMAT@@@@@@";
  481. WCHAR *dst = NULL;
  482. int num;
  483. num = ConvertToUnicode(CP_UTF8, 0, src, 16, &dst, 0);
  484. printf("ConvertToUnicode returned %d dst=%p\n", num, (void*) dst);
  485. string_hexdump((BYTE*)dst, num * 2 + 2);
  486. }
  487. */
  488. return 0;
  489. }