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