]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/cintltst/ccapitst.c
ICU-531.48.tar.gz
[apple/icu.git] / icuSources / test / cintltst / ccapitst.c
CommitLineData
b75a7d8f
A
1/********************************************************************
2 * COPYRIGHT:
57a6839d 3 * Copyright (c) 1997-2014, International Business Machines Corporation and
b75a7d8f
A
4 * others. All Rights Reserved.
5 ********************************************************************/
46f4442e 6/*****************************************************************************
b75a7d8f
A
7*
8* File CU_CAPITST.C
9*
10* Modification History:
11* Name Description
12* Madhu Katragadda Ported for C API
46f4442e 13******************************************************************************
b75a7d8f
A
14*/
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <ctype.h>
19#include "unicode/uloc.h"
20#include "unicode/ucnv.h"
21#include "unicode/ucnv_err.h"
374ca955 22#include "unicode/putil.h"
46f4442e 23#include "unicode/uset.h"
b75a7d8f 24#include "unicode/ustring.h"
374ca955 25#include "ucnv_bld.h" /* for sizeof(UConverter) */
73c04bcf 26#include "cmemory.h" /* for UAlignedMemory */
b75a7d8f
A
27#include "cintltst.h"
28#include "ccapitst.h"
4388f060 29#include "cstring.h"
b75a7d8f
A
30
31#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
32
33#define NUM_CODEPAGE 1
34#define MAX_FILE_LEN 1024*20
35#define UCS_FILE_NAME_SIZE 512
36
37/*returns an action other than the one provided*/
51004dcb 38#if !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
39static UConverterFromUCallback otherUnicodeAction(UConverterFromUCallback MIA);
40static UConverterToUCallback otherCharAction(UConverterToUCallback MIA);
51004dcb 41#endif
b75a7d8f 42
374ca955
A
43static UConverter *
44cnv_open(const char *name, UErrorCode *pErrorCode) {
45 if(name!=NULL && name[0]=='*') {
46 return ucnv_openPackage(loadTestData(pErrorCode), name+1, pErrorCode);
47 } else {
48 return ucnv_open(name, pErrorCode);
49 }
50}
51
b75a7d8f
A
52
53static void ListNames(void);
374ca955 54static void TestFlushCache(void);
b75a7d8f
A
55static void TestDuplicateAlias(void);
56static void TestCCSID(void);
57static void TestJ932(void);
58static void TestJ1968(void);
51004dcb 59#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f 60static void TestLMBCSMaxChar(void);
51004dcb 61#endif
73c04bcf
A
62
63#if !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f 64static void TestConvertSafeCloneCallback(void);
73c04bcf
A
65#endif
66
b75a7d8f
A
67static void TestEBCDICSwapLFNL(void);
68static void TestConvertEx(void);
46f4442e 69static void TestConvertExFromUTF8(void);
729e4ab9 70static void TestConvertExFromUTF8_C5F0(void);
b75a7d8f 71static void TestConvertAlgorithmic(void);
374ca955 72 void TestDefaultConverterError(void); /* defined in cctest.c */
729e4ab9 73 void TestDefaultConverterSet(void); /* defined in cctest.c */
73c04bcf
A
74static void TestToUCountPending(void);
75static void TestFromUCountPending(void);
76static void TestDefaultName(void);
77static void TestCompareNames(void);
78static void TestSubstString(void);
46f4442e 79static void InvalidArguments(void);
729e4ab9
A
80static void TestGetName(void);
81static void TestUTFBOM(void);
b75a7d8f
A
82
83void addTestConvert(TestNode** root);
84
85void addTestConvert(TestNode** root)
86{
87 addTest(root, &ListNames, "tsconv/ccapitst/ListNames");
88 addTest(root, &TestConvert, "tsconv/ccapitst/TestConvert");
89 addTest(root, &TestFlushCache, "tsconv/ccapitst/TestFlushCache");
90 addTest(root, &TestAlias, "tsconv/ccapitst/TestAlias");
91 addTest(root, &TestDuplicateAlias, "tsconv/ccapitst/TestDuplicateAlias");
73c04bcf 92 addTest(root, &TestConvertSafeClone, "tsconv/ccapitst/TestConvertSafeClone");
73c04bcf
A
93#if !UCONFIG_NO_LEGACY_CONVERSION
94 addTest(root, &TestConvertSafeCloneCallback,"tsconv/ccapitst/TestConvertSafeCloneCallback");
95#endif
b75a7d8f
A
96 addTest(root, &TestCCSID, "tsconv/ccapitst/TestCCSID");
97 addTest(root, &TestJ932, "tsconv/ccapitst/TestJ932");
98 addTest(root, &TestJ1968, "tsconv/ccapitst/TestJ1968");
729e4ab9 99#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f 100 addTest(root, &TestLMBCSMaxChar, "tsconv/ccapitst/TestLMBCSMaxChar");
729e4ab9 101#endif
b75a7d8f
A
102 addTest(root, &TestEBCDICSwapLFNL, "tsconv/ccapitst/TestEBCDICSwapLFNL");
103 addTest(root, &TestConvertEx, "tsconv/ccapitst/TestConvertEx");
46f4442e 104 addTest(root, &TestConvertExFromUTF8, "tsconv/ccapitst/TestConvertExFromUTF8");
729e4ab9 105 addTest(root, &TestConvertExFromUTF8_C5F0, "tsconv/ccapitst/TestConvertExFromUTF8_C5F0");
b75a7d8f 106 addTest(root, &TestConvertAlgorithmic, "tsconv/ccapitst/TestConvertAlgorithmic");
374ca955 107 addTest(root, &TestDefaultConverterError, "tsconv/ccapitst/TestDefaultConverterError");
729e4ab9
A
108 addTest(root, &TestDefaultConverterSet, "tsconv/ccapitst/TestDefaultConverterSet");
109#if !UCONFIG_NO_FILE_IO
73c04bcf
A
110 addTest(root, &TestToUCountPending, "tsconv/ccapitst/TestToUCountPending");
111 addTest(root, &TestFromUCountPending, "tsconv/ccapitst/TestFromUCountPending");
729e4ab9 112#endif
73c04bcf
A
113 addTest(root, &TestDefaultName, "tsconv/ccapitst/TestDefaultName");
114 addTest(root, &TestCompareNames, "tsconv/ccapitst/TestCompareNames");
115 addTest(root, &TestSubstString, "tsconv/ccapitst/TestSubstString");
46f4442e 116 addTest(root, &InvalidArguments, "tsconv/ccapitst/InvalidArguments");
729e4ab9
A
117 addTest(root, &TestGetName, "tsconv/ccapitst/TestGetName");
118 addTest(root, &TestUTFBOM, "tsconv/ccapitst/TestUTFBOM");
b75a7d8f
A
119}
120
121static void ListNames(void) {
122 UErrorCode err = U_ZERO_ERROR;
123 int32_t testLong1 = 0;
124 const char* available_conv;
125 UEnumeration *allNamesEnum = NULL;
126 int32_t allNamesCount = 0;
127 uint16_t count;
128
129 log_verbose("Testing ucnv_openAllNames()...");
130 allNamesEnum = ucnv_openAllNames(&err);
131 if(U_FAILURE(err)) {
729e4ab9 132 log_data_err("FAILURE! ucnv_openAllNames() -> %s\n", myErrorName(err));
b75a7d8f
A
133 }
134 else {
135 const char *string = NULL;
136 int32_t len = 0;
137 int32_t count1 = 0;
138 int32_t count2 = 0;
139 allNamesCount = uenum_count(allNamesEnum, &err);
140 while ((string = uenum_next(allNamesEnum, &len, &err))) {
141 count1++;
142 log_verbose("read \"%s\", length %i\n", string, len);
143 }
73c04bcf
A
144 if (U_FAILURE(err)) {
145 log_err("FAILURE! uenum_next(allNamesEnum...) set an error: %s\n", u_errorName(err));
146 err = U_ZERO_ERROR;
147 }
b75a7d8f
A
148 uenum_reset(allNamesEnum, &err);
149 while ((string = uenum_next(allNamesEnum, &len, &err))) {
150 count2++;
151 ucnv_close(ucnv_open(string, &err));
152 log_verbose("read \"%s\", length %i (%s)\n", string, len, U_SUCCESS(err) ? "available" : "unavailable");
153 err = U_ZERO_ERROR;
154 }
155 if (count1 != count2) {
156 log_err("FAILURE! uenum_reset(allNamesEnum, &err); doesn't work\n");
157 }
158 }
159 uenum_close(allNamesEnum);
160 err = U_ZERO_ERROR;
161
162 /*Tests ucnv_getAvailableName(), getAvialableCount()*/
163
164 log_verbose("Testing ucnv_countAvailable()...");
165
166 testLong1=ucnv_countAvailable();
167 log_info("Number of available codepages: %d/%d\n", testLong1, allNamesCount);
168
169 log_verbose("\n---Testing ucnv_getAvailableName.."); /*need to check this out */
170
171 available_conv = ucnv_getAvailableName(testLong1);
172 /*test ucnv_getAvailableName with err condition*/
173 log_verbose("\n---Testing ucnv_getAvailableName..with index < 0 ");
174 available_conv = ucnv_getAvailableName(-1);
175 if(available_conv != NULL){
176 log_err("ucnv_getAvailableName() with index < 0) should return NULL\n");
177 }
178
179 /* Test ucnv_countAliases() etc. */
180 count = ucnv_countAliases("utf-8", &err);
181 if(U_FAILURE(err)) {
729e4ab9 182 log_data_err("FAILURE! ucnv_countAliases(\"utf-8\") -> %s\n", myErrorName(err));
b75a7d8f
A
183 } else if(count <= 0) {
184 log_err("FAILURE! ucnv_countAliases(\"utf-8\") -> %d aliases\n", count);
185 } else {
186 /* try to get the aliases individually */
187 const char *alias;
188 alias = ucnv_getAlias("utf-8", 0, &err);
189 if(U_FAILURE(err)) {
190 log_err("FAILURE! ucnv_getAlias(\"utf-8\", 0) -> %s\n", myErrorName(err));
191 } else if(strcmp("UTF-8", alias) != 0) {
192 log_err("FAILURE! ucnv_getAlias(\"utf-8\", 0) -> %s instead of UTF-8\n", alias);
193 } else {
194 uint16_t aliasNum;
195 for(aliasNum = 0; aliasNum < count; ++aliasNum) {
196 alias = ucnv_getAlias("utf-8", aliasNum, &err);
197 if(U_FAILURE(err)) {
198 log_err("FAILURE! ucnv_getAlias(\"utf-8\", %d) -> %s\n", aliasNum, myErrorName(err));
199 } else if(strlen(alias) > 20) {
200 /* sanity check */
201 log_err("FAILURE! ucnv_getAlias(\"utf-8\", %d) -> alias %s insanely long, corrupt?!\n", aliasNum, alias);
202 } else {
203 log_verbose("alias %d for utf-8: %s\n", aliasNum, alias);
204 }
205 }
206 if(U_SUCCESS(err)) {
207 /* try to fill an array with all aliases */
208 const char **aliases;
209 aliases=(const char **)malloc(count * sizeof(const char *));
210 if(aliases != 0) {
211 ucnv_getAliases("utf-8", aliases, &err);
212 if(U_FAILURE(err)) {
213 log_err("FAILURE! ucnv_getAliases(\"utf-8\") -> %s\n", myErrorName(err));
214 } else {
215 for(aliasNum = 0; aliasNum < count; ++aliasNum) {
216 /* compare the pointers with the ones returned individually */
217 alias = ucnv_getAlias("utf-8", aliasNum, &err);
218 if(U_FAILURE(err)) {
219 log_err("FAILURE! ucnv_getAlias(\"utf-8\", %d) -> %s\n", aliasNum, myErrorName(err));
220 } else if(aliases[aliasNum] != alias) {
221 log_err("FAILURE! ucnv_getAliases(\"utf-8\")[%d] != ucnv_getAlias(\"utf-8\", %d)\n", aliasNum, aliasNum);
222 }
223 }
224 }
225 free((char **)aliases);
226 }
227 }
228 }
229 }
230}
231
232
233static void TestConvert()
234{
73c04bcf 235#if !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
236 char myptr[4];
237 char save[4];
238 int32_t testLong1 = 0;
239 uint16_t rest = 0;
240 int32_t len = 0;
241 int32_t x = 0;
242 FILE* ucs_file_in = NULL;
243 UChar BOM = 0x0000;
244 UChar myUChar = 0x0000;
245 char* mytarget; /* [MAX_FILE_LEN] */
246 char* mytarget_1;
247 char* mytarget_use;
248 UChar* consumedUni = NULL;
249 char* consumed = NULL;
250 char* output_cp_buffer; /* [MAX_FILE_LEN] */
251 UChar* ucs_file_buffer; /* [MAX_FILE_LEN] */
252 UChar* ucs_file_buffer_use;
253 UChar* my_ucs_file_buffer; /* [MAX_FILE_LEN] */
254 UChar* my_ucs_file_buffer_1;
255 int8_t ii = 0;
b75a7d8f
A
256 uint16_t codepage_index = 0;
257 int32_t cp = 0;
258 UErrorCode err = U_ZERO_ERROR;
259 char ucs_file_name[UCS_FILE_NAME_SIZE];
260 UConverterFromUCallback MIA1, MIA1_2;
261 UConverterToUCallback MIA2, MIA2_2;
262 const void *MIA1Context, *MIA1Context2, *MIA2Context, *MIA2Context2;
263 UConverter* someConverters[5];
264 UConverter* myConverter = 0;
265 UChar* displayname = 0;
266
267 const char* locale;
268
269 UChar* uchar1 = 0;
270 UChar* uchar2 = 0;
271 UChar* uchar3 = 0;
272 int32_t targetcapacity2;
273 int32_t targetcapacity;
274 int32_t targetsize;
275 int32_t disnamelen;
276
277 const UChar* tmp_ucs_buf;
278 const UChar* tmp_consumedUni=NULL;
279 const char* tmp_mytarget_use;
280 const char* tmp_consumed;
281
282 /******************************************************************
283 Checking Unicode -> ksc
284 ******************************************************************/
285
286 const char* CodePagesToTest[NUM_CODEPAGE] =
287 {
288 "ibm-949_P110-1999"
289
290
291 };
292 const uint16_t CodePageNumberToTest[NUM_CODEPAGE] =
293 {
294 949
295 };
296
297
298 const int8_t CodePagesMinChars[NUM_CODEPAGE] =
299 {
300 1
301
302 };
303
304 const int8_t CodePagesMaxChars[NUM_CODEPAGE] =
305 {
306 2
307
308 };
309
310 const uint16_t CodePagesSubstitutionChars[NUM_CODEPAGE] =
311 {
312 0xAFFE
313 };
314
315 const char* CodePagesTestFiles[NUM_CODEPAGE] =
316 {
317 "uni-text.bin"
318 };
319
320
321 const UConverterPlatform CodePagesPlatform[NUM_CODEPAGE] =
322 {
323 UCNV_IBM
324
325 };
326
327 const char* CodePagesLocale[NUM_CODEPAGE] =
328 {
329 "ko_KR"
330 };
331
332 UConverterFromUCallback oldFromUAction = NULL;
333 UConverterToUCallback oldToUAction = NULL;
334 const void* oldFromUContext = NULL;
335 const void* oldToUContext = NULL;
336
337 /* Allocate memory */
338 mytarget = (char*) malloc(MAX_FILE_LEN * sizeof(mytarget[0]));
339 output_cp_buffer = (char*) malloc(MAX_FILE_LEN * sizeof(output_cp_buffer[0]));
340 ucs_file_buffer = (UChar*) malloc(MAX_FILE_LEN * sizeof(ucs_file_buffer[0]));
341 my_ucs_file_buffer = (UChar*) malloc(MAX_FILE_LEN * sizeof(my_ucs_file_buffer[0]));
342
343 ucs_file_buffer_use = ucs_file_buffer;
344 mytarget_1=mytarget;
345 mytarget_use = mytarget;
346 my_ucs_file_buffer_1=my_ucs_file_buffer;
347
348 /* flush the converter cache to get a consistent state before the flushing is tested */
349 ucnv_flushCache();
350
351 /*Testing ucnv_openU()*/
352 {
353 UChar converterName[]={ 0x0069, 0x0062, 0x006d, 0x002d, 0x0039, 0x0034, 0x0033, 0x0000}; /*ibm-943*/
354 UChar firstSortedName[]={ 0x0021, 0x0000}; /* ! */
355 UChar lastSortedName[]={ 0x007E, 0x0000}; /* ~ */
356 const char *illegalNameChars={ "ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943 ibm-943"};
357 UChar illegalName[100];
358 UConverter *converter=NULL;
359 err=U_ZERO_ERROR;
360 converter=ucnv_openU(converterName, &err);
361 if(U_FAILURE(err)){
362 log_data_err("FAILURE! ucnv_openU(ibm-943, err) failed. %s\n", myErrorName(err));
363 }
364 ucnv_close(converter);
365 err=U_ZERO_ERROR;
366 converter=ucnv_openU(NULL, &err);
367 if(U_FAILURE(err)){
368 log_err("FAILURE! ucnv_openU(NULL, err) failed. %s\n", myErrorName(err));
369 }
370 ucnv_close(converter);
371 /*testing with error value*/
372 err=U_ILLEGAL_ARGUMENT_ERROR;
373 converter=ucnv_openU(converterName, &err);
374 if(!(converter == NULL)){
375 log_data_err("FAILURE! ucnv_openU(ibm-943, U_ILLEGAL_ARGUMENT_ERROR) is expected to fail\n");
376 }
377 ucnv_close(converter);
378 err=U_ZERO_ERROR;
379 u_uastrcpy(illegalName, "");
380 u_uastrcpy(illegalName, illegalNameChars);
381 ucnv_openU(illegalName, &err);
382 if(!(err==U_ILLEGAL_ARGUMENT_ERROR)){
383 log_err("FAILURE! ucnv_openU(illegalName, err) is expected to fail\n");
384 }
385
386 err=U_ZERO_ERROR;
387 ucnv_openU(firstSortedName, &err);
388 if(err!=U_FILE_ACCESS_ERROR){
389 log_err("FAILURE! ucnv_openU(firstSortedName, err) is expected to fail\n");
390 }
391
392 err=U_ZERO_ERROR;
393 ucnv_openU(lastSortedName, &err);
394 if(err!=U_FILE_ACCESS_ERROR){
395 log_err("FAILURE! ucnv_openU(lastSortedName, err) is expected to fail\n");
396 }
397
398 err=U_ZERO_ERROR;
399 }
400 log_verbose("Testing ucnv_open() with converter name greater than 7 characters\n");
401 {
402 UConverter *cnv=NULL;
403 err=U_ZERO_ERROR;
404 cnv=ucnv_open("ibm-949,Madhu", &err);
405 if(U_FAILURE(err)){
406 log_data_err("FAILURE! ucnv_open(\"ibm-949,Madhu\", err) failed. %s\n", myErrorName(err));
407 }
408 ucnv_close(cnv);
409
410 }
411 /*Testing ucnv_convert()*/
412 {
413 int32_t targetLimit=0, sourceLimit=0, i=0, targetCapacity=0;
414 const uint8_t source[]={ 0x00, 0x04, 0x05, 0x06, 0xa2, 0xb4, 0x00};
415 const uint8_t expectedTarget[]={ 0x00, 0x37, 0x2d, 0x2e, 0x0e, 0x49, 0x62, 0x0f, 0x00};
416 char *target=0;
417 sourceLimit=sizeof(source)/sizeof(source[0]);
418 err=U_ZERO_ERROR;
419 targetLimit=0;
420
421 targetCapacity=ucnv_convert("ibm-1364", "ibm-1363", NULL, targetLimit , (const char*)source, sourceLimit, &err);
422 if(err == U_BUFFER_OVERFLOW_ERROR){
423 err=U_ZERO_ERROR;
424 targetLimit=targetCapacity+1;
425 target=(char*)malloc(sizeof(char) * targetLimit);
426 targetCapacity=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source, sourceLimit, &err);
427 }
428 if(U_FAILURE(err)){
429 log_data_err("FAILURE! ucnv_convert(ibm-1363->ibm-1364) failed. %s\n", myErrorName(err));
430 }
431 else {
432 for(i=0; i<targetCapacity; i++){
433 if(target[i] != expectedTarget[i]){
434 log_err("FAIL: ucnv_convert(ibm-1363->ibm-1364) failed.at index \n i=%d, Expected: %lx Got: %lx\n", i, (UChar)expectedTarget[i], (uint8_t)target[i]);
435 }
436 }
437
438 i=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source+1, -1, &err);
439 if(U_FAILURE(err) || i!=7){
440 log_err("FAILURE! ucnv_convert() with sourceLimit=-1 failed: %s, returned %d instead of 7\n",
441 u_errorName(err), i);
442 }
443
444 /*Test error conditions*/
445 err=U_ZERO_ERROR;
446 i=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source, 0, &err);
447 if(i !=0){
448 log_err("FAILURE! ucnv_convert() with sourceLimit=0 is expected to return 0\n");
449 }
450
451 err=U_ILLEGAL_ARGUMENT_ERROR;
452 sourceLimit=sizeof(source)/sizeof(source[0]);
453 i=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source, sourceLimit, &err);
454 if(i !=0 ){
455 log_err("FAILURE! ucnv_convert() with err=U_ILLEGAL_ARGUMENT_ERROR is expected to return 0\n");
456 }
457
458 err=U_ZERO_ERROR;
459 sourceLimit=sizeof(source)/sizeof(source[0]);
460 targetLimit=0;
461 i=ucnv_convert("ibm-1364", "ibm-1363", target, targetLimit , (const char*)source, sourceLimit, &err);
462 if(!(U_FAILURE(err) && err==U_BUFFER_OVERFLOW_ERROR)){
463 log_err("FAILURE! ucnv_convert() with targetLimit=0 is expected to throw U_BUFFER_OVERFLOW_ERROR\n");
464 }
465 err=U_ZERO_ERROR;
466 free(target);
467 }
468 }
469
470 /*Testing ucnv_openCCSID and ucnv_open with error conditions*/
471 log_verbose("\n---Testing ucnv_open with err ! = U_ZERO_ERROR...\n");
472 err=U_ILLEGAL_ARGUMENT_ERROR;
473 if(ucnv_open(NULL, &err) != NULL){
474 log_err("ucnv_open with err != U_ZERO_ERROR is supposed to fail\n");
475 }
476 if(ucnv_openCCSID(1051, UCNV_IBM, &err) != NULL){
477 log_err("ucnv_open with err != U_ZERO_ERROR is supposed to fail\n");
478 }
479 err=U_ZERO_ERROR;
480
481 /* Testing ucnv_openCCSID(), ucnv_open(), ucnv_getName() */
482 log_verbose("\n---Testing ucnv_open default...\n");
483 someConverters[0] = ucnv_open(NULL,&err);
484 someConverters[1] = ucnv_open(NULL,&err);
485 someConverters[2] = ucnv_open("utf8", &err);
486 someConverters[3] = ucnv_openCCSID(949,UCNV_IBM,&err);
487 ucnv_close(ucnv_openCCSID(1051, UCNV_IBM, &err)); /* test for j350; ucnv_close(NULL) is safe */
488 if (U_FAILURE(err)){ log_data_err("FAILURE! %s\n", myErrorName(err));}
489
490 /* Testing ucnv_getName()*/
491 /*default code page */
492 ucnv_getName(someConverters[0], &err);
493 if(U_FAILURE(err)) {
494 log_data_err("getName[0] failed\n");
495 } else {
496 log_verbose("getName(someConverters[0]) returned %s\n", ucnv_getName(someConverters[0], &err));
497 }
498 ucnv_getName(someConverters[1], &err);
499 if(U_FAILURE(err)) {
500 log_data_err("getName[1] failed\n");
501 } else {
502 log_verbose("getName(someConverters[1]) returned %s\n", ucnv_getName(someConverters[1], &err));
503 }
504
b75a7d8f
A
505 ucnv_close(someConverters[0]);
506 ucnv_close(someConverters[1]);
507 ucnv_close(someConverters[2]);
508 ucnv_close(someConverters[3]);
509
510
511 for (codepage_index=0; codepage_index < NUM_CODEPAGE; ++codepage_index)
512 {
513 int32_t i = 0;
b75a7d8f
A
514
515 err = U_ZERO_ERROR;
374ca955
A
516#ifdef U_TOPSRCDIR
517 strcpy(ucs_file_name, U_TOPSRCDIR U_FILE_SEP_STRING"test"U_FILE_SEP_STRING"testdata"U_FILE_SEP_STRING);
518#else
b75a7d8f
A
519 strcpy(ucs_file_name, loadTestData(&err));
520
521 if(U_FAILURE(err)){
522 log_err("\nCouldn't get the test data directory... Exiting...Error:%s\n", u_errorName(err));
523 return;
524 }
525
374ca955
A
526 {
527 char* index = strrchr(ucs_file_name,(char)U_FILE_SEP_CHAR);
b75a7d8f 528
374ca955
A
529 if((unsigned int)(index-ucs_file_name) != (strlen(ucs_file_name)-1)){
530 *(index+1)=0;
531 }
b75a7d8f
A
532 }
533
534 strcat(ucs_file_name,".."U_FILE_SEP_STRING);
374ca955 535#endif
b75a7d8f
A
536 strcat(ucs_file_name, CodePagesTestFiles[codepage_index]);
537
538 ucs_file_in = fopen(ucs_file_name,"rb");
539 if (!ucs_file_in)
540 {
46f4442e 541 log_data_err("Couldn't open the Unicode file [%s]... Exiting...\n", ucs_file_name);
b75a7d8f
A
542 return;
543 }
544
545 /*Creates a converter and testing ucnv_openCCSID(u_int code_page, platform, errstatus*/
546
547 /* myConverter =ucnv_openCCSID(CodePageNumberToTest[codepage_index],UCNV_IBM, &err); */
548 /* ucnv_flushCache(); */
549 myConverter =ucnv_open( "ibm-949", &err);
550 if (!myConverter || U_FAILURE(err))
551 {
552 log_data_err("Error creating the ibm-949 converter - %s \n", u_errorName(err));
4388f060
A
553 fclose(ucs_file_in);
554 break;
b75a7d8f
A
555 }
556
557 /*testing for ucnv_getName() */
558 log_verbose("Testing ucnv_getName()...\n");
559 ucnv_getName(myConverter, &err);
560 if(U_FAILURE(err))
561 log_err("Error in getName\n");
562 else
563 {
564 log_verbose("getName o.k. %s\n", ucnv_getName(myConverter, &err));
565 }
4388f060 566 if (uprv_stricmp(ucnv_getName(myConverter, &err), CodePagesToTest[codepage_index]))
b75a7d8f
A
567 log_err("getName failed\n");
568 else
569 log_verbose("getName ok\n");
570 /*Test getName with error condition*/
571 {
572 const char* name=0;
573 err=U_ILLEGAL_ARGUMENT_ERROR;
574 log_verbose("Testing ucnv_getName with err != U_ZERO_ERROR");
575 name=ucnv_getName(myConverter, &err);
576 if(name != NULL){
577 log_err("ucnv_getName() with err != U_ZERO_ERROR is expected to fail");
578 }
579 err=U_ZERO_ERROR;
580 }
581
582
583 /*Tests ucnv_getMaxCharSize() and ucnv_getMinCharSize()*/
584
585 log_verbose("Testing ucnv_getMaxCharSize()...\n");
586 if (ucnv_getMaxCharSize(myConverter)==CodePagesMaxChars[codepage_index])
587 log_verbose("Max byte per character OK\n");
588 else
589 log_err("Max byte per character failed\n");
590
591 log_verbose("\n---Testing ucnv_getMinCharSize()...\n");
592 if (ucnv_getMinCharSize(myConverter)==CodePagesMinChars[codepage_index])
593 log_verbose("Min byte per character OK\n");
594 else
595 log_err("Min byte per character failed\n");
596
597
598 /*Testing for ucnv_getSubstChars() and ucnv_setSubstChars()*/
599 log_verbose("\n---Testing ucnv_getSubstChars...\n");
600 ii=4;
601 ucnv_getSubstChars(myConverter, myptr, &ii, &err);
374ca955
A
602 if (ii <= 0) {
603 log_err("ucnv_getSubstChars returned a negative number %d\n", ii);
604 }
b75a7d8f
A
605
606 for(x=0;x<ii;x++)
607 rest = (uint16_t)(((unsigned char)rest << 8) + (unsigned char)myptr[x]);
608 if (rest==CodePagesSubstitutionChars[codepage_index])
609 log_verbose("Substitution character ok\n");
610 else
611 log_err("Substitution character failed.\n");
612
613 log_verbose("\n---Testing ucnv_setSubstChars RoundTrip Test ...\n");
614 ucnv_setSubstChars(myConverter, myptr, ii, &err);
615 if (U_FAILURE(err))
616 {
617 log_err("FAILURE! %s\n", myErrorName(err));
618 }
619 ucnv_getSubstChars(myConverter,save, &ii, &err);
620 if (U_FAILURE(err))
621 {
622 log_err("FAILURE! %s\n", myErrorName(err));
623 }
624
625 if (strncmp(save, myptr, ii))
626 log_err("Saved substitution character failed\n");
627 else
628 log_verbose("Saved substitution character ok\n");
629
630 /*Testing for ucnv_getSubstChars() and ucnv_setSubstChars() with error conditions*/
631 log_verbose("\n---Testing ucnv_getSubstChars.. with len < minBytesPerChar\n");
632 ii=1;
633 ucnv_getSubstChars(myConverter, myptr, &ii, &err);
634 if(err != U_INDEX_OUTOFBOUNDS_ERROR){
635 log_err("ucnv_getSubstChars() with len < minBytesPerChar should throw U_INDEX_OUTOFBOUNDS_ERROR Got %s\n", myErrorName(err));
636 }
637 err=U_ZERO_ERROR;
638 ii=4;
639 ucnv_getSubstChars(myConverter, myptr, &ii, &err);
640 log_verbose("\n---Testing ucnv_setSubstChars.. with len < minBytesPerChar\n");
641 ucnv_setSubstChars(myConverter, myptr, 0, &err);
642 if(err != U_ILLEGAL_ARGUMENT_ERROR){
643 log_err("ucnv_setSubstChars() with len < minBytesPerChar should throw U_ILLEGAL_ARGUMENT_ERROR Got %s\n", myErrorName(err));
644 }
645 log_verbose("\n---Testing ucnv_setSubstChars.. with err != U_ZERO_ERROR \n");
646 strcpy(myptr, "abc");
647 ucnv_setSubstChars(myConverter, myptr, ii, &err);
648 err=U_ZERO_ERROR;
649 ucnv_getSubstChars(myConverter, save, &ii, &err);
650 if(strncmp(save, myptr, ii) == 0){
651 log_err("uncv_setSubstChars() with err != U_ZERO_ERROR shouldn't set the SubstChars and just return\n");
652 }
653 log_verbose("\n---Testing ucnv_getSubstChars.. with err != U_ZERO_ERROR \n");
654 err=U_ZERO_ERROR;
655 strcpy(myptr, "abc");
656 ucnv_setSubstChars(myConverter, myptr, ii, &err);
657 err=U_ILLEGAL_ARGUMENT_ERROR;
658 ucnv_getSubstChars(myConverter, save, &ii, &err);
659 if(strncmp(save, myptr, ii) == 0){
660 log_err("uncv_setSubstChars() with err != U_ZERO_ERROR shouldn't fill the SubstChars in the buffer, it just returns\n");
661 }
662 err=U_ZERO_ERROR;
663 /*------*/
664
374ca955 665#ifdef U_ENABLE_GENERIC_ISO_2022
b75a7d8f
A
666 /*resetState ucnv_reset()*/
667 log_verbose("\n---Testing ucnv_reset()..\n");
668 ucnv_reset(myConverter);
669 {
670 UChar32 c;
671 const uint8_t in[]={ 0x1b, 0x25, 0x42, 0x31, 0x32, 0x61, 0xc0, 0x80, 0xe0, 0x80, 0x80, 0xf0, 0x80, 0x80, 0x80};
672 const char *source=(const char *)in, *limit=(const char *)in+sizeof(in);
673 UConverter *cnv=ucnv_open("ISO_2022", &err);
674 if(U_FAILURE(err)) {
675 log_err("Unable to open a iso-2022 converter: %s\n", u_errorName(err));
676 }
677 c=ucnv_getNextUChar(cnv, &source, limit, &err);
678 if((U_FAILURE(err) || c != (UChar32)0x0031)) {
679 log_err("ucnv_getNextUChar() failed: %s\n", u_errorName(err));
680 }
681 ucnv_reset(cnv);
682 ucnv_close(cnv);
683
684 }
374ca955
A
685#endif
686
b75a7d8f
A
687 /*getDisplayName*/
688 log_verbose("\n---Testing ucnv_getDisplayName()...\n");
689 locale=CodePagesLocale[codepage_index];
b75a7d8f 690 len=0;
73c04bcf
A
691 displayname=NULL;
692 disnamelen = ucnv_getDisplayName(myConverter, locale, displayname, len, &err);
693 if(err==U_BUFFER_OVERFLOW_ERROR) {
b75a7d8f 694 err=U_ZERO_ERROR;
73c04bcf 695 displayname=(UChar*)malloc((disnamelen+1) * sizeof(UChar));
b75a7d8f 696 ucnv_getDisplayName(myConverter,locale,displayname,disnamelen+1, &err);
73c04bcf
A
697 if(U_FAILURE(err)) {
698 log_err("getDisplayName failed. The error is %s\n", myErrorName(err));
b75a7d8f 699 }
73c04bcf 700 else {
b75a7d8f 701 log_verbose(" getDisplayName o.k.\n");
73c04bcf
A
702 }
703 free(displayname);
704 displayname=NULL;
705 }
706 else {
707 log_err("getDisplayName preflight doesn't work. Error is %s\n", myErrorName(err));
b75a7d8f
A
708 }
709 /*test ucnv_getDiaplayName with error condition*/
b75a7d8f 710 err= U_ILLEGAL_ARGUMENT_ERROR;
73c04bcf 711 len=ucnv_getDisplayName(myConverter,locale,NULL,0, &err);
b75a7d8f
A
712 if( len !=0 ){
713 log_err("ucnv_getDisplayName() with err != U_ZERO_ERROR is supposed to return 0\n");
714 }
73c04bcf
A
715 /*test ucnv_getDiaplayName with error condition*/
716 err=U_ZERO_ERROR;
717 len=ucnv_getDisplayName(NULL,locale,NULL,0, &err);
718 if( len !=0 || U_SUCCESS(err)){
719 log_err("ucnv_getDisplayName(NULL) with cnv == NULL is supposed to return 0\n");
720 }
b75a7d8f
A
721 err=U_ZERO_ERROR;
722
723 /* testing ucnv_setFromUCallBack() and ucnv_getFromUCallBack()*/
724 ucnv_getFromUCallBack(myConverter, &MIA1, &MIA1Context);
725
726 log_verbose("\n---Testing ucnv_setFromUCallBack...\n");
727 ucnv_setFromUCallBack(myConverter, otherUnicodeAction(MIA1), &BOM, &oldFromUAction, &oldFromUContext, &err);
728 if (U_FAILURE(err) || oldFromUAction != MIA1 || oldFromUContext != MIA1Context)
729 {
730 log_err("FAILURE! %s\n", myErrorName(err));
731 }
732
733 ucnv_getFromUCallBack(myConverter, &MIA1_2, &MIA1Context2);
734 if (MIA1_2 != otherUnicodeAction(MIA1) || MIA1Context2 != &BOM)
735 log_err("get From UCallBack failed\n");
736 else
737 log_verbose("get From UCallBack ok\n");
738
739 log_verbose("\n---Testing getFromUCallBack Roundtrip...\n");
740 ucnv_setFromUCallBack(myConverter,MIA1, MIA1Context, &oldFromUAction, &oldFromUContext, &err);
741 if (U_FAILURE(err) || oldFromUAction != otherUnicodeAction(MIA1) || oldFromUContext != &BOM)
742 {
743 log_err("FAILURE! %s\n", myErrorName(err));
744 }
745
746 ucnv_getFromUCallBack(myConverter, &MIA1_2, &MIA1Context2);
747 if (MIA1_2 != MIA1 || MIA1Context2 != MIA1Context)
748 log_err("get From UCallBack action failed\n");
749 else
750 log_verbose("get From UCallBack action ok\n");
751
752 /*testing ucnv_setToUCallBack with error conditions*/
753 err=U_ILLEGAL_ARGUMENT_ERROR;
754 log_verbose("\n---Testing setFromUCallBack. with err != U_ZERO_ERROR..\n");
755 ucnv_setFromUCallBack(myConverter, otherUnicodeAction(MIA1), &BOM, &oldFromUAction, &oldFromUContext, &err);
756 ucnv_getFromUCallBack(myConverter, &MIA1_2, &MIA1Context2);
757 if(MIA1_2 == otherUnicodeAction(MIA1) || MIA1Context2 == &BOM){
758 log_err("To setFromUCallBack with err != U_ZERO_ERROR is supposed to fail\n");
759 }
760 err=U_ZERO_ERROR;
761
762
763 /*testing ucnv_setToUCallBack() and ucnv_getToUCallBack()*/
764 ucnv_getToUCallBack(myConverter, &MIA2, &MIA2Context);
765
766 log_verbose("\n---Testing setTo UCallBack...\n");
767 ucnv_setToUCallBack(myConverter,otherCharAction(MIA2), &BOM, &oldToUAction, &oldToUContext, &err);
768 if (U_FAILURE(err) || oldToUAction != MIA2 || oldToUContext != MIA2Context)
769 {
770 log_err("FAILURE! %s\n", myErrorName(err));
771 }
772
773 ucnv_getToUCallBack(myConverter, &MIA2_2, &MIA2Context2);
774 if (MIA2_2 != otherCharAction(MIA2) || MIA2Context2 != &BOM)
775 log_err("To UCallBack failed\n");
776 else
777 log_verbose("To UCallBack ok\n");
778
779 log_verbose("\n---Testing setTo UCallBack Roundtrip...\n");
780 ucnv_setToUCallBack(myConverter,MIA2, MIA2Context, &oldToUAction, &oldToUContext, &err);
781 if (U_FAILURE(err) || oldToUAction != otherCharAction(MIA2) || oldToUContext != &BOM)
782 { log_err("FAILURE! %s\n", myErrorName(err)); }
783
784 ucnv_getToUCallBack(myConverter, &MIA2_2, &MIA2Context2);
785 if (MIA2_2 != MIA2 || MIA2Context2 != MIA2Context)
786 log_err("To UCallBack failed\n");
787 else
788 log_verbose("To UCallBack ok\n");
789
790 /*testing ucnv_setToUCallBack with error conditions*/
791 err=U_ILLEGAL_ARGUMENT_ERROR;
792 log_verbose("\n---Testing setToUCallBack. with err != U_ZERO_ERROR..\n");
793 ucnv_setToUCallBack(myConverter,otherCharAction(MIA2), NULL, &oldToUAction, &oldToUContext, &err);
794 ucnv_getToUCallBack(myConverter, &MIA2_2, &MIA2Context2);
795 if (MIA2_2 == otherCharAction(MIA2) || MIA2Context2 == &BOM){
796 log_err("To setToUCallBack with err != U_ZERO_ERROR is supposed to fail\n");
797 }
798 err=U_ZERO_ERROR;
799
800
801 /*getcodepageid testing ucnv_getCCSID() */
802 log_verbose("\n----Testing getCCSID....\n");
803 cp = ucnv_getCCSID(myConverter,&err);
804 if (U_FAILURE(err))
805 {
806 log_err("FAILURE!..... %s\n", myErrorName(err));
807 }
808 if (cp != CodePageNumberToTest[codepage_index])
809 log_err("Codepage number test failed\n");
810 else
811 log_verbose("Codepage number test OK\n");
812
813 /*testing ucnv_getCCSID() with err != U_ZERO_ERROR*/
814 err=U_ILLEGAL_ARGUMENT_ERROR;
815 if( ucnv_getCCSID(myConverter,&err) != -1){
816 log_err("ucnv_getCCSID() with err != U_ZERO_ERROR is supposed to fail\n");
817 }
818 err=U_ZERO_ERROR;
819
820 /*getCodepagePlatform testing ucnv_getPlatform()*/
821 log_verbose("\n---Testing getCodepagePlatform ..\n");
822 if (CodePagesPlatform[codepage_index]!=ucnv_getPlatform(myConverter, &err))
823 log_err("Platform codepage test failed\n");
824 else
825 log_verbose("Platform codepage test ok\n");
826
827 if (U_FAILURE(err))
828 {
829 log_err("FAILURE! %s\n", myErrorName(err));
830 }
831 /*testing ucnv_getPlatform() with err != U_ZERO_ERROR*/
832 err= U_ILLEGAL_ARGUMENT_ERROR;
833 if(ucnv_getPlatform(myConverter, &err) != UCNV_UNKNOWN){
834 log_err("ucnv)getPlatform with err != U_ZERO_ERROR is supposed to fail\n");
835 }
836 err=U_ZERO_ERROR;
837
838
839 /*Reads the BOM*/
57a6839d
A
840 {
841 // Note: gcc produces a compile warning if the return value from fread() is ignored.
842 size_t numRead = fread(&BOM, sizeof(UChar), 1, ucs_file_in);
843 (void)numRead;
844 }
b75a7d8f
A
845 if (BOM!=0xFEFF && BOM!=0xFFFE)
846 {
847 log_err("File Missing BOM...Bailing!\n");
4388f060
A
848 fclose(ucs_file_in);
849 break;
b75a7d8f
A
850 }
851
852
853 /*Reads in the file*/
854 while(!feof(ucs_file_in)&&(i+=fread(ucs_file_buffer+i, sizeof(UChar), 1, ucs_file_in)))
855 {
856 myUChar = ucs_file_buffer[i-1];
857
858 ucs_file_buffer[i-1] = (UChar)((BOM==0xFEFF)?myUChar:((myUChar >> 8) | (myUChar << 8))); /*adjust if BIG_ENDIAN*/
859 }
860
861 myUChar = ucs_file_buffer[i-1];
862 ucs_file_buffer[i-1] = (UChar)((BOM==0xFEFF)?myUChar:((myUChar >> 8) | (myUChar << 8))); /*adjust if BIG_ENDIAN Corner Case*/
863
864
865 /*testing ucnv_fromUChars() and ucnv_toUChars() */
866 /*uchar1---fromUChar--->output_cp_buffer --toUChar--->uchar2*/
867
868 uchar1=(UChar*)malloc(sizeof(UChar) * (i+1));
869 u_uastrcpy(uchar1,"");
870 u_strncpy(uchar1,ucs_file_buffer,i);
871 uchar1[i] = 0;
872
873 uchar3=(UChar*)malloc(sizeof(UChar)*(i+1));
874 u_uastrcpy(uchar3,"");
875 u_strncpy(uchar3,ucs_file_buffer,i);
876 uchar3[i] = 0;
877
878 /*Calls the Conversion Routine */
879 testLong1 = MAX_FILE_LEN;
880 log_verbose("\n---Testing ucnv_fromUChars()\n");
881 targetcapacity = ucnv_fromUChars(myConverter, output_cp_buffer, testLong1, uchar1, -1, &err);
882 if (U_FAILURE(err))
883 {
884 log_err("\nFAILURE...%s\n", myErrorName(err));
885 }
886 else
887 log_verbose(" ucnv_fromUChars() o.k.\n");
888
889 /*test the conversion routine */
890 log_verbose("\n---Testing ucnv_toUChars()\n");
891 /*call it first time for trapping the targetcapacity and size needed to allocate memory for the buffer uchar2 */
892 targetcapacity2=0;
893 targetsize = ucnv_toUChars(myConverter,
894 NULL,
895 targetcapacity2,
896 output_cp_buffer,
897 strlen(output_cp_buffer),
898 &err);
899 /*if there is an buffer overflow then trap the values and pass them and make the actual call*/
900
901 if(err==U_BUFFER_OVERFLOW_ERROR)
902 {
903 err=U_ZERO_ERROR;
904 uchar2=(UChar*)malloc((targetsize+1) * sizeof(UChar));
905 targetsize = ucnv_toUChars(myConverter,
906 uchar2,
907 targetsize+1,
908 output_cp_buffer,
909 strlen(output_cp_buffer),
910 &err);
911
912 if(U_FAILURE(err))
913 log_err("ucnv_toUChars() FAILED %s\n", myErrorName(err));
914 else
915 log_verbose(" ucnv_toUChars() o.k.\n");
916
917 if(u_strcmp(uchar1,uchar2)!=0)
918 log_err("equality test failed with conversion routine\n");
919 }
920 else
921 {
922 log_err("ERR: calling toUChars: Didn't get U_BUFFER_OVERFLOW .. expected it.\n");
923 }
924 /*Testing ucnv_fromUChars and ucnv_toUChars with error conditions*/
925 err=U_ILLEGAL_ARGUMENT_ERROR;
926 log_verbose("\n---Testing ucnv_fromUChars() with err != U_ZERO_ERROR\n");
927 targetcapacity = ucnv_fromUChars(myConverter, output_cp_buffer, testLong1, uchar1, -1, &err);
928 if (targetcapacity !=0) {
929 log_err("\nFAILURE: ucnv_fromUChars with err != U_ZERO_ERROR is expected to fail and return 0\n");
930 }
931 err=U_ZERO_ERROR;
932 log_verbose("\n---Testing ucnv_fromUChars() with converter=NULL\n");
933 targetcapacity = ucnv_fromUChars(NULL, output_cp_buffer, testLong1, uchar1, -1, &err);
934 if (targetcapacity !=0 || err != U_ILLEGAL_ARGUMENT_ERROR) {
935 log_err("\nFAILURE: ucnv_fromUChars with converter=NULL is expected to fail\n");
936 }
937 err=U_ZERO_ERROR;
938 log_verbose("\n---Testing ucnv_fromUChars() with sourceLength = 0\n");
939 targetcapacity = ucnv_fromUChars(myConverter, output_cp_buffer, testLong1, uchar1, 0, &err);
940 if (targetcapacity !=0) {
941 log_err("\nFAILURE: ucnv_fromUChars with sourceLength 0 is expected to return 0\n");
942 }
943 log_verbose("\n---Testing ucnv_fromUChars() with targetLength = 0\n");
944 targetcapacity = ucnv_fromUChars(myConverter, output_cp_buffer, 0, uchar1, -1, &err);
945 if (err != U_BUFFER_OVERFLOW_ERROR) {
946 log_err("\nFAILURE: ucnv_fromUChars with targetLength 0 is expected to fail and throw U_BUFFER_OVERFLOW_ERROR\n");
947 }
948 /*toUChars with error conditions*/
949 targetsize = ucnv_toUChars(myConverter, uchar2, targetsize, output_cp_buffer, strlen(output_cp_buffer), &err);
950 if(targetsize != 0){
951 log_err("\nFAILURE: ucnv_toUChars with err != U_ZERO_ERROR is expected to fail and return 0\n");
952 }
953 err=U_ZERO_ERROR;
954 targetsize = ucnv_toUChars(myConverter, uchar2, -1, output_cp_buffer, strlen(output_cp_buffer), &err);
955 if(targetsize != 0 || err != U_ILLEGAL_ARGUMENT_ERROR){
956 log_err("\nFAILURE: ucnv_toUChars with targetsize < 0 is expected to throw U_ILLEGAL_ARGUMENT_ERROR and return 0\n");
957 }
958 err=U_ZERO_ERROR;
959 targetsize = ucnv_toUChars(myConverter, uchar2, 0, output_cp_buffer, 0, &err);
960 if (targetsize !=0) {
961 log_err("\nFAILURE: ucnv_toUChars with sourceLength 0 is expected to return 0\n");
962 }
963 targetcapacity2=0;
964 targetsize = ucnv_toUChars(myConverter, NULL, targetcapacity2, output_cp_buffer, strlen(output_cp_buffer), &err);
965 if (err != U_STRING_NOT_TERMINATED_WARNING) {
966 log_err("\nFAILURE: ucnv_toUChars(targetLength)->%s instead of U_STRING_NOT_TERMINATED_WARNING\n",
967 u_errorName(err));
968 }
969 err=U_ZERO_ERROR;
970 /*-----*/
971
972
973 /*testing for ucnv_fromUnicode() and ucnv_toUnicode() */
974 /*Clean up re-usable vars*/
b75a7d8f
A
975 log_verbose("Testing ucnv_fromUnicode().....\n");
976 tmp_ucs_buf=ucs_file_buffer_use;
977 ucnv_fromUnicode(myConverter, &mytarget_1,
978 mytarget + MAX_FILE_LEN,
979 &tmp_ucs_buf,
980 ucs_file_buffer_use+i,
981 NULL,
982 TRUE,
983 &err);
984 consumedUni = (UChar*)tmp_consumedUni;
57a6839d 985 (void)consumedUni; /* Suppress set but not used warning. */
b75a7d8f
A
986
987 if (U_FAILURE(err))
988 {
989 log_err("FAILURE! %s\n", myErrorName(err));
990 }
991 else
992 log_verbose("ucnv_fromUnicode() o.k.\n");
993
994 /*Uni1 ----ToUnicode----> Cp2 ----FromUnicode---->Uni3 */
995 log_verbose("Testing ucnv_toUnicode().....\n");
996 tmp_mytarget_use=mytarget_use;
997 tmp_consumed = consumed;
998 ucnv_toUnicode(myConverter, &my_ucs_file_buffer_1,
999 my_ucs_file_buffer + MAX_FILE_LEN,
1000 &tmp_mytarget_use,
1001 mytarget_use + (mytarget_1 - mytarget),
1002 NULL,
1003 FALSE,
1004 &err);
1005 consumed = (char*)tmp_consumed;
1006 if (U_FAILURE(err))
1007 {
1008 log_err("FAILURE! %s\n", myErrorName(err));
1009 }
1010 else
1011 log_verbose("ucnv_toUnicode() o.k.\n");
1012
1013
1014 log_verbose("\n---Testing RoundTrip ...\n");
1015
1016
1017 u_strncpy(uchar3, my_ucs_file_buffer,i);
1018 uchar3[i] = 0;
1019
1020 if(u_strcmp(uchar1,uchar3)==0)
1021 log_verbose("Equality test o.k.\n");
1022 else
1023 log_err("Equality test failed\n");
1024
1025 /*sanity compare */
1026 if(uchar2 == NULL)
1027 {
1028 log_err("uchar2 was NULL (ccapitst.c line %d), couldn't do sanity check\n", __LINE__);
1029 }
1030 else
1031 {
1032 if(u_strcmp(uchar2, uchar3)==0)
1033 log_verbose("Equality test o.k.\n");
1034 else
1035 log_err("Equality test failed\n");
1036 }
1037
1038 fclose(ucs_file_in);
1039 ucnv_close(myConverter);
b75a7d8f
A
1040 if (uchar1 != 0) free(uchar1);
1041 if (uchar2 != 0) free(uchar2);
1042 if (uchar3 != 0) free(uchar3);
1043 }
1044
1045 free((void*)mytarget);
1046 free((void*)output_cp_buffer);
1047 free((void*)ucs_file_buffer);
1048 free((void*)my_ucs_file_buffer);
73c04bcf 1049#endif
b75a7d8f
A
1050}
1051
51004dcb 1052#if !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
1053static UConverterFromUCallback otherUnicodeAction(UConverterFromUCallback MIA)
1054{
1055 return (MIA==(UConverterFromUCallback)UCNV_FROM_U_CALLBACK_STOP)?(UConverterFromUCallback)UCNV_FROM_U_CALLBACK_SUBSTITUTE:(UConverterFromUCallback)UCNV_FROM_U_CALLBACK_STOP;
1056}
1057
b75a7d8f
A
1058static UConverterToUCallback otherCharAction(UConverterToUCallback MIA)
1059{
1060 return (MIA==(UConverterToUCallback)UCNV_TO_U_CALLBACK_STOP)?(UConverterToUCallback)UCNV_TO_U_CALLBACK_SUBSTITUTE:(UConverterToUCallback)UCNV_TO_U_CALLBACK_STOP;
1061}
51004dcb 1062#endif
b75a7d8f 1063
374ca955 1064static void TestFlushCache(void) {
73c04bcf 1065#if !UCONFIG_NO_LEGACY_CONVERSION
374ca955
A
1066 UErrorCode err = U_ZERO_ERROR;
1067 UConverter* someConverters[5];
1068 int flushCount = 0;
1069
1070 /* flush the converter cache to get a consistent state before the flushing is tested */
1071 ucnv_flushCache();
1072
1073 /*Testing ucnv_open()*/
1074 /* Note: These converters have been chosen because they do NOT
1075 encode the Latin characters (U+0041, ...), and therefore are
1076 highly unlikely to be chosen as system default codepages */
1077
1078 someConverters[0] = ucnv_open("ibm-1047", &err);
1079 if (U_FAILURE(err)) {
1080 log_data_err("FAILURE! %s\n", myErrorName(err));
1081 }
1082
1083 someConverters[1] = ucnv_open("ibm-1047", &err);
1084 if (U_FAILURE(err)) {
1085 log_data_err("FAILURE! %s\n", myErrorName(err));
1086 }
1087
1088 someConverters[2] = ucnv_open("ibm-1047", &err);
1089 if (U_FAILURE(err)) {
1090 log_data_err("FAILURE! %s\n", myErrorName(err));
1091 }
1092
1093 someConverters[3] = ucnv_open("gb18030", &err);
1094 if (U_FAILURE(err)) {
1095 log_data_err("FAILURE! %s\n", myErrorName(err));
1096 }
1097
1098 someConverters[4] = ucnv_open("ibm-954", &err);
1099 if (U_FAILURE(err)) {
1100 log_data_err("FAILURE! %s\n", myErrorName(err));
1101 }
1102
1103
1104 /* Testing ucnv_flushCache() */
1105 log_verbose("\n---Testing ucnv_flushCache...\n");
1106 if ((flushCount=ucnv_flushCache())==0)
1107 log_verbose("Flush cache ok\n");
1108 else
1109 log_data_err("Flush Cache failed [line %d], expect 0 got %d \n", __LINE__, flushCount);
1110
1111 /*testing ucnv_close() and ucnv_flushCache() */
1112 ucnv_close(someConverters[0]);
1113 ucnv_close(someConverters[1]);
1114
1115 if ((flushCount=ucnv_flushCache())==0)
1116 log_verbose("Flush cache ok\n");
1117 else
1118 log_data_err("Flush Cache failed [line %d], expect 0 got %d \n", __LINE__, flushCount);
1119
1120 ucnv_close(someConverters[2]);
1121 ucnv_close(someConverters[3]);
1122
1123 if ((flushCount=ucnv_flushCache())==2)
1124 log_verbose("Flush cache ok\n"); /*because first, second and third are same */
1125 else
1126 log_data_err("Flush Cache failed line %d, got %d expected 2 or there is an error in ucnv_close()\n",
1127 __LINE__,
1128 flushCount);
1129
1130 ucnv_close(someConverters[4]);
1131 if ( (flushCount=ucnv_flushCache())==1)
1132 log_verbose("Flush cache ok\n");
1133 else
1134 log_data_err("Flush Cache failed line %d, expected 1 got %d \n", __LINE__, flushCount);
73c04bcf 1135#endif
374ca955
A
1136}
1137
b75a7d8f
A
1138/**
1139 * Test the converter alias API, specifically the fuzzy matching of
1140 * alias names and the alias table integrity. Make sure each
1141 * converter has at least one alias (itself), and that its listed
1142 * aliases map back to itself. Check some hard-coded UTF-8 and
1143 * ISO_2022 aliases to make sure they work.
1144 */
1145static void TestAlias() {
1146 int32_t i, ncnv;
1147 UErrorCode status = U_ZERO_ERROR;
1148
1149 /* Predetermined aliases that we expect to map back to ISO_2022
1150 * and UTF-8. UPDATE THIS DATA AS NECESSARY. */
1151 const char* ISO_2022_NAMES[] =
374ca955
A
1152 {"ISO_2022,locale=ja,version=2", "ISO-2022-JP-2", "csISO2022JP2",
1153 "Iso-2022jP2", "isO-2022_Jp_2", "iSo--2022,locale=ja,version=2"};
b75a7d8f
A
1154 int32_t ISO_2022_NAMES_LENGTH =
1155 sizeof(ISO_2022_NAMES) / sizeof(ISO_2022_NAMES[0]);
1156 const char *UTF8_NAMES[] =
1157 { "UTF-8", "utf-8", "utf8", "ibm-1208",
1158 "utf_8", "ibm1208", "cp1208" };
1159 int32_t UTF8_NAMES_LENGTH =
1160 sizeof(UTF8_NAMES) / sizeof(UTF8_NAMES[0]);
1161
1162 struct {
1163 const char *name;
1164 const char *alias;
1165 } CONVERTERS_NAMES[] = {
1166 { "UTF-32BE", "UTF32_BigEndian" },
1167 { "UTF-32LE", "UTF32_LittleEndian" },
1168 { "UTF-32", "ISO-10646-UCS-4" },
1169 { "UTF32_PlatformEndian", "UTF32_PlatformEndian" },
1170 { "UTF-32", "ucs-4" }
1171 };
1172 int32_t CONVERTERS_NAMES_LENGTH = sizeof(CONVERTERS_NAMES) / sizeof(*CONVERTERS_NAMES);
1173
1174 /* When there are bugs in gencnval or in ucnv_io, converters can
1175 appear to have no aliases. */
1176 ncnv = ucnv_countAvailable();
1177 log_verbose("%d converters\n", ncnv);
1178 for (i=0; i<ncnv; ++i) {
1179 const char *name = ucnv_getAvailableName(i);
1180 const char *alias0;
1181 uint16_t na = ucnv_countAliases(name, &status);
1182 uint16_t j;
1183 UConverter *cnv;
1184
1185 if (na == 0) {
1186 log_err("FAIL: Converter \"%s\" (i=%d)"
1187 " has no aliases; expect at least one\n",
1188 name, i);
1189 continue;
1190 }
1191 cnv = ucnv_open(name, &status);
1192 if (U_FAILURE(status)) {
1193 log_data_err("FAIL: Converter \"%s\" (i=%d)"
1194 " can't be opened.\n",
1195 name, i);
1196 }
1197 else {
1198 if (strcmp(ucnv_getName(cnv, &status), name) != 0
1199 && (strstr(name, "PlatformEndian") == 0 && strstr(name, "OppositeEndian") == 0)) {
1200 log_err("FAIL: Converter \"%s\" returned \"%s\" for getName. "
1201 "The should be the same\n",
1202 name, ucnv_getName(cnv, &status));
1203 }
1204 }
1205 ucnv_close(cnv);
1206
1207 status = U_ZERO_ERROR;
1208 alias0 = ucnv_getAlias(name, 0, &status);
1209 for (j=1; j<na; ++j) {
1210 const char *alias;
1211 /* Make sure each alias maps back to the the same list of
1212 aliases. Assume that if alias 0 is the same, the whole
1213 list is the same (this should always be true). */
1214 const char *mapBack;
1215
1216 status = U_ZERO_ERROR;
1217 alias = ucnv_getAlias(name, j, &status);
1218 if (status == U_AMBIGUOUS_ALIAS_WARNING) {
1219 log_err("FAIL: Converter \"%s\"is ambiguous\n", name);
1220 }
1221
1222 if (alias == NULL) {
1223 log_err("FAIL: Converter \"%s\" -> "
1224 "alias[%d]=NULL\n",
1225 name, j);
1226 continue;
1227 }
1228
1229 mapBack = ucnv_getAlias(alias, 0, &status);
1230
1231 if (mapBack == NULL) {
1232 log_err("FAIL: Converter \"%s\" -> "
1233 "alias[%d]=\"%s\" -> "
1234 "alias[0]=NULL, exp. \"%s\"\n",
1235 name, j, alias, alias0);
1236 continue;
1237 }
1238
1239 if (0 != strcmp(alias0, mapBack)) {
1240 int32_t idx;
1241 UBool foundAlias = FALSE;
1242 if (status == U_AMBIGUOUS_ALIAS_WARNING) {
1243 /* Make sure that we only get this mismapping when there is
1244 an ambiguous alias, and the other converter has this alias too. */
1245 for (idx = 0; idx < ucnv_countAliases(mapBack, &status); idx++) {
1246 if (strcmp(ucnv_getAlias(mapBack, (uint16_t)idx, &status), alias) == 0) {
1247 foundAlias = TRUE;
1248 break;
1249 }
1250 }
1251 }
1252 /* else not ambiguous, and this is a real problem. foundAlias = FALSE */
1253
1254 if (!foundAlias) {
1255 log_err("FAIL: Converter \"%s\" -> "
1256 "alias[%d]=\"%s\" -> "
1257 "alias[0]=\"%s\", exp. \"%s\"\n",
1258 name, j, alias, mapBack, alias0);
1259 }
1260 }
1261 }
1262 }
1263
1264
1265 /* Check a list of predetermined aliases that we expect to map
1266 * back to ISO_2022 and UTF-8. */
1267 for (i=1; i<ISO_2022_NAMES_LENGTH; ++i) {
1268 const char* mapBack = ucnv_getAlias(ISO_2022_NAMES[i], 0, &status);
1269 if(!mapBack) {
1270 log_data_err("Couldn't get alias for %s. You probably have no data\n", ISO_2022_NAMES[i]);
1271 continue;
1272 }
1273 if (0 != strcmp(mapBack, ISO_2022_NAMES[0])) {
374ca955 1274 log_err("FAIL: \"%s\" -> \"%s\", expect \"ISO_2022,locale=ja,version=2\"\n",
b75a7d8f
A
1275 ISO_2022_NAMES[i], mapBack);
1276 }
1277 }
1278
1279
1280 for (i=1; i<UTF8_NAMES_LENGTH; ++i) {
1281 const char* mapBack = ucnv_getAlias(UTF8_NAMES[i], 0, &status);
1282 if(!mapBack) {
1283 log_data_err("Couldn't get alias for %s. You probably have no data\n", UTF8_NAMES[i]);
1284 continue;
1285 }
1286 if (mapBack && 0 != strcmp(mapBack, UTF8_NAMES[0])) {
1287 log_err("FAIL: \"%s\" -> \"%s\", expect UTF-8\n",
1288 UTF8_NAMES[i], mapBack);
1289 }
1290 }
1291
1292 /*
1293 * Check a list of predetermined aliases that we expect to map
1294 * back to predermined converter names.
1295 */
1296
1297 for (i = 0; i < CONVERTERS_NAMES_LENGTH; ++i) {
1298 const char* mapBack = ucnv_getAlias(CONVERTERS_NAMES[i].alias, 0, &status);
1299 if(!mapBack) {
73c04bcf 1300 log_data_err("Couldn't get alias for %s. You probably have no data\n", CONVERTERS_NAMES[i].name);
b75a7d8f
A
1301 continue;
1302 }
1303 if (0 != strcmp(mapBack, CONVERTERS_NAMES[i].name)) {
1304 log_err("FAIL: \"%s\" -> \"%s\", expect %s\n",
1305 CONVERTERS_NAMES[i].alias, mapBack, CONVERTERS_NAMES[i].name);
1306 }
1307 }
1308
1309}
1310
1311static void TestDuplicateAlias(void) {
1312 const char *alias;
1313 UErrorCode status = U_ZERO_ERROR;
1314
1315 status = U_ZERO_ERROR;
1316 alias = ucnv_getStandardName("Shift_JIS", "IBM", &status);
1317 if (alias == NULL || strcmp(alias, "ibm-943") != 0 || status != U_AMBIGUOUS_ALIAS_WARNING) {
729e4ab9 1318 log_data_err("FAIL: Didn't get ibm-943 for Shift_JIS {IBM}. Got %s\n", alias);
b75a7d8f
A
1319 }
1320 status = U_ZERO_ERROR;
1321 alias = ucnv_getStandardName("ibm-943", "IANA", &status);
1322 if (alias == NULL || strcmp(alias, "Shift_JIS") != 0 || status != U_AMBIGUOUS_ALIAS_WARNING) {
1323 log_data_err("FAIL: Didn't get Shift_JIS for ibm-943 {IANA}. Got %s\n", alias);
1324 }
1325 status = U_ZERO_ERROR;
1326 alias = ucnv_getStandardName("ibm-943_P130-2000", "IANA", &status);
1327 if (alias != NULL || status == U_AMBIGUOUS_ALIAS_WARNING) {
1328 log_data_err("FAIL: Didn't get NULL for ibm-943 {IANA}. Got %s\n", alias);
1329 }
1330}
1331
1332
1333/* Test safe clone callback */
1334
1335static uint32_t TSCC_nextSerial()
1336{
1337 static uint32_t n = 1;
1338
1339 return (n++);
1340}
1341
1342typedef struct
1343{
1344 uint32_t magic; /* 0xC0FFEE to identify that the object is OK */
1345 uint32_t serial; /* minted from nextSerial, above */
1346 UBool wasClosed; /* close happened on the object */
1347} TSCCContext;
1348
1349static TSCCContext *TSCC_clone(TSCCContext *ctx)
1350{
1351 TSCCContext *newCtx = (TSCCContext *)malloc(sizeof(TSCCContext));
1352
1353 newCtx->serial = TSCC_nextSerial();
1354 newCtx->wasClosed = 0;
1355 newCtx->magic = 0xC0FFEE;
1356
1357 log_verbose("TSCC_clone: %p:%d -> new context %p:%d\n", ctx, ctx->serial, newCtx, newCtx->serial);
1358
1359 return newCtx;
1360}
1361
51004dcb 1362#if !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
1363static void TSCC_fromU(const void *context,
1364 UConverterFromUnicodeArgs *fromUArgs,
1365 const UChar* codeUnits,
1366 int32_t length,
1367 UChar32 codePoint,
1368 UConverterCallbackReason reason,
1369 UErrorCode * err)
1370{
1371 TSCCContext *ctx = (TSCCContext*)context;
1372 UConverterFromUCallback junkFrom;
1373
1374 log_verbose("TSCC_fromU: Context %p:%d called, reason %d on cnv %p\n", ctx, ctx->serial, reason, fromUArgs->converter);
1375
1376 if(ctx->magic != 0xC0FFEE) {
1377 log_err("TSCC_fromU: Context %p:%d magic is 0x%x should be 0xC0FFEE.\n", ctx,ctx->serial, ctx->magic);
1378 return;
1379 }
1380
1381 if(reason == UCNV_CLONE) {
1382 UErrorCode subErr = U_ZERO_ERROR;
1383 TSCCContext *newCtx;
1384 TSCCContext *junkCtx;
73c04bcf 1385 TSCCContext **pjunkCtx = &junkCtx;
b75a7d8f
A
1386
1387 /* "recreate" it */
1388 log_verbose("TSCC_fromU: cloning..\n");
1389 newCtx = TSCC_clone(ctx);
1390
1391 if(newCtx == NULL) {
1392 log_err("TSCC_fromU: internal clone failed on %p\n", ctx);
1393 }
1394
1395 /* now, SET it */
73c04bcf 1396 ucnv_getFromUCallBack(fromUArgs->converter, &junkFrom, (const void**)pjunkCtx);
b75a7d8f
A
1397 ucnv_setFromUCallBack(fromUArgs->converter, junkFrom, newCtx, NULL, NULL, &subErr);
1398
1399 if(U_FAILURE(subErr)) {
1400 *err = subErr;
1401 }
1402 }
1403
1404 if(reason == UCNV_CLOSE) {
1405 log_verbose("TSCC_fromU: Context %p:%d closing\n", ctx, ctx->serial);
1406 ctx->wasClosed = TRUE;
1407 }
1408}
1409
b75a7d8f
A
1410static void TSCC_toU(const void *context,
1411 UConverterToUnicodeArgs *toUArgs,
1412 const char* codeUnits,
1413 int32_t length,
1414 UConverterCallbackReason reason,
1415 UErrorCode * err)
1416{
1417 TSCCContext *ctx = (TSCCContext*)context;
1418 UConverterToUCallback junkFrom;
1419
1420 log_verbose("TSCC_toU: Context %p:%d called, reason %d on cnv %p\n", ctx, ctx->serial, reason, toUArgs->converter);
1421
1422 if(ctx->magic != 0xC0FFEE) {
1423 log_err("TSCC_toU: Context %p:%d magic is 0x%x should be 0xC0FFEE.\n", ctx,ctx->serial, ctx->magic);
1424 return;
1425 }
1426
1427 if(reason == UCNV_CLONE) {
1428 UErrorCode subErr = U_ZERO_ERROR;
1429 TSCCContext *newCtx;
1430 TSCCContext *junkCtx;
73c04bcf 1431 TSCCContext **pjunkCtx = &junkCtx;
b75a7d8f
A
1432
1433 /* "recreate" it */
1434 log_verbose("TSCC_toU: cloning..\n");
1435 newCtx = TSCC_clone(ctx);
1436
1437 if(newCtx == NULL) {
1438 log_err("TSCC_toU: internal clone failed on %p\n", ctx);
1439 }
1440
1441 /* now, SET it */
73c04bcf 1442 ucnv_getToUCallBack(toUArgs->converter, &junkFrom, (const void**)pjunkCtx);
b75a7d8f
A
1443 ucnv_setToUCallBack(toUArgs->converter, junkFrom, newCtx, NULL, NULL, &subErr);
1444
1445 if(U_FAILURE(subErr)) {
1446 *err = subErr;
1447 }
1448 }
1449
1450 if(reason == UCNV_CLOSE) {
1451 log_verbose("TSCC_toU: Context %p:%d closing\n", ctx, ctx->serial);
1452 ctx->wasClosed = TRUE;
1453 }
1454}
1455
1456static void TSCC_init(TSCCContext *q)
1457{
1458 q->magic = 0xC0FFEE;
1459 q->serial = TSCC_nextSerial();
1460 q->wasClosed = 0;
1461}
1462
1463static void TSCC_print_log(TSCCContext *q, const char *name)
1464{
1465 if(q==NULL) {
1466 log_verbose("TSCContext: %s is NULL!!\n", name);
1467 } else {
1468 if(q->magic != 0xC0FFEE) {
1469 log_err("TSCCContext: %p:%d's magic is %x, supposed to be 0xC0FFEE\n",
1470 q,q->serial, q->magic);
1471 }
1472 log_verbose("TSCCContext %p:%d=%s - magic %x, %s\n",
1473 q, q->serial, name, q->magic, q->wasClosed?"CLOSED":"open");
1474 }
1475}
1476
1477static void TestConvertSafeCloneCallback()
1478{
1479 UErrorCode err = U_ZERO_ERROR;
1480 TSCCContext from1, to1;
1481 TSCCContext *from2, *from3, *to2, *to3;
73c04bcf 1482 TSCCContext **pfrom2 = &from2, **pfrom3 = &from3, **pto2 = &to2, **pto3 = &to3;
b75a7d8f
A
1483 char hunk[8192];
1484 int32_t hunkSize = 8192;
1485 UConverterFromUCallback junkFrom;
1486 UConverterToUCallback junkTo;
1487 UConverter *conv1, *conv2 = NULL;
1488
1489 conv1 = ucnv_open("iso-8859-3", &err);
1490
1491 if(U_FAILURE(err)) {
729e4ab9 1492 log_data_err("Err opening iso-8859-3, %s\n", u_errorName(err));
b75a7d8f
A
1493 return;
1494 }
1495
1496 log_verbose("Opened conv1=%p\n", conv1);
1497
1498 TSCC_init(&from1);
1499 TSCC_init(&to1);
1500
1501 TSCC_print_log(&from1, "from1");
1502 TSCC_print_log(&to1, "to1");
1503
1504 ucnv_setFromUCallBack(conv1, TSCC_fromU, &from1, NULL, NULL, &err);
1505 log_verbose("Set from1 on conv1\n");
1506 TSCC_print_log(&from1, "from1");
1507
1508 ucnv_setToUCallBack(conv1, TSCC_toU, &to1, NULL, NULL, &err);
1509 log_verbose("Set to1 on conv1\n");
1510 TSCC_print_log(&to1, "to1");
1511
1512 conv2 = ucnv_safeClone(conv1, hunk, &hunkSize, &err);
1513 if(U_FAILURE(err)) {
1514 log_err("safeClone failed: %s\n", u_errorName(err));
1515 return;
1516 }
1517 log_verbose("Cloned to conv2=%p.\n", conv2);
1518
1519/********** from *********************/
73c04bcf
A
1520 ucnv_getFromUCallBack(conv2, &junkFrom, (const void**)pfrom2);
1521 ucnv_getFromUCallBack(conv1, &junkFrom, (const void**)pfrom3);
b75a7d8f
A
1522
1523 TSCC_print_log(from2, "from2");
1524 TSCC_print_log(from3, "from3(==from1)");
1525
1526 if(from2 == NULL) {
1527 log_err("FAIL! from2 is null \n");
1528 return;
1529 }
1530
1531 if(from3 == NULL) {
1532 log_err("FAIL! from3 is null \n");
1533 return;
1534 }
1535
1536 if(from3 != (&from1) ) {
1537 log_err("FAIL! conv1's FROM context changed!\n");
1538 }
1539
1540 if(from2 == (&from1) ) {
1541 log_err("FAIL! conv1's FROM context is the same as conv2's!\n");
1542 }
1543
1544 if(from1.wasClosed) {
1545 log_err("FAIL! from1 is closed \n");
1546 }
1547
1548 if(from2->wasClosed) {
1549 log_err("FAIL! from2 was closed\n");
1550 }
1551
1552/********** to *********************/
73c04bcf
A
1553 ucnv_getToUCallBack(conv2, &junkTo, (const void**)pto2);
1554 ucnv_getToUCallBack(conv1, &junkTo, (const void**)pto3);
b75a7d8f
A
1555
1556 TSCC_print_log(to2, "to2");
1557 TSCC_print_log(to3, "to3(==to1)");
1558
1559 if(to2 == NULL) {
1560 log_err("FAIL! to2 is null \n");
1561 return;
1562 }
1563
1564 if(to3 == NULL) {
1565 log_err("FAIL! to3 is null \n");
1566 return;
1567 }
1568
1569 if(to3 != (&to1) ) {
1570 log_err("FAIL! conv1's TO context changed!\n");
1571 }
1572
1573 if(to2 == (&to1) ) {
1574 log_err("FAIL! conv1's TO context is the same as conv2's!\n");
1575 }
1576
1577 if(to1.wasClosed) {
1578 log_err("FAIL! to1 is closed \n");
1579 }
1580
1581 if(to2->wasClosed) {
1582 log_err("FAIL! to2 was closed\n");
1583 }
1584
1585/*************************************/
1586
1587 ucnv_close(conv1);
1588 log_verbose("ucnv_closed (conv1)\n");
1589 TSCC_print_log(&from1, "from1");
1590 TSCC_print_log(from2, "from2");
1591 TSCC_print_log(&to1, "to1");
1592 TSCC_print_log(to2, "to2");
1593
1594 if(from1.wasClosed == FALSE) {
1595 log_err("FAIL! from1 is NOT closed \n");
1596 }
1597
1598 if(from2->wasClosed) {
1599 log_err("FAIL! from2 was closed\n");
1600 }
1601
1602 if(to1.wasClosed == FALSE) {
1603 log_err("FAIL! to1 is NOT closed \n");
1604 }
1605
1606 if(to2->wasClosed) {
1607 log_err("FAIL! to2 was closed\n");
1608 }
1609
1610 ucnv_close(conv2);
1611 log_verbose("ucnv_closed (conv2)\n");
1612
1613 TSCC_print_log(&from1, "from1");
1614 TSCC_print_log(from2, "from2");
1615
1616 if(from1.wasClosed == FALSE) {
1617 log_err("FAIL! from1 is NOT closed \n");
1618 }
1619
1620 if(from2->wasClosed == FALSE) {
1621 log_err("FAIL! from2 was NOT closed\n");
1622 }
1623
1624 TSCC_print_log(&to1, "to1");
1625 TSCC_print_log(to2, "to2");
1626
1627 if(to1.wasClosed == FALSE) {
1628 log_err("FAIL! to1 is NOT closed \n");
1629 }
1630
1631 if(to2->wasClosed == FALSE) {
1632 log_err("FAIL! to2 was NOT closed\n");
1633 }
1634
1635 if(to2 != (&to1)) {
1636 free(to2); /* to1 is stack based */
1637 }
1638 if(from2 != (&from1)) {
1639 free(from2); /* from1 is stack based */
1640 }
1641}
73c04bcf 1642#endif
b75a7d8f 1643
374ca955
A
1644static UBool
1645containsAnyOtherByte(uint8_t *p, int32_t length, uint8_t b) {
1646 while(length>0) {
1647 if(*p!=b) {
1648 return TRUE;
1649 }
1650 ++p;
1651 --length;
1652 }
1653 return FALSE;
1654}
1655
b75a7d8f
A
1656static void TestConvertSafeClone()
1657{
374ca955
A
1658 /* one 'regular' & all the 'private stateful' converters */
1659 static const char *const names[] = {
73c04bcf 1660#if !UCONFIG_NO_LEGACY_CONVERSION
374ca955
A
1661 "ibm-1047",
1662 "ISO_2022,locale=zh,version=1",
73c04bcf 1663#endif
374ca955 1664 "SCSU",
73c04bcf 1665#if !UCONFIG_NO_LEGACY_CONVERSION
374ca955
A
1666 "HZ",
1667 "lmbcs",
1668 "ISCII,version=0",
1669 "ISO_2022,locale=kr,version=1",
1670 "ISO_2022,locale=jp,version=2",
73c04bcf 1671#endif
374ca955
A
1672 "BOCU-1",
1673 "UTF-7",
73c04bcf 1674#if !UCONFIG_NO_LEGACY_CONVERSION
374ca955
A
1675 "IMAP-mailbox-name",
1676 "ibm-1047-s390"
73c04bcf
A
1677#else
1678 "IMAP=mailbox-name"
1679#endif
374ca955
A
1680 };
1681
73c04bcf
A
1682 /* store the actual sizes of each converter */
1683 int32_t actualSizes[LENGTHOF(names)];
1684
374ca955
A
1685 static const int32_t bufferSizes[] = {
1686 U_CNV_SAFECLONE_BUFFERSIZE,
1687 (int32_t)(3*sizeof(UConverter))/2, /* 1.5*sizeof(UConverter) */
1688 (int32_t)sizeof(UConverter)/2 /* 0.5*sizeof(UConverter) */
1689 };
b75a7d8f 1690
73c04bcf
A
1691 char charBuffer[21]; /* Leave at an odd number for alignment testing */
1692 uint8_t buffer[3] [U_CNV_SAFECLONE_BUFFERSIZE];
374ca955
A
1693 int32_t bufferSize, maxBufferSize;
1694 const char *maxName;
1695 UConverter * cnv, *cnv2;
1696 UErrorCode err;
b75a7d8f
A
1697
1698 char *pCharBuffer;
1699 const char *pConstCharBuffer;
1700 const char *charBufferLimit = charBuffer + sizeof(charBuffer)/sizeof(*charBuffer);
73c04bcf
A
1701 UChar uniBuffer[] = {0x0058, 0x0059, 0x005A}; /* "XYZ" */
1702 UChar uniCharBuffer[20];
1703 char charSourceBuffer[] = { 0x1b, 0x24, 0x42 };
b75a7d8f
A
1704 const char *pCharSource = charSourceBuffer;
1705 const char *pCharSourceLimit = charSourceBuffer + sizeof(charSourceBuffer);
1706 UChar *pUCharTarget = uniCharBuffer;
1707 UChar *pUCharTargetLimit = uniCharBuffer + sizeof(uniCharBuffer)/sizeof(*uniCharBuffer);
1708 const UChar * pUniBuffer;
1709 const UChar *uniBufferLimit = uniBuffer + sizeof(uniBuffer)/sizeof(*uniBuffer);
51004dcb 1710 int32_t idx, j;
b75a7d8f 1711
b75a7d8f 1712 err = U_ZERO_ERROR;
374ca955
A
1713 cnv = ucnv_open(names[0], &err);
1714 if(U_SUCCESS(err)) {
1715 /* Check the various error & informational states: */
b75a7d8f 1716
374ca955
A
1717 /* Null status - just returns NULL */
1718 bufferSize = U_CNV_SAFECLONE_BUFFERSIZE;
57a6839d 1719 if (NULL != ucnv_safeClone(cnv, buffer[0], &bufferSize, NULL))
374ca955
A
1720 {
1721 log_err("FAIL: Cloned converter failed to deal correctly with null status\n");
1722 }
1723 /* error status - should return 0 & keep error the same */
1724 err = U_MEMORY_ALLOCATION_ERROR;
57a6839d 1725 if (NULL != ucnv_safeClone(cnv, buffer[0], &bufferSize, &err) || err != U_MEMORY_ALLOCATION_ERROR)
374ca955
A
1726 {
1727 log_err("FAIL: Cloned converter failed to deal correctly with incoming error status\n");
1728 }
1729 err = U_ZERO_ERROR;
b75a7d8f 1730
57a6839d
A
1731 /* Null buffer size pointer is ok */
1732 if (NULL == (cnv2 = ucnv_safeClone(cnv, buffer[0], NULL, &err)) || U_FAILURE(err))
374ca955
A
1733 {
1734 log_err("FAIL: Cloned converter failed to deal correctly with null bufferSize pointer\n");
1735 }
57a6839d 1736 ucnv_close(cnv2);
374ca955 1737 err = U_ZERO_ERROR;
b75a7d8f 1738
374ca955
A
1739 /* buffer size pointer is 0 - fill in pbufferSize with a size */
1740 bufferSize = 0;
57a6839d 1741 if (NULL != ucnv_safeClone(cnv, buffer[0], &bufferSize, &err) || U_FAILURE(err) || bufferSize <= 0)
374ca955
A
1742 {
1743 log_err("FAIL: Cloned converter failed a sizing request ('preflighting')\n");
1744 }
1745 /* Verify our define is large enough */
1746 if (U_CNV_SAFECLONE_BUFFERSIZE < bufferSize)
1747 {
1748 log_err("FAIL: Pre-calculated buffer size is too small\n");
1749 }
1750 /* Verify we can use this run-time calculated size */
57a6839d 1751 if (NULL == (cnv2 = ucnv_safeClone(cnv, buffer[0], &bufferSize, &err)) || U_FAILURE(err))
374ca955
A
1752 {
1753 log_err("FAIL: Converter can't be cloned with run-time size\n");
1754 }
1755 if (cnv2) {
1756 ucnv_close(cnv2);
1757 }
1758
1759 /* size one byte too small - should allocate & let us know */
1760 --bufferSize;
57a6839d 1761 if (NULL == (cnv2 = ucnv_safeClone(cnv, NULL, &bufferSize, &err)) || err != U_SAFECLONE_ALLOCATED_WARNING)
374ca955
A
1762 {
1763 log_err("FAIL: Cloned converter failed to deal correctly with too-small buffer size\n");
1764 }
1765 if (cnv2) {
1766 ucnv_close(cnv2);
1767 }
1768
1769 err = U_ZERO_ERROR;
1770 bufferSize = U_CNV_SAFECLONE_BUFFERSIZE;
1771
1772 /* Null buffer pointer - return converter & set error to U_SAFECLONE_ALLOCATED_ERROR */
57a6839d 1773 if (NULL == (cnv2 = ucnv_safeClone(cnv, NULL, &bufferSize, &err)) || err != U_SAFECLONE_ALLOCATED_WARNING)
374ca955
A
1774 {
1775 log_err("FAIL: Cloned converter failed to deal correctly with null buffer pointer\n");
1776 }
1777 if (cnv2) {
1778 ucnv_close(cnv2);
1779 }
1780
1781 err = U_ZERO_ERROR;
b75a7d8f 1782
374ca955 1783 /* Null converter - return NULL & set U_ILLEGAL_ARGUMENT_ERROR */
57a6839d 1784 if (NULL != ucnv_safeClone(NULL, buffer[0], &bufferSize, &err) || err != U_ILLEGAL_ARGUMENT_ERROR)
374ca955
A
1785 {
1786 log_err("FAIL: Cloned converter failed to deal correctly with null converter pointer\n");
1787 }
1788
1789 ucnv_close(cnv);
b75a7d8f
A
1790 }
1791
374ca955
A
1792 maxBufferSize = 0;
1793 maxName = "";
b75a7d8f
A
1794
1795 /* Do these cloned converters work at all - shuffle UChars to chars & back again..*/
1796
374ca955 1797 for(j = 0; j < LENGTHOF(bufferSizes); ++j) {
51004dcb 1798 for (idx = 0; idx < LENGTHOF(names); idx++)
374ca955
A
1799 {
1800 err = U_ZERO_ERROR;
51004dcb 1801 cnv = ucnv_open(names[idx], &err);
374ca955 1802 if(U_FAILURE(err)) {
51004dcb 1803 log_data_err("ucnv_open(\"%s\") failed - %s\n", names[idx], u_errorName(err));
374ca955
A
1804 continue;
1805 }
b75a7d8f 1806
374ca955
A
1807 if(j == 0) {
1808 /* preflight to get maxBufferSize */
51004dcb
A
1809 actualSizes[idx] = 0;
1810 ucnv_safeClone(cnv, NULL, &actualSizes[idx], &err);
1811 if(actualSizes[idx] > maxBufferSize) {
1812 maxBufferSize = actualSizes[idx];
1813 maxName = names[idx];
374ca955
A
1814 }
1815 }
b75a7d8f 1816
374ca955 1817 memset(buffer, 0xaa, sizeof(buffer));
b75a7d8f 1818
374ca955
A
1819 bufferSize = bufferSizes[j];
1820 cnv2 = ucnv_safeClone(cnv, buffer[1], &bufferSize, &err);
b75a7d8f 1821
374ca955
A
1822 /* close the original immediately to make sure that the clone works by itself */
1823 ucnv_close(cnv);
b75a7d8f 1824
51004dcb 1825 if( actualSizes[idx] <= (bufferSizes[j] - (int32_t)sizeof(UAlignedMemory)) &&
73c04bcf
A
1826 err == U_SAFECLONE_ALLOCATED_WARNING
1827 ) {
51004dcb 1828 log_err("ucnv_safeClone(%s) did a heap clone although the buffer was large enough\n", names[idx]);
73c04bcf
A
1829 }
1830
374ca955
A
1831 /* check if the clone function overwrote any bytes that it is not supposed to touch */
1832 if(bufferSize <= bufferSizes[j]) {
1833 /* used the stack buffer */
1834 if( containsAnyOtherByte(buffer[0], (int32_t)sizeof(buffer[0]), 0xaa) ||
1835 containsAnyOtherByte(buffer[1]+bufferSize, (int32_t)(sizeof(buffer)-(sizeof(buffer[0])+bufferSize)), 0xaa)
1836 ) {
1837 log_err("cloning %s in a stack buffer overwrote bytes outside the bufferSize %d (requested %d)\n",
51004dcb 1838 names[idx], bufferSize, bufferSizes[j]);
374ca955
A
1839 }
1840 } else {
1841 /* heap-allocated the clone */
1842 if(containsAnyOtherByte(buffer[0], (int32_t)sizeof(buffer), 0xaa)) {
1843 log_err("cloning %s used the heap (bufferSize %d, requested %d) but overwrote stack buffer bytes\n",
51004dcb 1844 names[idx], bufferSize, bufferSizes[j]);
374ca955
A
1845 }
1846 }
1847
1848 pCharBuffer = charBuffer;
1849 pUniBuffer = uniBuffer;
1850
1851 ucnv_fromUnicode(cnv2,
1852 &pCharBuffer,
1853 charBufferLimit,
1854 &pUniBuffer,
1855 uniBufferLimit,
1856 NULL,
1857 TRUE,
1858 &err);
1859 if(U_FAILURE(err)){
1860 log_err("FAIL: cloned converter failed to do fromU conversion. Error: %s\n",u_errorName(err));
1861 }
1862 ucnv_toUnicode(cnv2,
1863 &pUCharTarget,
1864 pUCharTargetLimit,
1865 &pCharSource,
1866 pCharSourceLimit,
1867 NULL,
1868 TRUE,
1869 &err
1870 );
1871
1872 if(U_FAILURE(err)){
1873 log_err("FAIL: cloned converter failed to do toU conversion. Error: %s\n",u_errorName(err));
1874 }
1875
1876 pConstCharBuffer = charBuffer;
1877 if (uniBuffer [0] != ucnv_getNextUChar(cnv2, &pConstCharBuffer, pCharBuffer, &err))
1878 {
1879 log_err("FAIL: Cloned converter failed to do conversion. Error: %s\n",u_errorName(err));
1880 }
1881 ucnv_close(cnv2);
b75a7d8f 1882 }
b75a7d8f 1883 }
374ca955
A
1884
1885 log_verbose("ucnv_safeClone(): sizeof(UConverter)=%lu max preflighted clone size=%d (%s) U_CNV_SAFECLONE_BUFFERSIZE=%d\n",
1886 sizeof(UConverter), maxBufferSize, maxName, (int)U_CNV_SAFECLONE_BUFFERSIZE);
73c04bcf
A
1887 if(maxBufferSize > U_CNV_SAFECLONE_BUFFERSIZE) {
1888 log_err("ucnv_safeClone(): max preflighted clone size=%d (%s) is larger than U_CNV_SAFECLONE_BUFFERSIZE=%d\n",
1889 maxBufferSize, maxName, (int)U_CNV_SAFECLONE_BUFFERSIZE);
1890 }
b75a7d8f
A
1891}
1892
1893static void TestCCSID() {
73c04bcf 1894#if !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
1895 UConverter *cnv;
1896 UErrorCode errorCode;
374ca955 1897 int32_t ccsids[]={ 37, 850, 943, 949, 950, 1047, 1252, 1392, 33722 };
b75a7d8f
A
1898 int32_t i, ccsid;
1899
1900 for(i=0; i<(int32_t)(sizeof(ccsids)/sizeof(int32_t)); ++i) {
1901 ccsid=ccsids[i];
1902
1903 errorCode=U_ZERO_ERROR;
1904 cnv=ucnv_openCCSID(ccsid, UCNV_IBM, &errorCode);
1905 if(U_FAILURE(errorCode)) {
374ca955 1906 log_data_err("error: ucnv_openCCSID(%ld) failed (%s)\n", ccsid, u_errorName(errorCode));
b75a7d8f
A
1907 continue;
1908 }
1909
1910 if(ccsid!=ucnv_getCCSID(cnv, &errorCode)) {
1911 log_err("error: ucnv_getCCSID(ucnv_openCCSID(%ld))=%ld\n", ccsid, ucnv_getCCSID(cnv, &errorCode));
1912 }
1913
374ca955
A
1914 /* skip gb18030(ccsid 1392) */
1915 if(ccsid != 1392 && UCNV_IBM!=ucnv_getPlatform(cnv, &errorCode)) {
b75a7d8f
A
1916 log_err("error: ucnv_getPlatform(ucnv_openCCSID(%ld))=%ld!=UCNV_IBM\n", ccsid, ucnv_getPlatform(cnv, &errorCode));
1917 }
1918
1919 ucnv_close(cnv);
1920 }
73c04bcf 1921#endif
b75a7d8f
A
1922}
1923
1924/* jitterbug 932: ucnv_convert() bugs --------------------------------------- */
1925
1926/* CHUNK_SIZE defined in common\ucnv.c: */
1927#define CHUNK_SIZE 1024
1928
1929static void bug1(void);
1930static void bug2(void);
1931static void bug3(void);
1932
1933static void
1934TestJ932(void)
1935{
1936 bug1(); /* Unicode intermediate buffer straddle bug */
1937 bug2(); /* pre-flighting size incorrect caused by simple overflow */
1938 bug3(); /* pre-flighting size incorrect caused by expansion overflow */
1939}
1940
1941/*
1942 * jitterbug 932: test chunking boundary conditions in
1943
1944 int32_t ucnv_convert(const char *toConverterName,
1945 const char *fromConverterName,
1946 char *target,
1947 int32_t targetSize,
1948 const char *source,
1949 int32_t sourceSize,
1950 UErrorCode * err)
1951
1952 * See discussions on the icu mailing list in
1953 * 2001-April with the subject "converter 'flush' question".
1954 *
1955 * Bug report and test code provided by Edward J. Batutis.
1956 */
1957static void bug1()
1958{
73c04bcf 1959#if !UCONFIG_NO_LEGACY_CONVERSION
46f4442e
A
1960 char char_in[CHUNK_SIZE+32];
1961 char char_out[CHUNK_SIZE*2];
b75a7d8f
A
1962
1963 /* GB 18030 equivalent of U+10000 is 90308130 */
1964 static const char test_seq[]={ (char)0x90u, 0x30, (char)0x81u, 0x30 };
1965
1966 UErrorCode err = U_ZERO_ERROR;
1967 int32_t i, test_seq_len = sizeof(test_seq);
1968
1969 /*
1970 * causes straddle bug in Unicode intermediate buffer by sliding the test sequence forward
1971 * until the straddle bug appears. I didn't want to hard-code everything so this test could
1972 * be expanded - however this is the only type of straddle bug I can think of at the moment -
1973 * a high surrogate in the last position of the Unicode intermediate buffer. Apparently no
1974 * other Unicode sequences cause a bug since combining sequences are not supported by the
1975 * converters.
1976 */
1977
1978 for (i = test_seq_len; i >= 0; i--) {
1979 /* put character sequence into input buffer */
1980 memset(char_in, 0x61, sizeof(char_in)); /* GB 18030 'a' */
1981 memcpy(char_in + (CHUNK_SIZE - i), test_seq, test_seq_len);
1982
1983 /* do the conversion */
1984 ucnv_convert("us-ascii", /* out */
1985 "gb18030", /* in */
1986 char_out,
1987 sizeof(char_out),
1988 char_in,
1989 sizeof(char_in),
1990 &err);
1991
1992 /* bug1: */
1993 if (err == U_TRUNCATED_CHAR_FOUND) {
1994 /* this happens when surrogate pair straddles the intermediate buffer in
1995 * T_UConverter_fromCodepageToCodepage */
1996 log_err("error j932 bug 1: expected success, got U_TRUNCATED_CHAR_FOUND\n");
1997 }
1998 }
73c04bcf 1999#endif
b75a7d8f
A
2000}
2001
2002/* bug2: pre-flighting loop bug: simple overflow causes bug */
2003static void bug2()
2004{
2005 /* US-ASCII "1234567890" */
2006 static const char source[]={ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39 };
2007 static const char sourceUTF8[]={ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, (char)0xef, (char)0x80, (char)0x80 };
2008 static const char sourceUTF32[]={ 0x00, 0x00, 0x00, 0x30,
2009 0x00, 0x00, 0x00, 0x31,
2010 0x00, 0x00, 0x00, 0x32,
2011 0x00, 0x00, 0x00, 0x33,
2012 0x00, 0x00, 0x00, 0x34,
2013 0x00, 0x00, 0x00, 0x35,
2014 0x00, 0x00, 0x00, 0x36,
2015 0x00, 0x00, 0x00, 0x37,
2016 0x00, 0x00, 0x00, 0x38,
2017 0x00, 0x00, (char)0xf0, 0x00};
2018 static char target[5];
2019
2020 UErrorCode err = U_ZERO_ERROR;
2021 int32_t size;
2022
2023 /* do the conversion */
2024 size = ucnv_convert("iso-8859-1", /* out */
2025 "us-ascii", /* in */
2026 target,
2027 sizeof(target),
2028 source,
2029 sizeof(source),
2030 &err);
2031
2032 if ( size != 10 ) {
2033 /* bug2: size is 5, should be 10 */
2034 log_data_err("error j932 bug 2 us-ascii->iso-8859-1: got preflighting size %d instead of 10\n", size);
2035 }
2036
2037 err = U_ZERO_ERROR;
2038 /* do the conversion */
2039 size = ucnv_convert("UTF-32BE", /* out */
2040 "UTF-8", /* in */
2041 target,
2042 sizeof(target),
2043 sourceUTF8,
2044 sizeof(sourceUTF8),
2045 &err);
2046
2047 if ( size != 32 ) {
2048 /* bug2: size is 5, should be 32 */
2049 log_err("error j932 bug 2 UTF-8->UTF-32BE: got preflighting size %d instead of 32\n", size);
2050 }
2051
2052 err = U_ZERO_ERROR;
2053 /* do the conversion */
2054 size = ucnv_convert("UTF-8", /* out */
2055 "UTF-32BE", /* in */
2056 target,
2057 sizeof(target),
2058 sourceUTF32,
2059 sizeof(sourceUTF32),
2060 &err);
2061
2062 if ( size != 12 ) {
2063 /* bug2: size is 5, should be 12 */
2064 log_err("error j932 bug 2 UTF-32BE->UTF-8: got preflighting size %d instead of 12\n", size);
2065 }
2066}
2067
2068/*
2069 * bug3: when the characters expand going from source to target codepage
2070 * you get bug3 in addition to bug2
2071 */
2072static void bug3()
2073{
73c04bcf 2074#if !UCONFIG_NO_LEGACY_CONVERSION
46f4442e
A
2075 char char_in[CHUNK_SIZE*4];
2076 char target[5];
b75a7d8f
A
2077 UErrorCode err = U_ZERO_ERROR;
2078 int32_t size;
2079
2080 /*
2081 * first get the buggy size from bug2 then
2082 * compare it to buggy size with an expansion
2083 */
2084 memset(char_in, 0x61, sizeof(char_in)); /* US-ASCII 'a' */
2085
2086 /* do the conversion */
2087 size = ucnv_convert("lmbcs", /* out */
2088 "us-ascii", /* in */
2089 target,
2090 sizeof(target),
2091 char_in,
2092 sizeof(char_in),
2093 &err);
2094
2095 if ( size != sizeof(char_in) ) {
2096 /*
2097 * bug2: size is 0x2805 (CHUNK_SIZE*2+5 - maybe 5 is the size of the overflow buffer
2098 * in the converter?), should be CHUNK_SIZE*4
2099 *
2100 * Markus 2001-05-18: 5 is the size of our target[] here, ucnv_convert() did not reset targetSize...
2101 */
2102 log_data_err("error j932 bug 2/3a: expected preflighting size 0x%04x, got 0x%04x\n", sizeof(char_in), size);
2103 }
2104
2105 /*
2106 * now do the conversion with expansion
2107 * ascii 0x08 expands to 0x0F 0x28 in lmbcs
2108 */
2109 memset(char_in, 8, sizeof(char_in));
2110 err = U_ZERO_ERROR;
2111
2112 /* do the conversion */
2113 size = ucnv_convert("lmbcs", /* out */
2114 "us-ascii", /* in */
2115 target,
2116 sizeof(target),
2117 char_in,
2118 sizeof(char_in),
2119 &err);
2120
2121 /* expect 2X expansion */
2122 if ( size != sizeof(char_in) * 2 ) {
2123 /*
2124 * bug3:
2125 * bug2 would lead us to expect 0x2805, but it isn't that either, it is 0x3c05:
2126 */
2127 log_data_err("error j932 bug 3b: expected 0x%04x, got 0x%04x\n", sizeof(char_in) * 2, size);
2128 }
73c04bcf 2129#endif
b75a7d8f
A
2130}
2131
2132static void
2133convertExStreaming(UConverter *srcCnv, UConverter *targetCnv,
2134 const char *src, int32_t srcLength,
2135 const char *expectTarget, int32_t expectTargetLength,
2136 int32_t chunkSize,
2137 const char *testName,
2138 UErrorCode expectCode) {
2139 UChar pivotBuffer[CHUNK_SIZE];
2140 UChar *pivotSource, *pivotTarget;
2141 const UChar *pivotLimit;
2142
2143 char targetBuffer[CHUNK_SIZE];
2144 char *target;
2145 const char *srcLimit, *finalSrcLimit, *targetLimit;
2146
2147 int32_t targetLength;
2148
2149 UBool flush;
2150
2151 UErrorCode errorCode;
2152
2153 /* setup */
2154 if(chunkSize>CHUNK_SIZE) {
2155 chunkSize=CHUNK_SIZE;
2156 }
2157
2158 pivotSource=pivotTarget=pivotBuffer;
2159 pivotLimit=pivotBuffer+chunkSize;
2160
2161 finalSrcLimit=src+srcLength;
2162 target=targetBuffer;
2163 targetLimit=targetBuffer+chunkSize;
2164
2165 ucnv_resetToUnicode(srcCnv);
2166 ucnv_resetFromUnicode(targetCnv);
2167
2168 errorCode=U_ZERO_ERROR;
2169 flush=FALSE;
2170
2171 /* convert, streaming-style (both converters and pivot keep state) */
2172 for(;;) {
2173 /* for testing, give ucnv_convertEx() at most <chunkSize> input/pivot/output units at a time */
2174 if(src+chunkSize<=finalSrcLimit) {
2175 srcLimit=src+chunkSize;
2176 } else {
2177 srcLimit=finalSrcLimit;
2178 }
2179 ucnv_convertEx(targetCnv, srcCnv,
2180 &target, targetLimit,
2181 &src, srcLimit,
2182 pivotBuffer, &pivotSource, &pivotTarget, pivotLimit,
2183 FALSE, flush, &errorCode);
2184 targetLength=(int32_t)(target-targetBuffer);
46f4442e
A
2185 if(target>targetLimit) {
2186 log_err("ucnv_convertEx(%s) chunk[%d] target %p exceeds targetLimit %p\n",
2187 testName, chunkSize, target, targetLimit);
2188 break; /* TODO: major problem! */
2189 }
b75a7d8f
A
2190 if(errorCode==U_BUFFER_OVERFLOW_ERROR) {
2191 /* continue converting another chunk */
2192 errorCode=U_ZERO_ERROR;
2193 if(targetLength+chunkSize<=sizeof(targetBuffer)) {
2194 targetLimit=target+chunkSize;
2195 } else {
2196 targetLimit=targetBuffer+sizeof(targetBuffer);
2197 }
2198 } else if(U_FAILURE(errorCode)) {
2199 /* failure */
2200 break;
2201 } else if(flush) {
2202 /* all done */
2203 break;
2204 } else if(src==finalSrcLimit && pivotSource==pivotTarget) {
2205 /* all consumed, now flush without input (separate from conversion for testing) */
2206 flush=TRUE;
2207 }
2208 }
2209
2210 if(!(errorCode==expectCode || (expectCode==U_ZERO_ERROR && errorCode==U_STRING_NOT_TERMINATED_WARNING))) {
2211 log_err("ucnv_convertEx(%s) chunk[%d] results in %s instead of %s\n",
2212 testName, chunkSize, u_errorName(errorCode), u_errorName(expectCode));
2213 } else if(targetLength!=expectTargetLength) {
2214 log_err("ucnv_convertEx(%s) chunk[%d] writes %d bytes instead of %d\n",
2215 testName, chunkSize, targetLength, expectTargetLength);
2216 } else if(memcmp(targetBuffer, expectTarget, targetLength)!=0) {
2217 log_err("ucnv_convertEx(%s) chunk[%d] writes different bytes than expected\n",
2218 testName, chunkSize);
2219 }
2220}
2221
2222static void
2223convertExMultiStreaming(UConverter *srcCnv, UConverter *targetCnv,
2224 const char *src, int32_t srcLength,
2225 const char *expectTarget, int32_t expectTargetLength,
2226 const char *testName,
2227 UErrorCode expectCode) {
2228 convertExStreaming(srcCnv, targetCnv,
2229 src, srcLength,
2230 expectTarget, expectTargetLength,
2231 1, testName, expectCode);
2232 convertExStreaming(srcCnv, targetCnv,
2233 src, srcLength,
2234 expectTarget, expectTargetLength,
2235 3, testName, expectCode);
2236 convertExStreaming(srcCnv, targetCnv,
2237 src, srcLength,
2238 expectTarget, expectTargetLength,
2239 7, testName, expectCode);
2240}
2241
2242static void TestConvertEx() {
73c04bcf 2243#if !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
2244 static const uint8_t
2245 utf8[]={
2246 /* 4e00 30a1 ff61 0410 */
2247 0xe4, 0xb8, 0x80, 0xe3, 0x82, 0xa1, 0xef, 0xbd, 0xa1, 0xd0, 0x90
2248 },
2249 shiftJIS[]={
2250 0x88, 0xea, 0x83, 0x40, 0xa1, 0x84, 0x40
2251 },
2252 errorTarget[]={
2253 /*
2254 * expected output when converting shiftJIS[] from UTF-8 to Shift-JIS:
2255 * SUB, SUB, 0x40, SUB, SUB, 0x40
2256 */
374ca955 2257 0xfc, 0xfc, 0xfc, 0xfc, 0x40, 0xfc, 0xfc, 0xfc, 0xfc, 0x40
b75a7d8f
A
2258 };
2259
2260 char srcBuffer[100], targetBuffer[100];
2261
2262 const char *src;
2263 char *target;
2264
2265 UChar pivotBuffer[100];
2266 UChar *pivotSource, *pivotTarget;
2267
2268 UConverter *cnv1, *cnv2;
2269 UErrorCode errorCode;
2270
2271 errorCode=U_ZERO_ERROR;
2272 cnv1=ucnv_open("UTF-8", &errorCode);
2273 if(U_FAILURE(errorCode)) {
2274 log_err("unable to open a UTF-8 converter - %s\n", u_errorName(errorCode));
2275 return;
2276 }
2277
2278 cnv2=ucnv_open("Shift-JIS", &errorCode);
2279 if(U_FAILURE(errorCode)) {
2280 log_data_err("unable to open a Shift-JIS converter - %s\n", u_errorName(errorCode));
2281 ucnv_close(cnv1);
2282 return;
2283 }
2284
2285 /* test ucnv_convertEx() with streaming conversion style */
2286 convertExMultiStreaming(cnv1, cnv2,
2287 (const char *)utf8, sizeof(utf8), (const char *)shiftJIS, sizeof(shiftJIS),
2288 "UTF-8 -> Shift-JIS", U_ZERO_ERROR);
2289
2290 convertExMultiStreaming(cnv2, cnv1,
2291 (const char *)shiftJIS, sizeof(shiftJIS), (const char *)utf8, sizeof(utf8),
2292 "Shift-JIS -> UTF-8", U_ZERO_ERROR);
2293
2294 /* U_ZERO_ERROR because by default the SUB callbacks are set */
2295 convertExMultiStreaming(cnv1, cnv2,
2296 (const char *)shiftJIS, sizeof(shiftJIS), (const char *)errorTarget, sizeof(errorTarget),
2297 "shiftJIS[] UTF-8 -> Shift-JIS", U_ZERO_ERROR);
2298
2299 /* test some simple conversions */
2300
2301 /* NUL-terminated source and target */
2302 errorCode=U_STRING_NOT_TERMINATED_WARNING;
2303 memcpy(srcBuffer, utf8, sizeof(utf8));
2304 srcBuffer[sizeof(utf8)]=0;
2305 src=srcBuffer;
2306 target=targetBuffer;
2307 ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
2308 NULL, NULL, NULL, NULL, TRUE, TRUE, &errorCode);
2309 if( errorCode!=U_ZERO_ERROR ||
2310 target-targetBuffer!=sizeof(shiftJIS) ||
2311 *target!=0 ||
2312 memcmp(targetBuffer, shiftJIS, sizeof(shiftJIS))!=0
2313 ) {
2314 log_err("ucnv_convertEx(simple UTF-8 -> Shift_JIS) fails: %s - writes %d bytes, expect %d\n",
2315 u_errorName(errorCode), target-targetBuffer, sizeof(shiftJIS));
2316 }
2317
2318 /* NUL-terminated source and U_STRING_NOT_TERMINATED_WARNING */
2319 errorCode=U_AMBIGUOUS_ALIAS_WARNING;
2320 memset(targetBuffer, 0xff, sizeof(targetBuffer));
2321 src=srcBuffer;
2322 target=targetBuffer;
2323 ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(shiftJIS), &src, NULL,
2324 NULL, NULL, NULL, NULL, TRUE, TRUE, &errorCode);
2325 if( errorCode!=U_STRING_NOT_TERMINATED_WARNING ||
2326 target-targetBuffer!=sizeof(shiftJIS) ||
2327 *target!=(char)0xff ||
2328 memcmp(targetBuffer, shiftJIS, sizeof(shiftJIS))!=0
2329 ) {
2330 log_err("ucnv_convertEx(simple UTF-8 -> Shift_JIS) fails: %s, expect U_STRING_NOT_TERMINATED_WARNING - writes %d bytes, expect %d\n",
2331 u_errorName(errorCode), target-targetBuffer, sizeof(shiftJIS));
2332 }
2333
2334 /* bad arguments */
2335 errorCode=U_MESSAGE_PARSE_ERROR;
2336 src=srcBuffer;
2337 target=targetBuffer;
2338 ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
2339 NULL, NULL, NULL, NULL, TRUE, TRUE, &errorCode);
2340 if(errorCode!=U_MESSAGE_PARSE_ERROR) {
2341 log_err("ucnv_convertEx(U_MESSAGE_PARSE_ERROR) sets %s\n", u_errorName(errorCode));
2342 }
2343
2344 /* pivotLimit==pivotStart */
2345 errorCode=U_ZERO_ERROR;
2346 pivotSource=pivotTarget=pivotBuffer;
2347 ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
2348 pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer, TRUE, TRUE, &errorCode);
2349 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
2350 log_err("ucnv_convertEx(pivotLimit==pivotStart) sets %s\n", u_errorName(errorCode));
2351 }
2352
2353 /* *pivotSource==NULL */
2354 errorCode=U_ZERO_ERROR;
2355 pivotSource=NULL;
2356 ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
2357 pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer+1, TRUE, TRUE, &errorCode);
2358 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
2359 log_err("ucnv_convertEx(*pivotSource==NULL) sets %s\n", u_errorName(errorCode));
2360 }
2361
2362 /* *source==NULL */
2363 errorCode=U_ZERO_ERROR;
2364 src=NULL;
2365 pivotSource=pivotBuffer;
2366 ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
2367 pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer+1, TRUE, TRUE, &errorCode);
2368 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
2369 log_err("ucnv_convertEx(*source==NULL) sets %s\n", u_errorName(errorCode));
2370 }
2371
73c04bcf
A
2372 /* streaming conversion without a pivot buffer */
2373 errorCode=U_ZERO_ERROR;
2374 src=srcBuffer;
2375 pivotSource=pivotBuffer;
2376 ucnv_convertEx(cnv2, cnv1, &target, targetBuffer+sizeof(targetBuffer), &src, NULL,
2377 NULL, &pivotSource, &pivotTarget, pivotBuffer+1, TRUE, FALSE, &errorCode);
2378 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
2379 log_err("ucnv_convertEx(pivotStart==NULL) sets %s\n", u_errorName(errorCode));
2380 }
2381
b75a7d8f
A
2382 ucnv_close(cnv1);
2383 ucnv_close(cnv2);
73c04bcf 2384#endif
b75a7d8f
A
2385}
2386
46f4442e
A
2387/* Test illegal UTF-8 input: Data and functions for TestConvertExFromUTF8(). */
2388static const char *const badUTF8[]={
2389 /* trail byte */
2390 "\x80",
2391
2392 /* truncated multi-byte sequences */
2393 "\xd0",
2394 "\xe0",
2395 "\xe1",
2396 "\xed",
2397 "\xee",
2398 "\xf0",
2399 "\xf1",
2400 "\xf4",
2401 "\xf8",
2402 "\xfc",
2403
2404 "\xe0\x80",
2405 "\xe0\xa0",
2406 "\xe1\x80",
2407 "\xed\x80",
2408 "\xed\xa0",
2409 "\xee\x80",
2410 "\xf0\x80",
2411 "\xf0\x90",
2412 "\xf1\x80",
2413 "\xf4\x80",
2414 "\xf4\x90",
2415 "\xf8\x80",
2416 "\xfc\x80",
2417
2418 "\xf0\x80\x80",
2419 "\xf0\x90\x80",
2420 "\xf1\x80\x80",
2421 "\xf4\x80\x80",
2422 "\xf4\x90\x80",
2423 "\xf8\x80\x80",
2424 "\xfc\x80\x80",
2425
2426 "\xf8\x80\x80\x80",
2427 "\xfc\x80\x80\x80",
2428
2429 "\xfc\x80\x80\x80\x80",
2430
2431 /* complete sequences but non-shortest forms or out of range etc. */
2432 "\xc0\x80",
2433 "\xe0\x80\x80",
2434 "\xed\xa0\x80",
2435 "\xf0\x80\x80\x80",
2436 "\xf4\x90\x80\x80",
2437 "\xf8\x80\x80\x80\x80",
2438 "\xfc\x80\x80\x80\x80\x80",
2439 "\xfe",
2440 "\xff"
2441};
2442
4388f060
A
2443#define ARG_CHAR_ARR_SIZE 8
2444
46f4442e
A
2445/* get some character that can be converted and convert it */
2446static UBool getTestChar(UConverter *cnv, const char *converterName,
2447 char charUTF8[4], int32_t *pCharUTF8Length,
4388f060
A
2448 char char0[ARG_CHAR_ARR_SIZE], int32_t *pChar0Length,
2449 char char1[ARG_CHAR_ARR_SIZE], int32_t *pChar1Length) {
46f4442e
A
2450 UChar utf16[U16_MAX_LENGTH];
2451 int32_t utf16Length;
2452
2453 const UChar *utf16Source;
2454 char *target;
2455
2456 USet *set;
2457 UChar32 c;
2458 UErrorCode errorCode;
2459
2460 errorCode=U_ZERO_ERROR;
2461 set=uset_open(1, 0);
2462 ucnv_getUnicodeSet(cnv, set, UCNV_ROUNDTRIP_SET, &errorCode);
2463 c=uset_charAt(set, uset_size(set)/2);
2464 uset_close(set);
2465
2466 utf16Length=0;
2467 U16_APPEND_UNSAFE(utf16, utf16Length, c);
2468 *pCharUTF8Length=0;
2469 U8_APPEND_UNSAFE(charUTF8, *pCharUTF8Length, c);
2470
2471 utf16Source=utf16;
2472 target=char0;
2473 ucnv_fromUnicode(cnv,
4388f060 2474 &target, char0+ARG_CHAR_ARR_SIZE,
46f4442e
A
2475 &utf16Source, utf16+utf16Length,
2476 NULL, FALSE, &errorCode);
2477 *pChar0Length=(int32_t)(target-char0);
2478
2479 utf16Source=utf16;
2480 target=char1;
2481 ucnv_fromUnicode(cnv,
4388f060 2482 &target, char1+ARG_CHAR_ARR_SIZE,
46f4442e
A
2483 &utf16Source, utf16+utf16Length,
2484 NULL, FALSE, &errorCode);
2485 *pChar1Length=(int32_t)(target-char1);
2486
2487 if(U_FAILURE(errorCode)) {
2488 log_err("unable to get test character for %s - %s\n", converterName, u_errorName(errorCode));
2489 return FALSE;
2490 }
2491 return TRUE;
2492}
2493
2494static void testFromTruncatedUTF8(UConverter *utf8Cnv, UConverter *cnv, const char *converterName,
2495 char charUTF8[4], int32_t charUTF8Length,
2496 char char0[8], int32_t char0Length,
2497 char char1[8], int32_t char1Length) {
2498 char utf8[16];
2499 int32_t utf8Length;
2500
2501 char output[16];
2502 int32_t outputLength;
2503
2504 char invalidChars[8];
2505 int8_t invalidLength;
2506
2507 const char *source;
2508 char *target;
2509
2510 UChar pivotBuffer[8];
2511 UChar *pivotSource, *pivotTarget;
2512
2513 UErrorCode errorCode;
2514 int32_t i;
2515
2516 /* test truncated sequences */
2517 errorCode=U_ZERO_ERROR;
2518 ucnv_setToUCallBack(utf8Cnv, UCNV_TO_U_CALLBACK_STOP, NULL, NULL, NULL, &errorCode);
2519
2520 memcpy(utf8, charUTF8, charUTF8Length);
2521
2522 for(i=0; i<LENGTHOF(badUTF8); ++i) {
2523 /* truncated sequence? */
2524 int32_t length=strlen(badUTF8[i]);
2525 if(length>=(1+U8_COUNT_TRAIL_BYTES(badUTF8[i][0]))) {
2526 continue;
2527 }
2528
2529 /* assemble a string with the test character and the truncated sequence */
2530 memcpy(utf8+charUTF8Length, badUTF8[i], length);
2531 utf8Length=charUTF8Length+length;
2532
2533 /* convert and check the invalidChars */
2534 source=utf8;
2535 target=output;
2536 pivotSource=pivotTarget=pivotBuffer;
2537 errorCode=U_ZERO_ERROR;
2538 ucnv_convertEx(cnv, utf8Cnv,
2539 &target, output+sizeof(output),
2540 &source, utf8+utf8Length,
2541 pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer+LENGTHOF(pivotBuffer),
2542 TRUE, TRUE, /* reset & flush */
2543 &errorCode);
2544 outputLength=(int32_t)(target-output);
57a6839d 2545 (void)outputLength; /* Suppress set but not used warning. */
46f4442e
A
2546 if(errorCode!=U_TRUNCATED_CHAR_FOUND || pivotSource!=pivotBuffer) {
2547 log_err("unexpected error %s from %s badUTF8[%ld]\n", u_errorName(errorCode), converterName, (long)i);
2548 continue;
2549 }
2550
2551 errorCode=U_ZERO_ERROR;
2552 invalidLength=(int8_t)sizeof(invalidChars);
2553 ucnv_getInvalidChars(utf8Cnv, invalidChars, &invalidLength, &errorCode);
2554 if(invalidLength!=length || 0!=memcmp(invalidChars, badUTF8[i], length)) {
2555 log_err("wrong invalidChars from %s badUTF8[%ld]\n", converterName, (long)i);
2556 }
2557 }
2558}
2559
2560static void testFromBadUTF8(UConverter *utf8Cnv, UConverter *cnv, const char *converterName,
2561 char charUTF8[4], int32_t charUTF8Length,
2562 char char0[8], int32_t char0Length,
2563 char char1[8], int32_t char1Length) {
2564 char utf8[600], expect[600];
2565 int32_t utf8Length, expectLength;
2566
2567 char testName[32];
2568
2569 UErrorCode errorCode;
2570 int32_t i;
2571
2572 errorCode=U_ZERO_ERROR;
2573 ucnv_setToUCallBack(utf8Cnv, UCNV_TO_U_CALLBACK_SKIP, NULL, NULL, NULL, &errorCode);
2574
2575 /*
2576 * assemble an input string with the test character between each
2577 * bad sequence,
2578 * and an expected string with repeated test character output
2579 */
2580 memcpy(utf8, charUTF8, charUTF8Length);
2581 utf8Length=charUTF8Length;
2582
2583 memcpy(expect, char0, char0Length);
2584 expectLength=char0Length;
2585
2586 for(i=0; i<LENGTHOF(badUTF8); ++i) {
2587 int32_t length=strlen(badUTF8[i]);
2588 memcpy(utf8+utf8Length, badUTF8[i], length);
2589 utf8Length+=length;
2590
2591 memcpy(utf8+utf8Length, charUTF8, charUTF8Length);
2592 utf8Length+=charUTF8Length;
2593
2594 memcpy(expect+expectLength, char1, char1Length);
2595 expectLength+=char1Length;
2596 }
2597
2598 /* expect that each bad UTF-8 sequence is detected and skipped */
2599 strcpy(testName, "from bad UTF-8 to ");
2600 strcat(testName, converterName);
2601
2602 convertExMultiStreaming(utf8Cnv, cnv,
2603 utf8, utf8Length,
2604 expect, expectLength,
2605 testName,
2606 U_ZERO_ERROR);
2607}
2608
2609/* Test illegal UTF-8 input. */
2610static void TestConvertExFromUTF8() {
2611 static const char *const converterNames[]={
2612#if !UCONFIG_NO_LEGACY_CONVERSION
2613 "windows-1252",
2614 "shift-jis",
2615#endif
2616 "us-ascii",
2617 "iso-8859-1",
2618 "utf-8"
2619 };
2620
2621 UConverter *utf8Cnv, *cnv;
2622 UErrorCode errorCode;
2623 int32_t i;
2624
2625 /* fromUnicode versions of some character, from initial state and later */
2626 char charUTF8[4], char0[8], char1[8];
2627 int32_t charUTF8Length, char0Length, char1Length;
2628
2629 errorCode=U_ZERO_ERROR;
2630 utf8Cnv=ucnv_open("UTF-8", &errorCode);
2631 if(U_FAILURE(errorCode)) {
729e4ab9 2632 log_data_err("unable to open UTF-8 converter - %s\n", u_errorName(errorCode));
46f4442e
A
2633 return;
2634 }
2635
2636 for(i=0; i<LENGTHOF(converterNames); ++i) {
2637 errorCode=U_ZERO_ERROR;
2638 cnv=ucnv_open(converterNames[i], &errorCode);
2639 if(U_FAILURE(errorCode)) {
729e4ab9 2640 log_data_err("unable to open %s converter - %s\n", converterNames[i], u_errorName(errorCode));
46f4442e
A
2641 continue;
2642 }
2643 if(!getTestChar(cnv, converterNames[i], charUTF8, &charUTF8Length, char0, &char0Length, char1, &char1Length)) {
2644 continue;
2645 }
2646 testFromTruncatedUTF8(utf8Cnv, cnv, converterNames[i], charUTF8, charUTF8Length, char0, char0Length, char1, char1Length);
2647 testFromBadUTF8(utf8Cnv, cnv, converterNames[i], charUTF8, charUTF8Length, char0, char0Length, char1, char1Length);
2648 ucnv_close(cnv);
2649 }
2650 ucnv_close(utf8Cnv);
2651}
2652
729e4ab9
A
2653static void TestConvertExFromUTF8_C5F0() {
2654 static const char *const converterNames[]={
2655#if !UCONFIG_NO_LEGACY_CONVERSION
2656 "windows-1251",
2657 "shift-jis",
2658#endif
2659 "us-ascii",
2660 "iso-8859-1",
2661 "utf-8"
2662 };
2663
2664 UConverter *utf8Cnv, *cnv;
2665 UErrorCode errorCode;
2666 int32_t i;
2667
2668 static const char bad_utf8[2]={ (char)0xC5, (char)0xF0 };
2669 /* Expect "&#65533;&#65533;" (2x U+FFFD as decimal NCRs) */
2670 static const char twoNCRs[16]={
2671 0x26, 0x23, 0x36, 0x35, 0x35, 0x33, 0x33, 0x3B,
2672 0x26, 0x23, 0x36, 0x35, 0x35, 0x33, 0x33, 0x3B
2673 };
2674 static const char twoFFFD[6]={
2675 (char)0xef, (char)0xbf, (char)0xbd,
2676 (char)0xef, (char)0xbf, (char)0xbd
2677 };
2678 const char *expected;
2679 int32_t expectedLength;
2680 char dest[20]; /* longer than longest expectedLength */
2681
2682 const char *src;
2683 char *target;
2684
2685 UChar pivotBuffer[128];
2686 UChar *pivotSource, *pivotTarget;
2687
2688 errorCode=U_ZERO_ERROR;
2689 utf8Cnv=ucnv_open("UTF-8", &errorCode);
2690 if(U_FAILURE(errorCode)) {
2691 log_data_err("unable to open UTF-8 converter - %s\n", u_errorName(errorCode));
2692 return;
2693 }
2694
2695 for(i=0; i<LENGTHOF(converterNames); ++i) {
2696 errorCode=U_ZERO_ERROR;
2697 cnv=ucnv_open(converterNames[i], &errorCode);
2698 ucnv_setFromUCallBack(cnv, UCNV_FROM_U_CALLBACK_ESCAPE, UCNV_ESCAPE_XML_DEC,
2699 NULL, NULL, &errorCode);
2700 if(U_FAILURE(errorCode)) {
2701 log_data_err("unable to open %s converter - %s\n",
2702 converterNames[i], u_errorName(errorCode));
2703 continue;
2704 }
2705 src=bad_utf8;
2706 target=dest;
2707 uprv_memset(dest, 9, sizeof(dest));
2708 if(i==LENGTHOF(converterNames)-1) {
2709 /* conversion to UTF-8 yields two U+FFFD directly */
2710 expected=twoFFFD;
2711 expectedLength=6;
2712 } else {
2713 /* conversion to a non-Unicode charset yields two NCRs */
2714 expected=twoNCRs;
2715 expectedLength=16;
2716 }
2717 pivotBuffer[0]=0;
2718 pivotBuffer[1]=1;
2719 pivotBuffer[2]=2;
2720 pivotSource=pivotTarget=pivotBuffer;
2721 ucnv_convertEx(
2722 cnv, utf8Cnv,
2723 &target, dest+expectedLength,
2724 &src, bad_utf8+sizeof(bad_utf8),
2725 pivotBuffer, &pivotSource, &pivotTarget, pivotBuffer+LENGTHOF(pivotBuffer),
2726 TRUE, TRUE, &errorCode);
2727 if( errorCode!=U_STRING_NOT_TERMINATED_WARNING || src!=bad_utf8+2 ||
2728 target!=dest+expectedLength || 0!=uprv_memcmp(dest, expected, expectedLength) ||
2729 dest[expectedLength]!=9
2730 ) {
2731 log_err("ucnv_convertEx(UTF-8 C5 F0 -> %s/decimal NCRs) failed\n", converterNames[i]);
2732 }
2733 ucnv_close(cnv);
2734 }
2735 ucnv_close(utf8Cnv);
2736}
2737
b75a7d8f
A
2738static void
2739TestConvertAlgorithmic() {
73c04bcf 2740#if !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
2741 static const uint8_t
2742 utf8[]={
2743 /* 4e00 30a1 ff61 0410 */
2744 0xe4, 0xb8, 0x80, 0xe3, 0x82, 0xa1, 0xef, 0xbd, 0xa1, 0xd0, 0x90
2745 },
2746 shiftJIS[]={
2747 0x88, 0xea, 0x83, 0x40, 0xa1, 0x84, 0x40
2748 },
2749 /*errorTarget[]={*/
2750 /*
2751 * expected output when converting shiftJIS[] from UTF-8 to Shift-JIS:
2752 * SUB, SUB, 0x40, SUB, SUB, 0x40
2753 */
2754 /* 0x81, 0xa1, 0x81, 0xa1, 0x40, 0x81, 0xa1, 0x81, 0xa1, 0x40*/
2755 /*},*/
2756 utf16[]={
2757 0xfe, 0xff /* BOM only, no text */
2758 },
2759 utf32[]={
2760 0xff, 0xfe, 0, 0 /* BOM only, no text */
2761 };
2762
2763 char target[100], utf8NUL[100], shiftJISNUL[100];
2764
2765 UConverter *cnv;
2766 UErrorCode errorCode;
2767
2768 int32_t length;
2769
2770 errorCode=U_ZERO_ERROR;
2771 cnv=ucnv_open("Shift-JIS", &errorCode);
2772 if(U_FAILURE(errorCode)) {
2773 log_data_err("unable to open a Shift-JIS converter - %s\n", u_errorName(errorCode));
2774 ucnv_close(cnv);
2775 return;
2776 }
2777
2778 memcpy(utf8NUL, utf8, sizeof(utf8));
2779 utf8NUL[sizeof(utf8)]=0;
2780 memcpy(shiftJISNUL, shiftJIS, sizeof(shiftJIS));
2781 shiftJISNUL[sizeof(shiftJIS)]=0;
2782
2783 /*
2784 * The to/from algorithmic convenience functions share a common implementation,
2785 * so we need not test all permutations of them.
2786 */
2787
2788 /* length in, not terminated out */
2789 errorCode=U_ZERO_ERROR;
2790 length=ucnv_fromAlgorithmic(cnv, UCNV_UTF8, target, sizeof(shiftJIS), (const char *)utf8, sizeof(utf8), &errorCode);
2791 if( errorCode!=U_STRING_NOT_TERMINATED_WARNING ||
2792 length!=sizeof(shiftJIS) ||
2793 memcmp(target, shiftJIS, length)!=0
2794 ) {
2795 log_err("ucnv_fromAlgorithmic(UTF-8 -> Shift-JIS) fails (%s expect U_STRING_NOT_TERMINATED_WARNING), returns %d expect %d\n",
2796 u_errorName(errorCode), length, sizeof(shiftJIS));
2797 }
2798
2799 /* terminated in and out */
2800 memset(target, 0x55, sizeof(target));
2801 errorCode=U_STRING_NOT_TERMINATED_WARNING;
2802 length=ucnv_toAlgorithmic(UCNV_UTF8, cnv, target, sizeof(target), shiftJISNUL, -1, &errorCode);
2803 if( errorCode!=U_ZERO_ERROR ||
2804 length!=sizeof(utf8) ||
2805 memcmp(target, utf8, length)!=0
2806 ) {
2807 log_err("ucnv_toAlgorithmic(Shift-JIS -> UTF-8) fails (%s expect U_ZERO_ERROR), returns %d expect %d\n",
2808 u_errorName(errorCode), length, sizeof(shiftJIS));
2809 }
2810
2811 /* empty string, some target buffer */
2812 errorCode=U_STRING_NOT_TERMINATED_WARNING;
2813 length=ucnv_toAlgorithmic(UCNV_UTF8, cnv, target, sizeof(target), shiftJISNUL, 0, &errorCode);
2814 if( errorCode!=U_ZERO_ERROR ||
2815 length!=0
2816 ) {
2817 log_err("ucnv_toAlgorithmic(empty string -> UTF-8) fails (%s expect U_ZERO_ERROR), returns %d expect 0\n",
2818 u_errorName(errorCode), length);
2819 }
2820
2821 /* pseudo-empty string, no target buffer */
2822 errorCode=U_ZERO_ERROR;
2823 length=ucnv_fromAlgorithmic(cnv, UCNV_UTF16, target, 0, (const char *)utf16, 2, &errorCode);
2824 if( errorCode!=U_STRING_NOT_TERMINATED_WARNING ||
2825 length!=0
2826 ) {
2827 log_err("ucnv_fromAlgorithmic(UTF-16 only BOM -> Shift-JIS) fails (%s expect U_STRING_NOT_TERMINATED_WARNING), returns %d expect 0\n",
2828 u_errorName(errorCode), length);
2829 }
2830
2831 errorCode=U_ZERO_ERROR;
2832 length=ucnv_fromAlgorithmic(cnv, UCNV_UTF32, target, 0, (const char *)utf32, 4, &errorCode);
2833 if( errorCode!=U_STRING_NOT_TERMINATED_WARNING ||
2834 length!=0
2835 ) {
2836 log_err("ucnv_fromAlgorithmic(UTF-32 only BOM -> Shift-JIS) fails (%s expect U_STRING_NOT_TERMINATED_WARNING), returns %d expect 0\n",
2837 u_errorName(errorCode), length);
2838 }
2839
2840 /* bad arguments */
2841 errorCode=U_MESSAGE_PARSE_ERROR;
2842 length=ucnv_fromAlgorithmic(cnv, UCNV_UTF16, target, 0, (const char *)utf16, 2, &errorCode);
2843 if(errorCode!=U_MESSAGE_PARSE_ERROR) {
2844 log_err("ucnv_fromAlgorithmic(U_MESSAGE_PARSE_ERROR) sets %s\n", u_errorName(errorCode));
2845 }
2846
2847 /* source==NULL */
2848 errorCode=U_ZERO_ERROR;
2849 length=ucnv_fromAlgorithmic(cnv, UCNV_UTF16, target, 0, NULL, 2, &errorCode);
2850 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
2851 log_err("ucnv_fromAlgorithmic(source==NULL) sets %s\n", u_errorName(errorCode));
2852 }
2853
2854 /* illegal alg. type */
2855 errorCode=U_ZERO_ERROR;
2856 length=ucnv_fromAlgorithmic(cnv, (UConverterType)99, target, 0, (const char *)utf16, 2, &errorCode);
2857 if(errorCode!=U_ILLEGAL_ARGUMENT_ERROR) {
2858 log_err("ucnv_fromAlgorithmic(illegal alg. type) sets %s\n", u_errorName(errorCode));
2859 }
2860ucnv_close(cnv);
73c04bcf 2861#endif
b75a7d8f
A
2862}
2863
51004dcb 2864#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
2865static void TestLMBCSMaxChar(void) {
2866 static const struct {
2867 int8_t maxSize;
2868 const char *name;
2869 } converter[] = {
374ca955
A
2870 /* some non-LMBCS converters - perfect test setup here */
2871 { 1, "US-ASCII"},
2872 { 1, "ISO-8859-1"},
2873
729e4ab9
A
2874 { 2, "UTF-16"},
2875 { 2, "UTF-16BE"},
374ca955
A
2876 { 3, "UTF-8"},
2877 { 3, "CESU-8"},
2878 { 3, "SCSU"},
2879 { 4, "UTF-32"},
2880 { 4, "UTF-7"},
2881 { 4, "IMAP-mailbox-name"},
2882 { 4, "BOCU-1"},
2883
2884 { 1, "windows-1256"},
2885 { 2, "Shift-JIS"},
2886 { 2, "ibm-16684"},
2887 { 3, "ibm-930"},
2888 { 3, "ibm-1390"},
2889 { 4, "*test3"},
2890 { 16,"*test4"},
2891
2892 { 4, "ISCII"},
2893 { 4, "HZ"},
2894
2895 { 3, "ISO-2022"},
2896 { 3, "ISO-2022-KR"},
2897 { 6, "ISO-2022-JP"},
2898 { 8, "ISO-2022-CN"},
2899
2900 /* LMBCS */
2901 { 3, "LMBCS-1"},
2902 { 3, "LMBCS-2"},
2903 { 3, "LMBCS-3"},
2904 { 3, "LMBCS-4"},
2905 { 3, "LMBCS-5"},
2906 { 3, "LMBCS-6"},
2907 { 3, "LMBCS-8"},
2908 { 3, "LMBCS-11"},
2909 { 3, "LMBCS-16"},
2910 { 3, "LMBCS-17"},
2911 { 3, "LMBCS-18"},
2912 { 3, "LMBCS-19"}
b75a7d8f
A
2913 };
2914 int32_t idx;
2915
2916 for (idx = 0; idx < LENGTHOF(converter); idx++) {
2917 UErrorCode status = U_ZERO_ERROR;
374ca955 2918 UConverter *cnv = cnv_open(converter[idx].name, &status);
b75a7d8f
A
2919 if (U_FAILURE(status)) {
2920 continue;
2921 }
2922 if (converter[idx].maxSize != ucnv_getMaxCharSize(cnv)) {
374ca955 2923 log_err("error: ucnv_getMaxCharSize(%s) expected %d, got %d\n",
b75a7d8f
A
2924 converter[idx].name, converter[idx].maxSize, ucnv_getMaxCharSize(cnv));
2925 }
2926 ucnv_close(cnv);
2927 }
374ca955
A
2928
2929 /* mostly test that the macro compiles */
2930 if(UCNV_GET_MAX_BYTES_FOR_STRING(1, 2)<10) {
2931 log_err("error UCNV_GET_MAX_BYTES_FOR_STRING(1, 2)<10\n");
2932 }
b75a7d8f 2933}
51004dcb 2934#endif
b75a7d8f
A
2935
2936static void TestJ1968(void) {
2937 UErrorCode err = U_ZERO_ERROR;
2938 UConverter *cnv;
2939 char myConvName[] = "My really really really really really really really really really really really"
2940 " really really really really really really really really really really really"
2941 " really really really really really really really really long converter name";
2942 UChar myConvNameU[sizeof(myConvName)];
2943
2944 u_charsToUChars(myConvName, myConvNameU, sizeof(myConvName));
2945
2946 err = U_ZERO_ERROR;
2947 myConvNameU[UCNV_MAX_CONVERTER_NAME_LENGTH+1] = 0;
2948 cnv = ucnv_openU(myConvNameU, &err);
2949 if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
2950 log_err("1U) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
2951 }
2952
2953 err = U_ZERO_ERROR;
2954 myConvNameU[UCNV_MAX_CONVERTER_NAME_LENGTH] = 0;
2955 cnv = ucnv_openU(myConvNameU, &err);
2956 if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
2957 log_err("2U) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
2958 }
2959
2960 err = U_ZERO_ERROR;
2961 myConvNameU[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = 0;
2962 cnv = ucnv_openU(myConvNameU, &err);
2963 if (cnv || err != U_FILE_ACCESS_ERROR) {
2964 log_err("3U) Didn't get U_FILE_ACCESS_ERROR as expected %s\n", u_errorName(err));
2965 }
2966
2967
2968
2969
2970 err = U_ZERO_ERROR;
2971 cnv = ucnv_open(myConvName, &err);
2972 if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
2973 log_err("1) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
2974 }
2975
2976 err = U_ZERO_ERROR;
2977 myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH] = ',';
2978 cnv = ucnv_open(myConvName, &err);
2979 if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
2980 log_err("2) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
2981 }
2982
2983 err = U_ZERO_ERROR;
2984 myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = ',';
2985 cnv = ucnv_open(myConvName, &err);
2986 if (cnv || err != U_FILE_ACCESS_ERROR) {
2987 log_err("3) Didn't get U_FILE_ACCESS_ERROR as expected %s\n", u_errorName(err));
2988 }
2989
2990 err = U_ZERO_ERROR;
2991 myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = ',';
2992 strncpy(myConvName + UCNV_MAX_CONVERTER_NAME_LENGTH, "locale=", 7);
2993 cnv = ucnv_open(myConvName, &err);
2994 if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
2995 log_err("4) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
2996 }
2997
2998 /* The comma isn't really a part of the converter name. */
2999 err = U_ZERO_ERROR;
3000 myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH] = 0;
3001 cnv = ucnv_open(myConvName, &err);
3002 if (cnv || err != U_FILE_ACCESS_ERROR) {
3003 log_err("5) Didn't get U_FILE_ACCESS_ERROR as expected %s\n", u_errorName(err));
3004 }
3005
3006 err = U_ZERO_ERROR;
3007 myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = ' ';
3008 cnv = ucnv_open(myConvName, &err);
3009 if (cnv || err != U_ILLEGAL_ARGUMENT_ERROR) {
3010 log_err("6) Didn't get U_ILLEGAL_ARGUMENT_ERROR as expected %s\n", u_errorName(err));
3011 }
3012
3013 err = U_ZERO_ERROR;
3014 myConvName[UCNV_MAX_CONVERTER_NAME_LENGTH-1] = 0;
3015 cnv = ucnv_open(myConvName, &err);
3016 if (cnv || err != U_FILE_ACCESS_ERROR) {
3017 log_err("7) Didn't get U_FILE_ACCESS_ERROR as expected %s\n", u_errorName(err));
3018 }
3019
3020}
3021
73c04bcf 3022#if !UCONFIG_NO_LEGACY_CONVERSION
b75a7d8f
A
3023static void
3024testSwap(const char *name, UBool swap) {
3025 /*
3026 * Test Unicode text.
3027 * Contains characters that are the highest for some of the
3028 * tested conversions, to make sure that the ucnvmbcs.c code that modifies the
3029 * tables copies the entire tables.
3030 */
3031 static const UChar text[]={
3032 0x61, 0xd, 0x62, 0xa, 0x4e00, 0x3000, 0xfffd, 0xa, 0x20, 0x85, 0xff5e, 0x7a
3033 };
3034
3035 UChar uNormal[32], uSwapped[32];
3036 char normal[32], swapped[32];
3037 const UChar *pcu;
3038 UChar *pu;
3039 char *pc;
3040 int32_t i, normalLength, swappedLength;
3041 UChar u;
3042 char c;
3043
3044 const char *swappedName;
3045 UConverter *cnv, *swapCnv;
3046 UErrorCode errorCode;
3047
3048 /* if the swap flag is FALSE, then the test encoding is not EBCDIC and must not swap */
3049
3050 /* open both the normal and the LF/NL-swapping converters */
3051 strcpy(swapped, name);
3052 strcat(swapped, UCNV_SWAP_LFNL_OPTION_STRING);
3053
3054 errorCode=U_ZERO_ERROR;
3055 swapCnv=ucnv_open(swapped, &errorCode);
3056 cnv=ucnv_open(name, &errorCode);
3057 if(U_FAILURE(errorCode)) {
3058 log_data_err("TestEBCDICSwapLFNL error: unable to open %s or %s (%s)\n", name, swapped, u_errorName(errorCode));
3059 goto cleanup;
3060 }
3061
3062 /* the name must contain the swap option if and only if we expect the converter to swap */
3063 swappedName=ucnv_getName(swapCnv, &errorCode);
3064 if(U_FAILURE(errorCode)) {
3065 log_err("TestEBCDICSwapLFNL error: ucnv_getName(%s,swaplfnl) failed (%s)\n", name, u_errorName(errorCode));
3066 goto cleanup;
3067 }
3068
3069 pc=strstr(swappedName, UCNV_SWAP_LFNL_OPTION_STRING);
3070 if(swap != (pc!=NULL)) {
3071 log_err("TestEBCDICSwapLFNL error: ucnv_getName(%s,swaplfnl)=%s should (%d) contain 'swaplfnl'\n", name, swappedName, swap);
3072 goto cleanup;
3073 }
3074
3075 /* convert to EBCDIC */
3076 pcu=text;
3077 pc=normal;
3078 ucnv_fromUnicode(cnv, &pc, normal+LENGTHOF(normal), &pcu, text+LENGTHOF(text), NULL, TRUE, &errorCode);
3079 normalLength=(int32_t)(pc-normal);
3080
3081 pcu=text;
3082 pc=swapped;
3083 ucnv_fromUnicode(swapCnv, &pc, swapped+LENGTHOF(swapped), &pcu, text+LENGTHOF(text), NULL, TRUE, &errorCode);
3084 swappedLength=(int32_t)(pc-swapped);
3085
3086 if(U_FAILURE(errorCode)) {
3087 log_err("TestEBCDICSwapLFNL error converting to %s - (%s)\n", name, u_errorName(errorCode));
3088 goto cleanup;
3089 }
3090
3091 /* compare EBCDIC output */
3092 if(normalLength!=swappedLength) {
3093 log_err("TestEBCDICSwapLFNL error converting to %s - output lengths %d vs. %d\n", name, normalLength, swappedLength);
3094 goto cleanup;
3095 }
3096 for(i=0; i<normalLength; ++i) {
3097 /* swap EBCDIC LF/NL for comparison */
3098 c=normal[i];
3099 if(swap) {
3100 if(c==0x15) {
3101 c=0x25;
3102 } else if(c==0x25) {
3103 c=0x15;
3104 }
3105 }
3106
3107 if(c!=swapped[i]) {
3108 log_err("TestEBCDICSwapLFNL error converting to %s - did not swap properly, output[%d]=0x%02x\n", name, i, (uint8_t)swapped[i]);
3109 goto cleanup;
3110 }
3111 }
3112
3113 /* convert back to Unicode (may not roundtrip) */
3114 pc=normal;
3115 pu=uNormal;
3116 ucnv_toUnicode(cnv, &pu, uNormal+LENGTHOF(uNormal), (const char **)&pc, normal+normalLength, NULL, TRUE, &errorCode);
3117 normalLength=(int32_t)(pu-uNormal);
3118
3119 pc=normal;
3120 pu=uSwapped;
3121 ucnv_toUnicode(swapCnv, &pu, uSwapped+LENGTHOF(uSwapped), (const char **)&pc, normal+swappedLength, NULL, TRUE, &errorCode);
3122 swappedLength=(int32_t)(pu-uSwapped);
3123
3124 if(U_FAILURE(errorCode)) {
3125 log_err("TestEBCDICSwapLFNL error converting from %s - (%s)\n", name, u_errorName(errorCode));
3126 goto cleanup;
3127 }
3128
3129 /* compare EBCDIC output */
3130 if(normalLength!=swappedLength) {
3131 log_err("TestEBCDICSwapLFNL error converting from %s - output lengths %d vs. %d\n", name, normalLength, swappedLength);
3132 goto cleanup;
3133 }
3134 for(i=0; i<normalLength; ++i) {
3135 /* swap EBCDIC LF/NL for comparison */
3136 u=uNormal[i];
3137 if(swap) {
3138 if(u==0xa) {
3139 u=0x85;
3140 } else if(u==0x85) {
3141 u=0xa;
3142 }
3143 }
3144
3145 if(u!=uSwapped[i]) {
3146 log_err("TestEBCDICSwapLFNL error converting from %s - did not swap properly, output[%d]=U+%04x\n", name, i, uSwapped[i]);
3147 goto cleanup;
3148 }
3149 }
3150
3151 /* clean up */
3152cleanup:
3153 ucnv_close(cnv);
3154 ucnv_close(swapCnv);
3155}
3156
3157static void
3158TestEBCDICSwapLFNL() {
3159 static const struct {
3160 const char *name;
3161 UBool swap;
3162 } tests[]={
3163 { "ibm-37", TRUE },
3164 { "ibm-1047", TRUE },
3165 { "ibm-1140", TRUE },
3166 { "ibm-930", TRUE },
3167 { "iso-8859-3", FALSE }
3168 };
3169
3170 int i;
3171
3172 for(i=0; i<LENGTHOF(tests); ++i) {
3173 testSwap(tests[i].name, tests[i].swap);
3174 }
3175}
73c04bcf
A
3176#else
3177static void
3178TestEBCDICSwapLFNL() {
3179 /* test nothing... */
3180}
3181#endif
3182
73c04bcf
A
3183static void TestFromUCountPending(){
3184#if !UCONFIG_NO_LEGACY_CONVERSION
3185 UErrorCode status = U_ZERO_ERROR;
3186/* const UChar expectedUnicode[] = { 0x20ac, 0x0005, 0x0006, 0x000b, 0xdbc4, 0xde34, 0xd84d, 0xdc56, 0xfffd}; */
3187 static const struct {
3188 UChar input[6];
3189 int32_t len;
3190 int32_t exp;
3191 }fromUnicodeTests[] = {
3192 /*m:n conversion*/
3193 {{0xdbc4},1,1},
3194 {{ 0xdbc4, 0xde34, 0xd84d},3,1},
3195 {{ 0xdbc4, 0xde34, 0xd900},3,3},
3196 };
3197 int i;
3198 UConverter* cnv = ucnv_openPackage(loadTestData(&status), "test3", &status);
3199 if(U_FAILURE(status)){
46f4442e 3200 log_data_err("Could not create converter for test3. Error: %s\n", u_errorName(status));
73c04bcf
A
3201 return;
3202 }
3203 for(i=0; i<LENGTHOF(fromUnicodeTests); ++i) {
3204 char tgt[10];
3205 char* target = tgt;
3206 char* targetLimit = target + 10;
3207 const UChar* source = fromUnicodeTests[i].input;
3208 const UChar* sourceLimit = source + fromUnicodeTests[i].len;
3209 int32_t len = 0;
3210 ucnv_reset(cnv);
3211 ucnv_fromUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
3212 len = ucnv_fromUCountPending(cnv, &status);
3213 if(U_FAILURE(status)){
3214 log_err("ucnv_fromUnicode call did not succeed. Error: %s\n", u_errorName(status));
3215 status = U_ZERO_ERROR;
3216 continue;
3217 }
3218 if(len != fromUnicodeTests[i].exp){
3219 log_err("Did not get the expeced output for ucnv_fromUInputConsumed.\n");
3220 }
3221 }
3222 status = U_ZERO_ERROR;
3223 {
3224 /*
3225 * The converter has to read the tail before it knows that
3226 * only head alone matches.
3227 * At the end, the output for head will overflow the target,
3228 * middle will be pending, and tail will not have been consumed.
3229 */
3230 /*
3231 \U00101234 -> x (<U101234> \x07 |0)
3232 \U00101234\U00050005 -> y (<U101234>+<U50005> \x07+\x00+\x01\x02\x0e+\x05 |0)
3233 \U00101234\U00050005\U00060006 -> z (<U101234>+<U50005>+<U60006> \x07+\x00+\x01\x02\x0f+\x09 |0)
3234 \U00060007 -> unassigned
3235 */
3236 static const UChar head[] = {0xDBC4,0xDE34,0xD900,0xDC05,0x0000};/* \U00101234\U00050005 */
3237 static const UChar middle[] = {0xD940,0x0000}; /* first half of \U00060006 or \U00060007 */
3238 static const UChar tail[] = {0xDC07,0x0000};/* second half of \U00060007 */
3239 char tgt[10];
3240 char* target = tgt;
3241 char* targetLimit = target + 2; /* expect overflow from converting \U00101234\U00050005 */
3242 const UChar* source = head;
3243 const UChar* sourceLimit = source + u_strlen(head);
3244 int32_t len = 0;
3245 ucnv_reset(cnv);
3246 ucnv_fromUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
3247 len = ucnv_fromUCountPending(cnv, &status);
3248 if(U_FAILURE(status)){
3249 log_err("ucnv_fromUnicode call did not succeed. Error: %s\n", u_errorName(status));
3250 status = U_ZERO_ERROR;
3251 }
3252 if(len!=4){
3253 log_err("ucnv_fromUInputHeld did not return correct length for head\n");
3254 }
3255 source = middle;
3256 sourceLimit = source + u_strlen(middle);
3257 ucnv_fromUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
3258 len = ucnv_fromUCountPending(cnv, &status);
3259 if(U_FAILURE(status)){
3260 log_err("ucnv_fromUnicode call did not succeed. Error: %s\n", u_errorName(status));
3261 status = U_ZERO_ERROR;
3262 }
3263 if(len!=5){
3264 log_err("ucnv_fromUInputHeld did not return correct length for middle\n");
3265 }
3266 source = tail;
3267 sourceLimit = source + u_strlen(tail);
3268 ucnv_fromUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
3269 if(status != U_BUFFER_OVERFLOW_ERROR){
3270 log_err("ucnv_fromUnicode call did not succeed. Error: %s\n", u_errorName(status));
3271 }
3272 status = U_ZERO_ERROR;
3273 len = ucnv_fromUCountPending(cnv, &status);
3274 /* middle[1] is pending, tail has not been consumed */
3275 if(U_FAILURE(status)){
3276 log_err("ucnv_fromUInputHeld call did not succeed. Error: %s\n", u_errorName(status));
3277 }
3278 if(len!=1){
3279 log_err("ucnv_fromUInputHeld did not return correct length for tail\n");
3280 }
3281 }
3282 ucnv_close(cnv);
3283#endif
3284}
3285
3286static void
3287TestToUCountPending(){
3288#if !UCONFIG_NO_LEGACY_CONVERSION
3289 UErrorCode status = U_ZERO_ERROR;
3290 static const struct {
3291 char input[6];
3292 int32_t len;
3293 int32_t exp;
3294 }toUnicodeTests[] = {
3295 /*m:n conversion*/
3296 {{0x05, 0x01, 0x02},3,3},
3297 {{0x01, 0x02},2,2},
3298 {{0x07, 0x00, 0x01, 0x02},4,4},
3299 };
3300
3301 int i;
3302 UConverterToUCallback *oldToUAction= NULL;
3303 UConverter* cnv = ucnv_openPackage(loadTestData(&status), "test3", &status);
3304 if(U_FAILURE(status)){
46f4442e 3305 log_data_err("Could not create converter for test3. Error: %s\n", u_errorName(status));
73c04bcf
A
3306 return;
3307 }
3308 ucnv_setToUCallBack(cnv, UCNV_TO_U_CALLBACK_STOP, NULL, oldToUAction, NULL, &status);
3309 for(i=0; i<LENGTHOF(toUnicodeTests); ++i) {
4388f060 3310 UChar tgt[20];
73c04bcf
A
3311 UChar* target = tgt;
3312 UChar* targetLimit = target + 20;
3313 const char* source = toUnicodeTests[i].input;
3314 const char* sourceLimit = source + toUnicodeTests[i].len;
3315 int32_t len = 0;
3316 ucnv_reset(cnv);
4388f060 3317 ucnv_toUnicode(cnv, &target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
73c04bcf
A
3318 len = ucnv_toUCountPending(cnv,&status);
3319 if(U_FAILURE(status)){
3320 log_err("ucnv_toUnicode call did not succeed. Error: %s\n", u_errorName(status));
3321 status = U_ZERO_ERROR;
3322 continue;
3323 }
3324 if(len != toUnicodeTests[i].exp){
3325 log_err("Did not get the expeced output for ucnv_toUInputConsumed.\n");
3326 }
3327 }
3328 status = U_ZERO_ERROR;
3329 ucnv_close(cnv);
3330
3331 {
3332 /*
3333 * The converter has to read the tail before it knows that
3334 * only head alone matches.
3335 * At the end, the output for head will overflow the target,
3336 * mid will be pending, and tail will not have been consumed.
3337 */
3338 char head[] = { 0x01, 0x02, 0x03, 0x0a , 0x00};
3339 char mid[] = { 0x01, 0x02, 0x03, 0x0b, 0x00 };
3340 char tail[] = { 0x01, 0x02, 0x03, 0x0d, 0x00 };
3341 /*
3342 0x01, 0x02, 0x03, 0x0a -> x (<U23456> \x01\x02\x03\x0a |0)
3343 0x01, 0x02, 0x03, 0x0b -> y (<U000b> \x01\x02\x03\x0b |0)
3344 0x01, 0x02, 0x03, 0x0d -> z (<U34567> \x01\x02\x03\x0d |3)
3345 0x01, 0x02, 0x03, 0x0a + 0x01, 0x02, 0x03, 0x0b + 0x01 + many more -> z (see test4 "many bytes, and bytes per UChar")
3346 */
3347 UChar tgt[10];
3348 UChar* target = tgt;
3349 UChar* targetLimit = target + 1; /* expect overflow from converting */
3350 const char* source = head;
3351 const char* sourceLimit = source + strlen(head);
3352 int32_t len = 0;
3353 cnv = ucnv_openPackage(loadTestData(&status), "test4", &status);
3354 if(U_FAILURE(status)){
3355 log_err("Could not create converter for test3. Error: %s\n", u_errorName(status));
3356 return;
3357 }
3358 ucnv_setToUCallBack(cnv, UCNV_TO_U_CALLBACK_STOP, NULL, oldToUAction, NULL, &status);
3359 ucnv_toUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
3360 len = ucnv_toUCountPending(cnv,&status);
3361 if(U_FAILURE(status)){
3362 log_err("ucnv_toUnicode call did not succeed. Error: %s\n", u_errorName(status));
3363 }
3364 if(len != 4){
3365 log_err("Did not get the expected len for head.\n");
3366 }
3367 source=mid;
3368 sourceLimit = source+strlen(mid);
3369 ucnv_toUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
3370 len = ucnv_toUCountPending(cnv,&status);
3371 if(U_FAILURE(status)){
3372 log_err("ucnv_toUnicode call did not succeed. Error: %s\n", u_errorName(status));
3373 }
3374 if(len != 8){
3375 log_err("Did not get the expected len for mid.\n");
3376 }
3377
3378 source=tail;
3379 sourceLimit = source+strlen(tail);
3380 targetLimit = target;
3381 ucnv_toUnicode(cnv,&target, targetLimit, &source, sourceLimit, NULL, FALSE, &status);
3382 if(status != U_BUFFER_OVERFLOW_ERROR){
3383 log_err("ucnv_toUnicode call did not succeed. Error: %s\n", u_errorName(status));
3384 }
3385 status = U_ZERO_ERROR;
3386 len = ucnv_toUCountPending(cnv,&status);
3387 /* mid[4] is pending, tail has not been consumed */
3388 if(U_FAILURE(status)){
3389 log_err("ucnv_toUCountPending call did not succeed. Error: %s\n", u_errorName(status));
3390 }
3391 if(len != 4){
3392 log_err("Did not get the expected len for tail.\n");
3393 }
3394 ucnv_close(cnv);
3395 }
3396#endif
3397}
3398
729e4ab9 3399static void TestOneDefaultNameChange(const char *name, const char *expected) {
73c04bcf
A
3400 UErrorCode status = U_ZERO_ERROR;
3401 UConverter *cnv;
3402 ucnv_setDefaultName(name);
729e4ab9 3403 if(strcmp(ucnv_getDefaultName(), expected)==0)
73c04bcf
A
3404 log_verbose("setDefaultName of %s works.\n", name);
3405 else
3406 log_err("setDefaultName of %s failed\n", name);
3407 cnv=ucnv_open(NULL, &status);
3408 if (U_FAILURE(status) || cnv == NULL) {
3409 log_err("opening the default converter of %s failed\n", name);
3410 return;
3411 }
729e4ab9 3412 if(strcmp(ucnv_getName(cnv, &status), expected)==0)
73c04bcf
A
3413 log_verbose("ucnv_getName of %s works.\n", name);
3414 else
3415 log_err("ucnv_getName of %s failed\n", name);
3416 ucnv_close(cnv);
3417}
3418
3419static void TestDefaultName(void) {
3420 /*Testing ucnv_getDefaultName() and ucnv_setDefaultNAme()*/
3421 static char defaultName[UCNV_MAX_CONVERTER_NAME_LENGTH + 1];
3422 strcpy(defaultName, ucnv_getDefaultName());
3423
3424 log_verbose("getDefaultName returned %s\n", defaultName);
3425
3426 /*change the default name by setting it */
729e4ab9
A
3427 TestOneDefaultNameChange("UTF-8", "UTF-8");
3428#if U_CHARSET_IS_UTF8
3429 TestOneDefaultNameChange("ISCII,version=1", "UTF-8");
3430 TestOneDefaultNameChange("ISCII,version=2", "UTF-8");
3431 TestOneDefaultNameChange("ISO-8859-1", "UTF-8");
3432#else
3433# if !UCONFIG_NO_LEGACY_CONVERSION
3434 TestOneDefaultNameChange("ISCII,version=1", "ISCII,version=1");
3435 TestOneDefaultNameChange("ISCII,version=2", "ISCII,version=2");
3436# endif
3437 TestOneDefaultNameChange("ISO-8859-1", "ISO-8859-1");
73c04bcf 3438#endif
73c04bcf
A
3439
3440 /*set the default name back*/
3441 ucnv_setDefaultName(defaultName);
3442}
3443
3444/* Test that ucnv_compareNames() matches names according to spec. ----------- */
3445
4388f060 3446static int
73c04bcf
A
3447sign(int n) {
3448 if(n==0) {
3449 return 0;
3450 } else if(n<0) {
3451 return -1;
3452 } else /* n>0 */ {
3453 return 1;
3454 }
3455}
3456
3457static void
3458compareNames(const char **names) {
3459 const char *relation, *name1, *name2;
3460 int rel, result;
3461
3462 relation=*names++;
3463 if(*relation=='=') {
3464 rel = 0;
3465 } else if(*relation=='<') {
3466 rel = -1;
3467 } else {
3468 rel = 1;
3469 }
3470
3471 name1=*names++;
3472 if(name1==NULL) {
3473 return;
3474 }
3475 while((name2=*names++)!=NULL) {
3476 result=ucnv_compareNames(name1, name2);
3477 if(sign(result)!=rel) {
3478 log_err("ucnv_compareNames(\"%s\", \"%s\")=%d, sign!=%d\n", name1, name2, result, rel);
3479 }
3480 name1=name2;
3481 }
3482}
3483
3484static void
3485TestCompareNames() {
3486 static const char *equalUTF8[]={ "=", "UTF-8", "utf_8", "u*T@f08", "Utf 8", NULL };
3487 static const char *equalIBM[]={ "=", "ibm-37", "IBM037", "i-B-m 00037", "ibm-0037", "IBM00037", NULL };
3488 static const char *lessMac[]={ "<", "macos-0_1-10.2", "macos-1-10.0.2", "macos-1-10.2", NULL };
3489 static const char *lessUTF080[]={ "<", "UTF-0008", "utf$080", "u*T@f0800", "Utf 0000000009", NULL };
3490
3491 compareNames(equalUTF8);
3492 compareNames(equalIBM);
3493 compareNames(lessMac);
3494 compareNames(lessUTF080);
3495}
3496
3497static void
3498TestSubstString() {
3499 static const UChar surrogate[1]={ 0xd900 };
3500 char buffer[16];
3501
3502 static const UChar sub[5]={ 0x61, 0x62, 0x63, 0x64, 0x65 };
3503 static const char subChars[5]={ 0x61, 0x62, 0x63, 0x64, 0x65 };
3504 UConverter *cnv;
3505 UErrorCode errorCode;
3506 int32_t length;
3507 int8_t len8;
3508
3509 /* UTF-16/32: test that the BOM is output before the sub character */
3510 errorCode=U_ZERO_ERROR;
3511 cnv=ucnv_open("UTF-16", &errorCode);
3512 if(U_FAILURE(errorCode)) {
729e4ab9 3513 log_data_err("ucnv_open(UTF-16) failed - %s\n", u_errorName(errorCode));
73c04bcf
A
3514 return;
3515 }
3516 length=ucnv_fromUChars(cnv, buffer, (int32_t)sizeof(buffer), surrogate, 1, &errorCode);
3517 ucnv_close(cnv);
3518 if(U_FAILURE(errorCode) ||
3519 length!=4 ||
3520 NULL == ucnv_detectUnicodeSignature(buffer, length, NULL, &errorCode)
3521 ) {
3522 log_err("ucnv_fromUChars(UTF-16, U+D900) did not write a BOM\n");
3523 }
3524
3525 errorCode=U_ZERO_ERROR;
3526 cnv=ucnv_open("UTF-32", &errorCode);
3527 if(U_FAILURE(errorCode)) {
729e4ab9 3528 log_data_err("ucnv_open(UTF-32) failed - %s\n", u_errorName(errorCode));
73c04bcf
A
3529 return;
3530 }
3531 length=ucnv_fromUChars(cnv, buffer, (int32_t)sizeof(buffer), surrogate, 1, &errorCode);
3532 ucnv_close(cnv);
3533 if(U_FAILURE(errorCode) ||
3534 length!=8 ||
3535 NULL == ucnv_detectUnicodeSignature(buffer, length, NULL, &errorCode)
3536 ) {
3537 log_err("ucnv_fromUChars(UTF-32, U+D900) did not write a BOM\n");
3538 }
3539
3540 /* Simple API test of ucnv_setSubstString() + ucnv_getSubstChars(). */
3541 errorCode=U_ZERO_ERROR;
3542 cnv=ucnv_open("ISO-8859-1", &errorCode);
3543 if(U_FAILURE(errorCode)) {
729e4ab9 3544 log_data_err("ucnv_open(ISO-8859-1) failed - %s\n", u_errorName(errorCode));
73c04bcf
A
3545 return;
3546 }
3547 ucnv_setSubstString(cnv, sub, LENGTHOF(sub), &errorCode);
3548 if(U_FAILURE(errorCode)) {
3549 log_err("ucnv_setSubstString(ISO-8859-1, sub[5]) failed - %s\n", u_errorName(errorCode));
3550 } else {
3551 len8 = sizeof(buffer);
3552 ucnv_getSubstChars(cnv, buffer, &len8, &errorCode);
3553 /* Stateless converter, we expect the string converted to charset bytes. */
3554 if(U_FAILURE(errorCode) || len8!=sizeof(subChars) || 0!=uprv_memcmp(buffer, subChars, len8)) {
3555 log_err("ucnv_getSubstChars(ucnv_setSubstString(ISO-8859-1, sub[5])) failed - %s\n", u_errorName(errorCode));
3556 }
3557 }
3558 ucnv_close(cnv);
3559
3560#if !UCONFIG_NO_LEGACY_CONVERSION
3561 errorCode=U_ZERO_ERROR;
3562 cnv=ucnv_open("HZ", &errorCode);
3563 if(U_FAILURE(errorCode)) {
729e4ab9 3564 log_data_err("ucnv_open(HZ) failed - %s\n", u_errorName(errorCode));
73c04bcf
A
3565 return;
3566 }
3567 ucnv_setSubstString(cnv, sub, LENGTHOF(sub), &errorCode);
3568 if(U_FAILURE(errorCode)) {
3569 log_err("ucnv_setSubstString(HZ, sub[5]) failed - %s\n", u_errorName(errorCode));
3570 } else {
3571 len8 = sizeof(buffer);
3572 ucnv_getSubstChars(cnv, buffer, &len8, &errorCode);
3573 /* Stateful converter, we expect that the Unicode string was set and that we get an empty char * string now. */
3574 if(U_FAILURE(errorCode) || len8!=0) {
3575 log_err("ucnv_getSubstChars(ucnv_setSubstString(HZ, sub[5])) failed - %s\n", u_errorName(errorCode));
3576 }
3577 }
3578 ucnv_close(cnv);
3579#endif
3580 /*
3581 * Further testing of ucnv_setSubstString() is done via intltest convert.
3582 * We do not test edge cases of illegal arguments and similar because the
3583 * function implementation uses all of its parameters in calls to other
3584 * functions with UErrorCode parameters.
3585 */
3586}
46f4442e
A
3587
3588static void
3589InvalidArguments() {
3590 UConverter *cnv;
3591 UErrorCode errorCode;
3592 char charBuffer[2] = {1, 1};
3593 char ucharAsCharBuffer[2] = {2, 2};
3594 char *charsPtr = charBuffer;
3595 UChar *ucharsPtr = (UChar *)ucharAsCharBuffer;
3596 UChar *ucharsBadPtr = (UChar *)(ucharAsCharBuffer + 1);
3597
3598 errorCode=U_ZERO_ERROR;
3599 cnv=ucnv_open("UTF-8", &errorCode);
3600 if(U_FAILURE(errorCode)) {
3601 log_err("ucnv_open() failed - %s\n", u_errorName(errorCode));
3602 return;
3603 }
3604
3605 errorCode=U_ZERO_ERROR;
3606 /* This one should fail because an incomplete UChar is being passed in */
3607 ucnv_fromUnicode(cnv, &charsPtr, charsPtr, (const UChar **)&ucharsPtr, ucharsBadPtr, NULL, TRUE, &errorCode);
3608 if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
3609 log_err("ucnv_fromUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for incomplete UChar * buffer - %s\n", u_errorName(errorCode));
3610 }
3611
3612 errorCode=U_ZERO_ERROR;
3613 /* This one should fail because ucharsBadPtr is > than ucharsPtr */
3614 ucnv_fromUnicode(cnv, &charsPtr, charsPtr, (const UChar **)&ucharsBadPtr, ucharsPtr, NULL, TRUE, &errorCode);
3615 if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
3616 log_err("ucnv_fromUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for bad limit pointer - %s\n", u_errorName(errorCode));
3617 }
3618
3619 errorCode=U_ZERO_ERROR;
3620 /* This one should fail because an incomplete UChar is being passed in */
3621 ucnv_toUnicode(cnv, &ucharsPtr, ucharsBadPtr, (const char **)&charsPtr, charsPtr, NULL, TRUE, &errorCode);
3622 if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
3623 log_err("ucnv_toUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for incomplete UChar * buffer - %s\n", u_errorName(errorCode));
3624 }
3625
3626 errorCode=U_ZERO_ERROR;
3627 /* This one should fail because ucharsBadPtr is > than ucharsPtr */
3628 ucnv_toUnicode(cnv, &ucharsBadPtr, ucharsPtr, (const char **)&charsPtr, charsPtr, NULL, TRUE, &errorCode);
3629 if(errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
3630 log_err("ucnv_toUnicode() failed to return U_ILLEGAL_ARGUMENT_ERROR for bad limit pointer - %s\n", u_errorName(errorCode));
3631 }
3632
3633 if (charBuffer[0] != 1 || charBuffer[1] != 1
3634 || ucharAsCharBuffer[0] != 2 || ucharAsCharBuffer[1] != 2)
3635 {
3636 log_err("Data was incorrectly written to buffers\n");
3637 }
3638
3639 ucnv_close(cnv);
3640}
3641
729e4ab9
A
3642static void TestGetName() {
3643 static const char *const names[] = {
3644 "Unicode", "UTF-16",
3645 "UnicodeBigUnmarked", "UTF-16BE",
3646 "UnicodeBig", "UTF-16BE,version=1",
3647 "UnicodeLittleUnmarked", "UTF-16LE",
3648 "UnicodeLittle", "UTF-16LE,version=1",
3649 "x-UTF-16LE-BOM", "UTF-16LE,version=1"
3650 };
3651 int32_t i;
3652 for(i = 0; i < LENGTHOF(names); i += 2) {
3653 UErrorCode errorCode = U_ZERO_ERROR;
3654 UConverter *cnv = ucnv_open(names[i], &errorCode);
3655 if(U_SUCCESS(errorCode)) {
3656 const char *name = ucnv_getName(cnv, &errorCode);
3657 if(U_FAILURE(errorCode) || 0 != strcmp(name, names[i+1])) {
3658 log_err("ucnv_getName(%s) = %s != %s -- %s\n",
3659 names[i], name, names[i+1], u_errorName(errorCode));
3660 }
3661 ucnv_close(cnv);
3662 }
3663 }
3664}
3665
3666static void TestUTFBOM() {
3667 static const UChar a16[] = { 0x61 };
3668 static const char *const names[] = {
3669 "UTF-16",
3670 "UTF-16,version=1",
3671 "UTF-16BE",
3672 "UnicodeBig",
3673 "UTF-16LE",
3674 "UnicodeLittle"
3675 };
3676 static const uint8_t expected[][5] = {
3677#if U_IS_BIG_ENDIAN
3678 { 4, 0xfe, 0xff, 0, 0x61 },
3679 { 4, 0xfe, 0xff, 0, 0x61 },
3680#else
3681 { 4, 0xff, 0xfe, 0x61, 0 },
3682 { 4, 0xff, 0xfe, 0x61, 0 },
3683#endif
3684
3685 { 2, 0, 0x61 },
3686 { 4, 0xfe, 0xff, 0, 0x61 },
3687
3688 { 2, 0x61, 0 },
3689 { 4, 0xff, 0xfe, 0x61, 0 }
3690 };
46f4442e 3691
729e4ab9
A
3692 char bytes[10];
3693 int32_t i;
3694
3695 for(i = 0; i < LENGTHOF(names); ++i) {
3696 UErrorCode errorCode = U_ZERO_ERROR;
3697 UConverter *cnv = ucnv_open(names[i], &errorCode);
3698 int32_t length = 0;
3699 const uint8_t *exp = expected[i];
3700 if (U_FAILURE(errorCode)) {
3701 log_err_status(errorCode, "Unable to open converter: %s got error code: %s\n", names[i], u_errorName(errorCode));
3702 continue;
3703 }
3704 length = ucnv_fromUChars(cnv, bytes, (int32_t)sizeof(bytes), a16, 1, &errorCode);
3705
3706 if(U_FAILURE(errorCode) || length != exp[0] || 0 != memcmp(bytes, exp+1, length)) {
3707 log_err("unexpected %s BOM writing behavior -- %s\n",
3708 names[i], u_errorName(errorCode));
3709 }
3710 ucnv_close(cnv);
3711 }
3712}