Home | History | Annotate | Download | only in cintltst
      1 /********************************************************************
      2  * COPYRIGHT:
      3  * Copyright (c) 1998-2012, International Business Machines Corporation and
      4  * others. All Rights Reserved.
      5  ********************************************************************/
      6 /*
      7 * File test.c
      8 *
      9 * Modification History:
     10 *
     11 *   Date          Name        Description
     12 *   02/22/2000    Madhu       Creation
     13 ******************************************************************************
     14 */
     15 
     16 #include "unicode/utypes.h"
     17 #include "unicode/putil.h"
     18 #include "unicode/udata.h"
     19 #include "unicode/uchar.h"
     20 #include "unicode/ucnv.h"
     21 #include "unicode/ures.h"
     22 #include "unicode/ustring.h"
     23 #include "unicode/uclean.h"
     24 #include "cmemory.h"
     25 #include "cstring.h"
     26 #include "filestrm.h"
     27 #include "udatamem.h"
     28 #include "cintltst.h"
     29 #include "ubrkimpl.h"
     30 
     31 #include <sys/types.h>
     32 #include <sys/stat.h>
     33 #include <fcntl.h>
     34 #include <stdlib.h>
     35 #include <stdio.h>
     36 
     37 #if U_PLATFORM_USES_ONLY_WIN32_API
     38 #include <io.h>
     39 #else
     40 #include <unistd.h>
     41 #endif
     42 
     43 /* includes for TestSwapData() */
     44 #include "udataswp.h"
     45 
     46 /* swapping implementations in common */
     47 #include "uresdata.h"
     48 #include "ucnv_io.h"
     49 #include "uprops.h"
     50 #include "ucase.h"
     51 #include "ucol_imp.h"
     52 #include "ucol_swp.h"
     53 #include "ucnv_bld.h"
     54 #include "sprpimpl.h"
     55 #include "rbbidata.h"
     56 
     57 /* swapping implementation in i18n */
     58 #include "uspoof_impl.h"
     59 
     60 U_CAPI int32_t U_EXPORT2
     61 unorm2_swap(const UDataSwapper *ds,
     62             const void *inData, int32_t length, void *outData,
     63             UErrorCode *pErrorCode);
     64 
     65 /* other definitions and prototypes */
     66 
     67 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
     68 
     69 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
     70 static void TestUDataOpen(void);
     71 static void TestUDataOpenChoiceDemo1(void);
     72 static void TestUDataOpenChoiceDemo2(void);
     73 static void TestUDataGetInfo(void);
     74 static void TestUDataGetMemory(void);
     75 static void TestErrorConditions(void);
     76 static void TestAppData(void);
     77 static void TestSwapData(void);
     78 #endif
     79 static void TestUDataSetAppData(void);
     80 static void TestICUDataName(void);
     81 static void PointerTableOfContents(void);
     82 static void SetBadCommonData(void);
     83 static void TestUDataFileAccess(void);
     84 
     85 
     86 void addUDataTest(TestNode** root);
     87 
     88 void
     89 addUDataTest(TestNode** root)
     90 {
     91 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
     92     addTest(root, &TestUDataOpen,       "udatatst/TestUDataOpen"      );
     93     addTest(root, &TestUDataOpenChoiceDemo1, "udatatst/TestUDataOpenChoiceDemo1");
     94     addTest(root, &TestUDataOpenChoiceDemo2, "udatatst/TestUDataOpenChoiceDemo2");
     95     addTest(root, &TestUDataGetInfo,    "udatatst/TestUDataGetInfo"   );
     96     addTest(root, &TestUDataGetMemory,  "udatatst/TestUDataGetMemory" );
     97     addTest(root, &TestErrorConditions, "udatatst/TestErrorConditions");
     98     addTest(root, &TestAppData, "udatatst/TestAppData" );
     99     addTest(root, &TestSwapData, "udatatst/TestSwapData" );
    100 #endif
    101     addTest(root, &TestUDataSetAppData, "udatatst/TestUDataSetAppData" );
    102     addTest(root, &TestICUDataName, "udatatst/TestICUDataName" );
    103     addTest(root, &PointerTableOfContents, "udatatst/PointerTableOfContents" );
    104     addTest(root, &SetBadCommonData, "udatatst/SetBadCommonData" );
    105     addTest(root, &TestUDataFileAccess, "udatatst/TestUDataFileAccess" );
    106 }
    107 
    108 #if 0
    109 static void lots_of_mallocs()
    110 {
    111     int q;
    112     for(q=1;q<100;q++)
    113     {
    114         free(malloc(q));
    115         malloc(q*2);
    116     }
    117 
    118 }
    119 #endif
    120 
    121 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
    122 static void TestUDataOpen(){
    123     UDataMemory *result;
    124     UErrorCode status=U_ZERO_ERROR;
    125     const char* memMap[][2]={
    126         {"root", "res"},
    127         {"cnvalias", "icu"},
    128         {"unames",   "icu"},
    129         {"ibm-37_P100-1995",   "cnv"}
    130     };
    131     const char* name            = "test";
    132     const char* type            = "icu";
    133     const char  dirSepString[]  = {U_FILE_SEP_CHAR, 0};
    134     const char  pathSepString[] = {U_PATH_SEP_CHAR, 0};
    135 
    136 
    137     char* path=(char*)malloc(sizeof(char) * (strlen(ctest_dataOutDir())
    138                                            + strlen(U_ICUDATA_NAME)
    139                                            + strlen("/build")+1 ) );
    140 
    141     char        *icuDataFilePath = 0;
    142     struct stat stat_buf;
    143 
    144     const char* testPath=loadTestData(&status);
    145     if(U_FAILURE(status)) {
    146         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
    147         free(path);
    148         return;
    149     }
    150 
    151     /* lots_of_mallocs(); */
    152 
    153     strcat(strcpy(path, ctest_dataOutDir()), U_ICUDATA_NAME);
    154 
    155     log_verbose("Testing udata_open()\n");
    156     result=udata_open(testPath, type, name, &status);
    157     if(U_FAILURE(status)){
    158         log_data_err("FAIL: udata_open() failed for path = %s, name=%s, type=%s, \n errorcode=%s\n", testPath, name, type, myErrorName(status));
    159     } else {
    160         log_verbose("PASS: udata_open worked\n");
    161         udata_close(result);
    162     }
    163 
    164     /* If the ICU system common data file is present in this confiugration,
    165      *   verify that udata_open can explicitly fetch items from it.
    166      *   If packaging mode == dll, the file may not exist.  So, if the file is
    167      *   missing, skip this test without error.
    168      */
    169     icuDataFilePath = (char *)malloc(strlen(path) + 10);
    170     strcpy(icuDataFilePath, path);
    171     strcat(icuDataFilePath, ".dat");
    172     /* lots_of_mallocs(); */
    173     if (stat(icuDataFilePath, &stat_buf) == 0)
    174     {
    175         int i;
    176         log_verbose("Testing udata_open() on %s\n", icuDataFilePath);
    177         for(i=0; i<sizeof(memMap)/sizeof(memMap[0]); i++){
    178             /* lots_of_mallocs(); */
    179             status=U_ZERO_ERROR;
    180             result=udata_open(path, memMap[i][1], memMap[i][0], &status);
    181             if(U_FAILURE(status)) {
    182                 log_data_err("FAIL: udata_open() failed for path = %s, name=%s, type=%s, \n errorcode=%s\n", path, memMap[i][0], memMap[i][1], myErrorName(status));
    183             } else {
    184                 log_verbose("PASS: udata_open worked for path = %s, name=%s, type=%s\n",  path, memMap[i][0], memMap[i][1]);
    185                 udata_close(result);
    186             }
    187         }
    188     }
    189     else
    190     {
    191     /* lots_of_mallocs(); */
    192          log_verbose("Skipping tests of udata_open() on %s.  File not present in this configuration.\n",
    193              icuDataFilePath);
    194     }
    195     free(icuDataFilePath);
    196     icuDataFilePath = NULL;
    197     /* lots_of_mallocs(); */
    198 
    199     /* If the ICU individual files used to build the ICU system common data are
    200      *   present in this configuration,
    201      *   verify that udata_open can explicitly open them.
    202      *   These data files are present in the ICU data/build directory after a build
    203      *    completes.  Tests are most commonly run with the data directory pointing
    204      *    back into this directory structure, but this is not required.  Soooo, if
    205      *    the files are missing, skip this test without error.
    206      */
    207     /* lots_of_mallocs(); */
    208     icuDataFilePath = (char *)malloc(strlen(ctest_dataOutDir()) + 50);
    209     strcpy(icuDataFilePath, ctest_dataOutDir());
    210     strcat(icuDataFilePath, "build");
    211     strcat(icuDataFilePath, dirSepString);
    212     strcat(icuDataFilePath, U_ICUDATA_NAME);
    213     strcat(icuDataFilePath, "_");
    214     strcat(icuDataFilePath, "cnvalias.icu");
    215 
    216     /* lots_of_mallocs(); */
    217     if (stat(icuDataFilePath, &stat_buf) == 0)
    218     {
    219         int i;
    220         log_verbose("%s exists, so..\n", icuDataFilePath);
    221         strcpy(icuDataFilePath, ctest_dataOutDir());
    222         strcat(icuDataFilePath, "build");
    223         strcat(icuDataFilePath, dirSepString);
    224         strcat(icuDataFilePath, U_ICUDATA_NAME);
    225         log_verbose("Testing udata_open() on %s\n", icuDataFilePath);
    226         for(i=0; i<sizeof(memMap)/sizeof(memMap[0]); i++){
    227             status=U_ZERO_ERROR;
    228             result=udata_open(icuDataFilePath, memMap[i][1], memMap[i][0], &status);
    229             if(U_FAILURE(status)) {
    230                 log_data_err("FAIL: udata_open() failed for path = %s, name=%s, type=%s, \n errorcode=%s\n", icuDataFilePath, memMap[i][0], memMap[i][1], myErrorName(status));
    231             } else {
    232                 log_verbose("PASS: udata_open worked for path = %s, name=%s, type=%s\n",  icuDataFilePath, memMap[i][0], memMap[i][1]);
    233                 udata_close(result);
    234             }
    235         }
    236     }
    237     else
    238     {
    239          log_verbose("Skipping tests of udata_open() on %s.  File not present in this configuration.\n",
    240              icuDataFilePath);
    241     }
    242 
    243     free(icuDataFilePath);
    244     icuDataFilePath = NULL;
    245 
    246     /*
    247      * Test fallback file names for open of separate data files.
    248      *    With these params to udata_open:
    249      *       path = wherever/testdata
    250      *       type = typ
    251      *       name = nam
    252      *     these files will be tried first:
    253      *              wherever/testudata_nam.typ
    254      *              testudata_nam.typ
    255      *  A test data file named testudata_nam.typ exists for the purpose of testing this.
    256      */
    257     log_verbose("Testing udata_open, with base_name.type style fallback to individual file.\n");
    258 
    259     status = U_ZERO_ERROR;
    260     result = udata_open( testPath, "typ", "nam", &status);
    261     if (status != U_ZERO_ERROR) {
    262         log_data_err("FAIL: udata_open( \"%s\", \"typ\", \"nam\") returned status %s\n", testPath, u_errorName(status));
    263     }
    264     udata_close(result);
    265     free(icuDataFilePath);
    266 
    267 
    268     /* This type of path is deprecated */
    269     /*
    270      * Another fallback test.   Paths ending with a trailing directory separator
    271      *    take a slightly different code path, with the "base name" from the path
    272      *    being empty in the internal udata_open logic.
    273      */
    274 
    275 /*      log_verbose("Testing udata_open, with path containing a trailing directory separator.\n"); */
    276 /*      icuDataFilePath = (char *)malloc(strlen(u_getDataDirectory()) + 50); */
    277 /*      strcpy(icuDataFilePath, testPath); */
    278 /*      status = U_ZERO_ERROR; */
    279 /*      result = udata_open( icuDataFilePath, "cnv", "test1", &status); */
    280 /*      if (status != U_ZERO_ERROR) { */
    281 /*          log_err("FAIL: udata_open( \"%s\", \"cnv\", \"test1\") returned status %s\n", icuDataFilePath, u_errorName(status)); */
    282 /*      } */
    283 /*      udata_close(result); */
    284 /*      free(icuDataFilePath); */
    285 
    286 
    287     log_verbose("Testing udata_open() with a non existing binary file\n");
    288     result=udata_open("testdata", "tst", "nonexist", &status);
    289     if(status==U_FILE_ACCESS_ERROR){
    290         log_verbose("Opening udata_open with non-existing file handled correctly.\n");
    291         status=U_ZERO_ERROR;
    292     } else {
    293         log_err("calling udata_open with non-existing file  [testdata | nonexist.tst] not handled correctly\n.  Expected: U_FILE_ACCESS_ERROR, Got: %s\n", myErrorName(status));
    294         if(U_SUCCESS(status)) {
    295             udata_close(result);
    296         }
    297     }
    298 
    299     if(result != NULL){
    300         log_err("calling udata_open with non-existing file didn't return a null value\n");
    301     } else {
    302         log_verbose("calling udat_open with non-existing file returned null as expected\n");
    303     }
    304 
    305     /*
    306      *  Try opening data with absurdly long path and name, to trigger buffer size
    307      *   overflow handling code.
    308      */
    309     {
    310         char longTestPath[1024];    /* Implementation goes to heap at length of 128.  */
    311         char longName[1024];
    312 
    313         /* Try a very long nonexistent directory path.
    314          * udata_open should still succeed.  Opening with the path will fail,
    315          * then fall back to skipping the directory portion of the path.
    316          */
    317         log_verbose("Testing udata_open() with really long names\n");
    318         longTestPath[0] = 0;
    319         strcat(longTestPath, "bogus_directory_name");
    320         while (strlen(longTestPath) < 500) {
    321             strcat(longTestPath, dirSepString);
    322             strcat(longTestPath, "bogus_directory_name");
    323         }
    324         strcat(longTestPath, pathSepString);
    325         strcat(longTestPath, testPath);
    326         result=udata_open(longTestPath, type, name, &status);
    327         if(U_FAILURE(status)){
    328             log_data_err("FAIL: udata_open() failed for path = %s\n name=%s, type=%s, \n errorcode=%s\n",
    329                 longTestPath, name, type, myErrorName(status));
    330         } else {
    331             log_verbose("PASS: udata_open worked\n");
    332             udata_close(result);
    333         }
    334 
    335         /* Try a very long name.  Won't open, but shouldn't blow up.
    336          */
    337         longName[0] = 0;
    338         while (strlen(longName) < 500) {
    339             strcat(longName, name);
    340             strcat(longName, "_");
    341         }
    342         strcat(longName, dirSepString);
    343         strcat(longName, name);
    344 
    345         result=udata_open(longTestPath, type, longName, &status);
    346         if (status != U_FILE_ACCESS_ERROR) {
    347             log_data_err("FAIL: udata_open() failed for path = %s\n name=%s, type=%s, \n errorcode=%s\n",
    348                 longTestPath, longName, type, myErrorName(status));
    349         }
    350         udata_close(result);
    351     }
    352 
    353     free(path);
    354 }
    355 #endif
    356 
    357 typedef struct {
    358     uint16_t headerSize;
    359     uint8_t magic1, magic2;
    360     UDataInfo info;
    361     char padding[8];
    362     uint32_t count, reserved;
    363     /*
    364     const struct {
    365     const char *const name;
    366     const void *const data;
    367     } toc[1];
    368     */
    369    int32_t   fakeNameAndData[4];
    370 } ICU_COMMON_Data_Header;
    371 
    372 static const ICU_COMMON_Data_Header gEmptyHeader = {
    373     32,          /* headerSize */
    374     0xda,        /* magic1,  (see struct MappedData in udata.c)  */
    375     0x27,        /* magic2     */
    376     {            /*UDataInfo   */
    377         sizeof(UDataInfo),      /* size        */
    378         0,                      /* reserved    */
    379 
    380 #if U_IS_BIG_ENDIAN
    381         1,
    382 #else
    383         0,
    384 #endif
    385 
    386         U_CHARSET_FAMILY,
    387         sizeof(UChar),
    388         0,               /* reserved      */
    389         {                /* data format identifier */
    390            0x43, 0x6d, 0x6e, 0x44}, /* "CmnD" */
    391            {1, 0, 0, 0},   /* format version major, minor, milli, micro */
    392            {0, 0, 0, 0}    /* dataVersion   */
    393     },
    394     {0,0,0,0,0,0,0,0},  /* Padding[8]   */
    395     0,                  /* count        */
    396     0,                  /* Reserved     */
    397     {                   /*  TOC structure */
    398 /*        {    */
    399           0 , 0 , 0, 0  /* name and data entries.  Count says there are none,  */
    400                         /*  but put one in just in case.                       */
    401 /*        }  */
    402     }
    403 };
    404 
    405 
    406 static void TestUDataSetAppData(){
    407 /*    UDataMemory      *dataItem;*/
    408 
    409     UErrorCode        status=U_ZERO_ERROR;
    410 
    411     /*
    412      * First we try some monkey business and try to do bad things.
    413      */
    414 
    415     status=U_ZERO_ERROR;
    416     udata_setAppData("appData1", NULL, &status);
    417     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
    418         log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData1\", NULL, status) should have failed."
    419                 " It returned status of %s\n", u_errorName(status));
    420         return;
    421     }
    422     /* The following call should fail.
    423        If the following works with a bad UErrorCode, then later calls to appData1 should fail. */
    424     udata_setAppData("appData1", &gEmptyHeader, &status);
    425 
    426     /*
    427      * Got testdata.dat into memory, now we try setAppData using the memory image.
    428      */
    429 
    430     status=U_ZERO_ERROR;
    431     udata_setAppData("appData1", &gEmptyHeader, &status);
    432     if (status != U_ZERO_ERROR) {
    433         log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData1\", fileBuf, status) "
    434                 " returned status of %s\n", u_errorName(status));
    435         return;
    436     }
    437 
    438     udata_setAppData("appData2", &gEmptyHeader, &status);
    439     if (status != U_ZERO_ERROR) {
    440         log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData2\", fileBuf, status) "
    441                 " returned status of %s\n", u_errorName(status));
    442         return;
    443     }
    444 
    445     /*  If we try to setAppData with the same name a second time, we should get a
    446      *    a using default warning.
    447      */
    448     udata_setAppData("appData2", &gEmptyHeader, &status);
    449     if (status != U_USING_DEFAULT_WARNING) {
    450         log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData2\", fileBuf, status) "
    451                 " returned status of %s, expected U_USING_DEFAULT_WARNING.\n", u_errorName(status));
    452     }
    453 
    454 
    455     /** It is no longer  correct to use udata_setAppData to change the
    456         package of a contained item.
    457 
    458         dataItem = udata_open("appData1", "res", "te_IN", &status); **/
    459 }
    460 
    461 static char *safeGetICUDataDirectory() {
    462     const char *dataDir = u_getDataDirectory();  /* Returned string vanashes with u_cleanup */
    463     char *retStr = NULL;
    464     if (dataDir != NULL) {
    465         retStr = (char *)malloc(strlen(dataDir)+1);
    466         strcpy(retStr, dataDir);
    467     }
    468     return retStr;
    469 }
    470 
    471 static void TestUDataFileAccess(){
    472     UErrorCode status;
    473     char            *icuDataDir;
    474     icuDataDir = safeGetICUDataDirectory();   /* save icu data dir, so we can put it back
    475                                                *  after doing u_cleanup().                */
    476 
    477     /** UDATA_NO_FILES, ICU does not access the file system for data loading. */
    478     status=U_ZERO_ERROR;
    479     u_cleanup();
    480     udata_setFileAccess(UDATA_NO_FILES,&status);
    481     u_init(&status);
    482     if(U_FAILURE(status) && *icuDataDir == 0){
    483         log_data_err("udata_setFileAccess(UDATA_NO_FILES) failed with ICU_DATA=\"\" err=%s\n", u_errorName(status));
    484     }
    485 
    486     /** UDATA_ONLY_PACKAGES, ICU only loads data from packages, not from single files. */
    487     status=U_ZERO_ERROR;
    488     u_cleanup();
    489     udata_setFileAccess(UDATA_ONLY_PACKAGES,&status);
    490     u_init(&status);
    491 
    492     /** UDATA_PACKAGES_FIRST, ICU loads data from packages first, and only from single files
    493         if the data cannot be found in a package. */
    494     status=U_ZERO_ERROR;
    495     u_cleanup();
    496     udata_setFileAccess(UDATA_PACKAGES_FIRST,&status);
    497     u_init(&status);
    498 
    499     /** UDATA_FILES_FIRST, ICU looks for data in single files first, then in packages. (default) */
    500     status=U_ZERO_ERROR;
    501     u_cleanup();
    502     udata_setFileAccess(UDATA_FILES_FIRST,&status);
    503     u_init(&status);
    504 
    505     /** An alias for the default access mode. */
    506     status=U_ZERO_ERROR;
    507     u_cleanup();
    508     udata_setFileAccess(UDATA_DEFAULT_ACCESS,&status);
    509     u_setDataDirectory(icuDataDir);
    510     u_init(&status);
    511     if(U_FAILURE(status)){
    512         log_err_status(status, "%s\n", u_errorName(status));
    513     }
    514     free(icuDataDir);
    515     ctest_resetICU();
    516 }
    517 
    518 
    519 static UBool U_CALLCONV
    520 isAcceptable1(void *context,
    521              const char *type, const char *name,
    522              const UDataInfo *pInfo) {
    523 
    524     if( pInfo->size>=20 &&
    525         pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
    526         pInfo->charsetFamily==U_CHARSET_FAMILY &&
    527         pInfo->dataFormat[0]==0x43 &&   /* dataFormat="CvAl" */
    528         pInfo->dataFormat[1]==0x76 &&
    529         pInfo->dataFormat[2]==0x41 &&
    530         pInfo->dataFormat[3]==0x6c &&
    531         pInfo->formatVersion[0]==3 )
    532     {
    533         log_verbose("The data from \"%s.%s\" IS acceptable using the verifing function isAcceptable1()\n", name, type);
    534         return TRUE;
    535     } else {
    536         log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable1():-\n"
    537             "\tsize              = %d\n"
    538             "\tisBigEndian       = %d\n"
    539             "\tcharsetFamily     = %d\n"
    540             "\tformatVersion[0]  = %d\n"
    541             "\tdataVersion[0]    = %d\n"
    542             "\tdataFormat        = %c%c%c%c\n",
    543             name, type, pInfo->size,  pInfo->isBigEndian, pInfo->charsetFamily, pInfo->formatVersion[0],
    544             pInfo->dataVersion[0], pInfo->dataFormat[0], pInfo->dataFormat[1], pInfo->dataFormat[2],
    545             pInfo->dataFormat[3]);
    546         log_verbose("Call another verifing function to accept the data\n");
    547         return FALSE;
    548     }
    549 }
    550 
    551 static UBool U_CALLCONV
    552 isAcceptable2(void *context,
    553              const char *type, const char *name,
    554       const UDataInfo *pInfo){
    555     UVersionInfo unicodeVersion;
    556 
    557     u_getUnicodeVersion(unicodeVersion);
    558 
    559     if( pInfo->size>=20 &&
    560         pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
    561         pInfo->charsetFamily==U_CHARSET_FAMILY &&
    562         pInfo->dataFormat[0]==0x75 &&   /* dataFormat="unam" */
    563         pInfo->dataFormat[1]==0x6e &&
    564         pInfo->dataFormat[2]==0x61 &&
    565         pInfo->dataFormat[3]==0x6d &&
    566         pInfo->formatVersion[0]==1 &&
    567         pInfo->dataVersion[0]==unicodeVersion[0] )
    568     {
    569         log_verbose("The data from \"%s.%s\" IS acceptable using the verifing function isAcceptable2()\n", name, type);
    570         return TRUE;
    571     } else {
    572         log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable2()\n", name, type);
    573 
    574         return FALSE;
    575     }
    576 
    577 
    578 }
    579 static UBool U_CALLCONV
    580 isAcceptable3(void *context,
    581              const char *type, const char *name,
    582              const UDataInfo *pInfo){
    583 
    584     if( pInfo->size>=20 &&
    585         pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
    586         pInfo->charsetFamily==U_CHARSET_FAMILY &&
    587         pInfo->dataFormat[0]==0x54 &&   /* dataFormat="test" */
    588         pInfo->dataFormat[1]==0x65 &&
    589         pInfo->dataFormat[2]==0x73 &&
    590         pInfo->dataFormat[3]==0x74 &&
    591         pInfo->formatVersion[0]==1 &&
    592         pInfo->dataVersion[0]==1   ) {
    593         log_verbose("The data from \"%s.%s\" IS acceptable using the verifing function isAcceptable3()\n", name, type);
    594 
    595         return TRUE;
    596     } else {
    597         log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable3()\n", name, type);
    598         return FALSE;
    599     }
    600 
    601 
    602 }
    603 
    604 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
    605 static void TestUDataOpenChoiceDemo1() {
    606     UDataMemory *result;
    607     UErrorCode status=U_ZERO_ERROR;
    608 
    609     const char* name[]={
    610         "cnvalias",
    611         "unames",
    612         "test",
    613         "nam"
    614     };
    615     const char* type="icu";
    616     const char* testPath="testdata";
    617     const char* fullTestDataPath = loadTestData(&status);
    618     if(U_FAILURE(status)) {
    619         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
    620         return;
    621     }
    622 
    623     result=udata_openChoice(NULL, "icu", name[0], isAcceptable1, NULL, &status);
    624     if(U_FAILURE(status)){
    625         log_data_err("FAIL: udata_openChoice() failed name=%s, type=%s, \n errorcode=%s\n", name[0], type, myErrorName(status));
    626     } else {
    627         log_verbose("PASS: udata_openChoice worked\n");
    628         udata_close(result);
    629     }
    630 
    631     status=U_ZERO_ERROR;
    632     result=udata_openChoice(NULL, type, name[1], isAcceptable1, NULL, &status);
    633     if(U_FAILURE(status)){
    634         status=U_ZERO_ERROR;
    635         result=udata_openChoice(NULL, type, name[1], isAcceptable2, NULL, &status);
    636         if(U_FAILURE(status)){
    637             log_data_err("FAIL: udata_openChoice() failed name=%s, type=%s, \n errorcode=%s\n", name[1], type, myErrorName(status));
    638         }
    639     }
    640     else {
    641         log_err("FAIL: udata_openChoice() unexpectedly passed. name=%s, type=%s, \n errorcode=%s\n", name[1], type, myErrorName(status));
    642     }
    643 
    644     if(U_SUCCESS(status)){
    645         udata_close(result);
    646     }
    647 
    648     status=U_ZERO_ERROR;
    649     result=udata_openChoice(testPath, type, name[2], isAcceptable1, NULL, &status);
    650     if(U_FAILURE(status)){
    651         status=U_ZERO_ERROR;
    652         result=udata_openChoice(testPath, type, name[2], isAcceptable3, NULL, &status);
    653         if(U_FAILURE(status)){
    654             log_data_err("FAIL: udata_openChoice() failed path=%s name=%s, type=%s, \n errorcode=%s\n", testPath, name[2], type, myErrorName(status));
    655         }
    656     }
    657     else {
    658         log_err("FAIL: udata_openChoice() unexpectedly passed. name=%s, type=%s, \n errorcode=%s\n", name[2], type, myErrorName(status));
    659     }
    660 
    661     if(U_SUCCESS(status)){
    662         udata_close(result);
    663     }
    664 
    665     status=U_ZERO_ERROR;
    666     type="typ";
    667     result=udata_openChoice(fullTestDataPath, type, name[3], isAcceptable1, NULL, &status);
    668     if(status != U_INVALID_FORMAT_ERROR){
    669         log_err("FAIL: udata_openChoice() did not fail as expected. name=%s, type=%s, \n errorcode=%s\n", name[3], type, myErrorName(status));
    670     }
    671 
    672     status=U_USELESS_COLLATOR_ERROR;
    673     result=udata_openChoice(fullTestDataPath, type, name[3], isAcceptable1, NULL, &status);
    674     if(status != U_USELESS_COLLATOR_ERROR){
    675         log_err("FAIL: udata_openChoice() did not fail as expected. name=%s, type=%s, \n errorcode=%s\n", name[3], type, myErrorName(status));
    676     }
    677 }
    678 
    679 static UBool U_CALLCONV
    680 isAcceptable(void *context,
    681              const char *type, const char *name,
    682              const UDataInfo *pInfo){
    683     if( pInfo->size>=20 &&
    684         pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
    685         pInfo->charsetFamily==U_CHARSET_FAMILY &&
    686         pInfo->dataFormat[0]==0x54 &&   /* dataFormat="test" */
    687         pInfo->dataFormat[1]==0x65 &&
    688         pInfo->dataFormat[2]==0x73 &&
    689         pInfo->dataFormat[3]==0x74 &&
    690         pInfo->formatVersion[0]==1 &&
    691         pInfo->dataVersion[0]==1   &&
    692         *((int*)context) == 2 ) {
    693         log_verbose("The data from\"%s.%s\" IS acceptable using the verifing function isAcceptable()\n", name, type);
    694 
    695         return TRUE;
    696     } else {
    697         log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable()\n", name, type);
    698         return FALSE;
    699     }
    700 }
    701 
    702 
    703 /* This test checks to see if the isAcceptable function is being called correctly. */
    704 
    705 static void TestUDataOpenChoiceDemo2() {
    706     UDataMemory *result;
    707     UErrorCode status=U_ZERO_ERROR;
    708     int i;
    709     int p=2;
    710 
    711     const char* name="test";
    712     const char* type="icu";
    713     const char* path = loadTestData(&status);
    714     if(U_FAILURE(status)) {
    715         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
    716         return;
    717     }
    718 
    719     result=udata_openChoice(path, type, name, isAcceptable, &p, &status);
    720     if(U_FAILURE(status)){
    721         log_data_err("failed to load data at p=%s t=%s n=%s, isAcceptable", path, type, name);
    722     }
    723     if(U_SUCCESS(status) ) {
    724         udata_close(result);
    725     }
    726 
    727     p=0;
    728     for(i=0;i<2; i++){
    729         result=udata_openChoice(path, type, name, isAcceptable, &p, &status);
    730         if(p<2) {
    731             if(U_FAILURE(status) && status==U_INVALID_FORMAT_ERROR){
    732                 log_verbose("Loads the data but rejects it as expected %s\n", myErrorName(status));
    733                 status=U_ZERO_ERROR;
    734                 p++;
    735             }
    736             else {
    737                 log_data_err("FAIL: failed to either load the data or to reject the loaded data. ERROR=%s\n", myErrorName(status) );
    738             }
    739         }
    740         else if(p == 2) {
    741             if(U_FAILURE(status)) {
    742                 log_data_err("FAIL: failed to load the data and accept it.  ERROR=%s\n", myErrorName(status) );
    743             }
    744             else {
    745                 log_verbose("Loads the data and accepts it for p==2 as expected\n");
    746                 udata_close(result);
    747             }
    748         }
    749     }
    750 }
    751 
    752 static void TestUDataGetInfo() {
    753 
    754     UDataMemory *result;
    755     /* UDataInfo cf. udata.h */
    756     static UDataInfo dataInfo={
    757     30,    /*sizeof(UDataInfo),*/
    758     0,
    759 
    760     U_IS_BIG_ENDIAN,
    761     U_CHARSET_FAMILY,
    762     sizeof(UChar),
    763     0,
    764 
    765     {0x54, 0x65, 0x73, 0x74},     /* dataFormat="Test" */
    766     {9, 0, 0, 0},                 /* formatVersion */
    767     {4, 0, 0, 0}                  /* dataVersion */
    768     };
    769     UErrorCode status=U_ZERO_ERROR;
    770     const char* name="cnvalias";
    771     const char* name2="test";
    772     const char* type="icu";
    773 
    774     const char* testPath=loadTestData(&status);
    775     if(U_FAILURE(status)) {
    776         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
    777         return;
    778     }
    779 
    780     log_verbose("Testing udata_getInfo() for cnvalias.icu\n");
    781     result=udata_open(NULL, "icu", name, &status);
    782     if(U_FAILURE(status)){
    783         log_data_err("FAIL: udata_open() failed for path = NULL, name=%s, type=%s, \n errorcode=%s\n",  name, type, myErrorName(status));
    784         return;
    785     }
    786     udata_getInfo(result, &dataInfo);
    787     if(dataInfo.size==20            &&  dataInfo.size!=30 &&
    788         dataInfo.isBigEndian==U_IS_BIG_ENDIAN       &&
    789         dataInfo.charsetFamily==U_CHARSET_FAMILY    &&
    790         dataInfo.dataFormat[0]==0x43 &&  dataInfo.dataFormat[0]!=0x54 && /* dataFormat="CvAl" and not "Test". The values are set for cnvalias.dat*/
    791         dataInfo.dataFormat[1]==0x76 &&  dataInfo.dataFormat[1]!=0x65 &&
    792         dataInfo.dataFormat[2]==0x41 &&  dataInfo.dataFormat[2]!=0x73 &&
    793         dataInfo.dataFormat[3]==0x6c &&  dataInfo.dataFormat[3]!=0x74 &&
    794         dataInfo.formatVersion[0]!=9 && /*formatVersion is also set to the one for cnvalias*/
    795         dataInfo.dataVersion[0]!=4   && /*dataVersion*/
    796         dataInfo.dataVersion[1]!=0   ){
    797             log_verbose("PASS: udata_getInfo() filled in the right values\n");
    798     } else {
    799         log_err("FAIL: udata_getInfo() filled in the wrong values\n");
    800     }
    801     udata_close(result);
    802 
    803 
    804     log_verbose("Testing udata_getInfo() for test.icu\n");
    805     result=udata_open(testPath, type, name2, &status);
    806     if(U_FAILURE(status)) {
    807        log_data_err("FAIL: udata_open() failed for path=%s name2=%s, type=%s, \n errorcode=%s\n", testPath, name2, type, myErrorName(status));
    808        return;
    809     }
    810     udata_getInfo(result, &dataInfo);
    811     if(dataInfo.size==20             &&
    812         dataInfo.isBigEndian==U_IS_BIG_ENDIAN       &&
    813         dataInfo.charsetFamily==U_CHARSET_FAMILY    &&
    814         dataInfo.dataFormat[0]==0x54 &&   /* dataFormat="Test". The values are set for test.dat*/
    815         dataInfo.dataFormat[1]==0x65 &&
    816         dataInfo.dataFormat[2]==0x73 &&
    817         dataInfo.dataFormat[3]==0x74 &&
    818         dataInfo.formatVersion[0]==1 &&  /*formatVersion is also set to the one for test*/
    819         dataInfo.dataVersion[0]==1   &&  /*dataVersion*/
    820         dataInfo.dataVersion[1]==0   )
    821     {
    822         log_verbose("PASS: udata_getInfo() filled in the right values\n");
    823     } else {
    824         log_err("FAIL: udata_getInfo() filled in the wrong values\n");
    825     }
    826     udata_close(result);
    827 }
    828 
    829 static void TestUDataGetMemory() {
    830 
    831     UDataMemory *result;
    832     const int32_t *table=NULL;
    833     uint16_t* intValue=0;
    834     UErrorCode status=U_ZERO_ERROR;
    835     const char* name="cnvalias";
    836     const char* type;
    837 
    838     const char* name2="test";
    839 
    840     const char* testPath = loadTestData(&status);
    841     if(U_FAILURE(status)) {
    842         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
    843         return;
    844     }
    845 
    846     type="icu";
    847     log_verbose("Testing udata_getMemory() for \"cnvalias.icu\"\n");
    848     result=udata_openChoice(NULL, type, name, isAcceptable1, NULL, &status);
    849     if(U_FAILURE(status)){
    850         log_data_err("FAIL: udata_openChoice() failed for name=%s, type=%s, \n errorcode=%s\n", name, type, myErrorName(status));
    851         return;
    852     }
    853     table=(const int32_t *)udata_getMemory(result);
    854 
    855     /* The alias table may list more converters than what's actually available now. [grhoten] */
    856     if(ucnv_countAvailable() > table[1])      /*???*/
    857         log_err("FAIL: udata_getMemory() failed ucnv_countAvailable returned = %d, expected = %d\n", ucnv_countAvailable(), table[1+2*(*table)]);
    858 
    859     udata_close(result);
    860 
    861     type="icu";
    862     log_verbose("Testing udata_getMemory for \"test.icu\"()\n");
    863     result=udata_openChoice(testPath, type, name2, isAcceptable3, NULL, &status);
    864     if(U_FAILURE(status)){
    865         log_data_err("FAIL: udata_openChoice() failed for path=%s name=%s, type=%s, \n errorcode=%s\n", testPath, name2, type, myErrorName(status));
    866         return;
    867     }
    868     intValue=(uint16_t *)udata_getMemory(result);
    869     /*printf("%d ..... %s", *(intValue), intValue+1));*/
    870     if( *intValue != 2000 || strcmp((char*)(intValue+1), "YEAR") != 0 )
    871         log_err("FAIL: udata_getMemory() failed: intValue :- Expected:2000 Got:%d \n\tstringValue:- Expected:YEAR Got:%s\n", *intValue, (intValue+1));
    872 
    873     udata_close(result);
    874 
    875 }
    876 
    877 static void TestErrorConditions(){
    878 
    879     UDataMemory *result=NULL;
    880     UErrorCode status=U_ZERO_ERROR;
    881     uint16_t* intValue=0;
    882     static UDataInfo dataInfo={
    883         30,    /*sizeof(UDataInfo),*/
    884         0,
    885 
    886         U_IS_BIG_ENDIAN,
    887         U_CHARSET_FAMILY,
    888         sizeof(UChar),
    889         0,
    890 
    891         {0x54, 0x65, 0x73, 0x74},     /* dataFormat="Test" */
    892         {9, 0, 0, 0},                 /* formatVersion */
    893         {4, 0, 0, 0}                  /* dataVersion */
    894     };
    895 
    896     const char* name = "test";
    897     const char* type="icu";
    898 
    899     const char *testPath = loadTestData(&status);
    900     if(U_FAILURE(status)) {
    901         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
    902         return;
    903     }
    904 
    905     status = U_ILLEGAL_ARGUMENT_ERROR;
    906     /*Try udata_open with status != U_ZERO_ERROR*/
    907     log_verbose("Testing udata_open() with status != U_ZERO_ERROR\n");
    908     result=udata_open(testPath, type, name, &status);
    909     if(result != NULL){
    910         log_data_err("FAIL: udata_open() is supposed to fail for path = %s, name=%s, type=%s, \n errorcode !=U_ZERO_ERROR\n", testPath, name, type);
    911         udata_close(result);
    912 
    913     } else {
    914         log_verbose("PASS: udata_open with errorCode != U_ZERO_ERROR failed as expected\n");
    915     }
    916 
    917     /*Try udata_open with data name=NULL*/
    918     log_verbose("Testing udata_open() with data name=NULL\n");
    919     status=U_ZERO_ERROR;
    920     result=udata_open(testPath, type, NULL, &status);
    921     if(U_FAILURE(status)){
    922         if(status != U_ILLEGAL_ARGUMENT_ERROR || result != NULL){
    923             log_err("FAIL: udata_open() with name=NULL should return NULL and errocode U_ILLEGAL_ARGUMENT_ERROR, GOT: errorcode=%s\n", myErrorName(status));
    924         }else{
    925             log_verbose("PASS: udata_open with name=NULL failed as expected and errorcode = %s as expected\n", myErrorName(status));
    926         }
    927     }else{
    928         log_err("FAIL: udata_open() with data name=NULL is supposed to fail for path = %s, name=NULL type=%s errorcode=U_ZERO_ERROR \n", testPath, type);
    929         udata_close(result);
    930     }
    931 
    932 
    933     /*Try udata_openChoice with status != U_ZERO_ERROR*/
    934     log_verbose("Testing udata_openChoice() with status != U_ZERO_ERROR\n");
    935     status=U_ILLEGAL_ARGUMENT_ERROR;
    936     result=udata_openChoice(testPath, type, name, isAcceptable3, NULL, &status);
    937     if(result != NULL){
    938         log_err("FAIL: udata_openChoice() is supposed to fail for path = %s, name=%s, type=%s, \n errorcode != U_ZERO_ERROR\n", testPath, name, type);
    939         udata_close(result);
    940     } else {
    941         log_verbose("PASS: udata_openChoice() with errorCode != U_ZERO_ERROR failed as expected\n");
    942     }
    943 
    944     /*Try udata_open with data name=NULL*/
    945     log_verbose("Testing udata_openChoice() with data name=NULL\n");
    946     status=U_ZERO_ERROR;
    947     result=udata_openChoice(testPath, type, NULL, isAcceptable3, NULL, &status);
    948     if(U_FAILURE(status)){
    949         if(status != U_ILLEGAL_ARGUMENT_ERROR || result != NULL){
    950             log_err("FAIL: udata_openChoice() with name=NULL should return NULL and errocode U_ILLEGAL_ARGUMENT_ERROR, GOT: errorcode=%s\n", myErrorName(status));
    951         }else{
    952             log_verbose("PASS: udata_openChoice with name=NULL failed as expected and errorcode = %s as expected\n", myErrorName(status));
    953         }
    954     }else{
    955         log_err("FAIL: udata_openChoice() with data name=NULL is supposed to fail for path = %s, name=NULL type=%s errorcode=U_ZERO_ERROR \n", testPath, type);
    956         udata_close(result);
    957     }
    958 
    959     /*Try udata_getMemory with UDataMemory=NULL*/
    960     log_verbose("Testing udata_getMemory with UDataMemory=NULL\n");
    961     intValue=(uint16_t*)udata_getMemory(NULL);
    962     if(intValue != NULL){
    963         log_err("FAIL: udata_getMemory with UDataMemory = NULL is supposed to fail\n");
    964     }
    965 
    966     /*Try udata_getInfo with UDataMemory=NULL*/
    967     status=U_ZERO_ERROR;
    968     udata_getInfo(NULL, &dataInfo);
    969     if(dataInfo.size != 0){
    970         log_err("FAIL : udata_getInfo with UDataMemory = NULL us supposed to fail\n");
    971     }
    972 
    973     /*Try udata_openChoice with a non existing binary file*/
    974     log_verbose("Testing udata_openChoice() with a non existing binary file\n");
    975     result=udata_openChoice(testPath, "tst", "nonexist", isAcceptable3, NULL, &status);
    976     if(status==U_FILE_ACCESS_ERROR){
    977         log_verbose("Opening udata_openChoice with non-existing file handled correctly.\n");
    978         status=U_ZERO_ERROR;
    979     } else {
    980         log_err("calling udata_open with non-existing file not handled correctly\n.  Expected: U_FILE_ACCESS_ERROR, Got: %s\n", myErrorName(status));
    981         if(U_SUCCESS(status)) {
    982             udata_close(result);
    983         }
    984     }
    985 
    986     if(result != NULL){
    987         log_err("calling udata_open with non-existing file didn't return a null value\n");
    988     } else {
    989         log_verbose("calling udat_open with non-existing file returned null as expected\n");
    990     }
    991 }
    992 
    993 /* Test whether apps and ICU can each have their own root.res */
    994 static void TestAppData()
    995 {
    996     UResourceBundle *icu, *app;
    997     UResourceBundle *tmp = NULL;
    998     UResourceBundle *tmp2 = NULL;
    999 
   1000     const UChar *appString;
   1001     const UChar *icuString;
   1002 
   1003     int32_t len;
   1004 
   1005     UErrorCode status = U_ZERO_ERROR;
   1006     char testMsgBuf[256];
   1007 
   1008     const char* testPath=loadTestData(&status);
   1009     if(U_FAILURE(status)) {
   1010         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
   1011         return;
   1012     }
   1013 
   1014     icu = ures_open(NULL, "root", &status);
   1015     if(U_FAILURE(status))
   1016     {
   1017         log_data_err("%s:%d: Couldn't open root ICU bundle- %s", __FILE__, __LINE__, u_errorName(status));
   1018         return;
   1019     }
   1020     /*  log_info("Open icu root: %s size_%d\n", u_errorName(status), ures_getSize(icu)); */
   1021     status = U_ZERO_ERROR;
   1022 
   1023     app = ures_open(testPath, "root", &status);
   1024     if(U_FAILURE(status))
   1025     {
   1026         log_data_err("%s:%d: Couldn't open app ICU bundle [%s]- %s", __FILE__, __LINE__, testPath, u_errorName(status));
   1027         return;
   1028     }
   1029     /* log_info("Open  app: %s, size %d\n", u_errorName(status), ures_getSize(app)); */
   1030 
   1031     tmp = ures_getByKey(icu, "Version", tmp, &status);
   1032     if(U_FAILURE(status))
   1033     {
   1034         log_err("%s:%d: Couldn't get Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status));
   1035         return;
   1036     }
   1037 
   1038     icuString =  ures_getString(tmp,  &len, &status);
   1039     if(U_FAILURE(status))
   1040     {
   1041         log_err("%s:%d: Couldn't get string from Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status));
   1042         return;
   1043     }
   1044     /* log_info("icuString=%p - %s\n", icuString, austrdup(icuString)); */
   1045 
   1046 
   1047     tmp2 = ures_getByKey(app, "Version", tmp2, &status);
   1048     if(U_FAILURE(status))
   1049     {
   1050         log_err("%s:%d: Couldn't get Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status));
   1051         return;
   1052     }
   1053 
   1054     appString =  ures_getString(tmp2,  &len, &status);
   1055     if(U_FAILURE(status))
   1056     {
   1057         log_err("%s:%d: Couldn't get string from Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status));
   1058         return;
   1059     }
   1060 
   1061     /* log_info("appString=%p - %s\n", appString, austrdup(appString)); */
   1062 
   1063 
   1064     if(!u_strcmp(icuString, appString))
   1065     {
   1066         log_err("%s:%d: Error! Expected ICU and App root version strings to be DIFFERENT but they are both %s and %s\n", __FILE__, __LINE__, austrdup(icuString),
   1067             austrdup(appString));
   1068     }
   1069     else
   1070     {
   1071         log_verbose("%s:%d:  appstr=%s, icustr=%s\n", __FILE__,
   1072             __LINE__, u_austrcpy(testMsgBuf, appString), u_austrcpy(testMsgBuf, icuString));
   1073     }
   1074 
   1075     ures_close(tmp);
   1076     ures_close(tmp2);
   1077     ures_close(icu);
   1078     ures_close(app);
   1079 }
   1080 #endif
   1081 
   1082 static void TestICUDataName()
   1083 {
   1084     UVersionInfo icuVersion;
   1085     char expectDataName[20];
   1086     unsigned int expectLen = 8;
   1087 
   1088     char typeChar  = '?';
   1089 
   1090     /* Print out the version # we have .. */
   1091     log_verbose("utypes.h says U_ICUDATA_NAME = %s\n", U_ICUDATA_NAME);
   1092 
   1093     /* Build up the version # we expect to get */
   1094     u_getVersion(icuVersion);
   1095 
   1096     switch(U_CHARSET_FAMILY)
   1097     {
   1098     case U_ASCII_FAMILY:
   1099           switch(U_IS_BIG_ENDIAN)
   1100           {
   1101           case 1:
   1102                 typeChar = 'b';
   1103                 break;
   1104           case 0:
   1105                 typeChar = 'l';
   1106                 break;
   1107           default:
   1108                 log_err("Expected 1 or 0 for U_IS_BIG_ENDIAN, got %d!\n", (int)U_IS_BIG_ENDIAN);
   1109                 /* return; */
   1110           }
   1111           break;
   1112     case U_EBCDIC_FAMILY:
   1113         typeChar = 'e';
   1114         break;
   1115     }
   1116 
   1117     /* Only major number is needed. */
   1118     sprintf(expectDataName, "%s%d%c",
   1119                 "icudt",
   1120                 (int)icuVersion[0],
   1121                 typeChar);
   1122 
   1123     log_verbose("Expected: %s\n", expectDataName);
   1124     if(uprv_strlen(expectDataName) != expectLen)
   1125     {
   1126         log_err("*Expected* length is wrong (test err?), should be %d is %d\n",
   1127             expectLen, uprv_strlen(expectDataName));
   1128     }
   1129 
   1130     if(uprv_strlen(U_ICUDATA_NAME) != expectLen)
   1131     {
   1132         log_err("U_ICUDATA_NAME length should be %d is %d\n",
   1133             expectLen, uprv_strlen(U_ICUDATA_NAME));
   1134     }
   1135 
   1136     if(uprv_strcmp(U_ICUDATA_NAME, expectDataName))
   1137     {
   1138         log_err("U_ICUDATA_NAME should be %s but is %s\n",
   1139                 expectDataName, U_ICUDATA_NAME);
   1140     }
   1141 
   1142         /* ICUDATA_NAME comes from the build system on *nix */
   1143 #ifdef ICUDATA_NAME
   1144     if(uprv_strcmp(U_ICUDATA_NAME, ICUDATA_NAME))
   1145     {
   1146         log_err("ICUDATA_NAME  and U_ICUDATA_NAME don't match: "
   1147             "ICUDATA_NAME=%s, U_ICUDATA_NAME=%s.  Check configure.in, icudefs.mk.in, utypes.h...\n",  ICUDATA_NAME, U_ICUDATA_NAME);
   1148     }
   1149     else
   1150     {
   1151         log_verbose("ICUDATA_NAME=%s (from icudefs.mk), U_ICUDATA_NAME=%s (from utypes.h)\n", ICUDATA_NAME, U_ICUDATA_NAME);
   1152     }
   1153 #endif
   1154 
   1155 }
   1156 
   1157 /* test data swapping ------------------------------------------------------- */
   1158 
   1159 #if U_PLATFORM == U_PF_OS400
   1160 /* See comments in genccode.c on when this special implementation can be removed. */
   1161 static const struct {
   1162     double bogus;
   1163     const char *bytes;
   1164 } gOffsetTOCAppDataItem1={ 0.0, /* alignment bytes */
   1165     "\x00\x14" /* sizeof(UDataInfo) *//* MappedData { */
   1166     "\xda"
   1167     "\x27"                            /* } */
   1168     "\x00\x14" /* sizeof(UDataInfo) *//* UDataInfo  { */
   1169     "\0\0"
   1170     "\1"       /* U_IS_BIG_ENDIAN   */
   1171     "\1"       /* U_CHARSET_FAMILY  */
   1172     "\2"       /* U_SIZEOF_WHAR_T   */
   1173     "\0"
   1174     "\x31\x31\x31\x31"
   1175     "\0\0\0\0"
   1176     "\0\0\0\0"                        /* } */
   1177 };
   1178 #else
   1179 static const struct {
   1180     double bogus;
   1181     MappedData bytes1;
   1182     UDataInfo bytes2;
   1183     uint8_t bytes3;
   1184 } gOffsetTOCAppDataItem1={
   1185     0.0,                            /* alignment bytes */
   1186     { sizeof(UDataInfo), 0xda, 0x27 },  /* MappedData */
   1187 
   1188     {sizeof(UDataInfo),
   1189     0,
   1190 
   1191     U_IS_BIG_ENDIAN,
   1192     U_CHARSET_FAMILY,
   1193     sizeof(UChar),
   1194     0,
   1195 
   1196     {0x31, 0x31, 0x31, 0x31},     /* dataFormat="1111" */
   1197     {0, 0, 0, 0},                 /* formatVersion */
   1198     {0, 0, 0, 0}}                 /* dataVersion */
   1199 };
   1200 #endif
   1201 
   1202 static const UChar gOffsetTOCGarbage[] = { /* "I have been very naughty!" */
   1203     0x49, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x62, 0x65, 0x65, 0x6E,
   1204     0x20, 0x76, 0x65, 0x72, 0x79, 0x20, 0x6E, 0x61, 0x75, 0x67, 0x68, 0x74, 0x79, 0x21
   1205 };
   1206 
   1207 /* Original source: icu/source/tools/genccode */
   1208 static const struct {
   1209     uint16_t headerSize;
   1210     uint8_t magic1, magic2;
   1211     UDataInfo info;
   1212     char padding[8];
   1213     uint32_t count, reserved;
   1214     const struct {
   1215         const char *const name;
   1216         const void *const data;
   1217     } toc[3];
   1218 } gOffsetTOCAppData_dat = {
   1219     32,          /* headerSize */
   1220     0xda,        /* magic1,  (see struct MappedData in udata.c)  */
   1221     0x27,        /* magic2     */
   1222     {            /*UDataInfo   */
   1223         sizeof(UDataInfo),      /* size        */
   1224         0,                      /* reserved    */
   1225         U_IS_BIG_ENDIAN,
   1226         U_CHARSET_FAMILY,
   1227         sizeof(UChar),
   1228         0,               /* reserved      */
   1229         {                /* data format identifier */
   1230            0x54, 0x6f, 0x43, 0x50}, /* "ToCP" */
   1231            {1, 0, 0, 0},   /* format version major, minor, milli, micro */
   1232            {0, 0, 0, 0}    /* dataVersion   */
   1233     },
   1234     {0,0,0,0,0,0,0,0},  /* Padding[8]   */
   1235     3,                  /* count        */
   1236     0,                  /* Reserved     */
   1237     {                   /*  TOC structure */
   1238         { "OffsetTOCAppData/a/b", &gOffsetTOCAppDataItem1 },
   1239         { "OffsetTOCAppData/gOffsetTOCAppDataItem1", &gOffsetTOCAppDataItem1 },
   1240         { "OffsetTOCAppData/gOffsetTOCGarbage", &gOffsetTOCGarbage }
   1241     }
   1242 };
   1243 
   1244 /* Unfortunately, dictionaries are in a C++ header */
   1245 U_CAPI int32_t U_EXPORT2
   1246 udict_swap(const UDataSwapper *ds, const void *inData, int32_t length, void *outData, UErrorCode *pErrorCode);
   1247 
   1248 /* test cases for maximum data swapping code coverage */
   1249 static const struct {
   1250     const char *name, *type;
   1251     UDataSwapFn *swapFn;
   1252 } swapCases[]={
   1253     /* resource bundles */
   1254 
   1255     /* resource bundle with many data types */
   1256     {"*testtypes",               "res", ures_swap},
   1257     /* resource bundle with collation data */
   1258     {"ja",                       "res", ures_swap},
   1259     /* resource bundle with options-only collation data */
   1260     {"ru",                       "res", ures_swap},
   1261     {"el",                       "res", ures_swap},
   1262     /* ICU's root */
   1263     {"root",                     "res", ures_swap},
   1264     /* Test a 32-bit key table. This is large. */
   1265     {"*testtable32",             "res", ures_swap},
   1266 
   1267     /* ICU 4.2 resource bundle - data format 1.2 (little-endian ASCII) */
   1268     {"*old_l_testtypes",         "res", ures_swap},
   1269     /* same for big-endian EBCDIC */
   1270     {"*old_e_testtypes",         "res", ures_swap},
   1271 
   1272 #if !UCONFIG_NO_COLLATION
   1273     /* standalone collation data files */
   1274     {"ucadata",                  "icu", ucol_swap},
   1275     {"invuca",                   "icu", ucol_swapInverseUCA},
   1276 #endif
   1277 
   1278 #if !UCONFIG_NO_LEGACY_CONVERSION
   1279     /* conversion table files */
   1280 
   1281     /* SBCS conversion table file without extension */
   1282     {"ibm-913_P100-2000",   "cnv", ucnv_swap},
   1283     /* EBCDIC_STATEFUL conversion table file with extension */
   1284     {"ibm-1390_P110-2003",       "cnv", ucnv_swap},
   1285     /* DBCS extension-only conversion table file */
   1286     {"ibm-16684_P110-2003",      "cnv", ucnv_swap},
   1287     /* EUC-TW (3-byte) conversion table file without extension */
   1288     {"ibm-964_P110-1999",        "cnv", ucnv_swap},
   1289     /* GB 18030 (4-byte) conversion table file without extension */
   1290     {"gb18030",                  "cnv", ucnv_swap},
   1291     /* MBCS conversion table file with extension */
   1292     {"*test4x",                  "cnv", ucnv_swap},
   1293     /*
   1294      * MBCS conversion table file without extension,
   1295      * to test swapping and preflighting of UTF-8-friendly mbcsIndex[].
   1296      */
   1297     {"jisx-212",                 "cnv", ucnv_swap},
   1298 #endif
   1299 
   1300 #if !UCONFIG_NO_CONVERSION
   1301     /* alias table */
   1302     {"cnvalias",                 "icu", ucnv_swapAliases},
   1303 #endif
   1304 
   1305 #if !UCONFIG_NO_IDNA
   1306     {"rfc3491",                    "spp", usprep_swap},
   1307 #endif
   1308 
   1309 #if !UCONFIG_NO_BREAK_ITERATION
   1310     {"char",                     "brk", ubrk_swap},
   1311     {"thaidict",                 "dict",udict_swap},
   1312 #endif
   1313 
   1314 #if 0
   1315     /*
   1316      * Starting with ICU 4.8, the Unicode property (value) aliases data
   1317      * is hardcoded in the ICU4C common library.
   1318      * The swapper was moved to the toolutil library for swapping for ICU4J.
   1319      */
   1320     /* Unicode properties */
   1321     {"pnames",                   "icu", upname_swap},
   1322 #endif
   1323 
   1324 #if 0
   1325     /*
   1326      * Starting with ICU4C 3.4, the core Unicode properties files
   1327      * (uprops.icu, ucase.icu, ubidi.icu, unorm.icu)
   1328      * are hardcoded in the common DLL and therefore not included
   1329      * in the data package any more.
   1330      * Their swapping code is moved from the common DLL to the icuswap tool so that
   1331      * we need not jump through hoops (like adding snapshots of these files
   1332      * to testdata) for code coverage in tests.
   1333      * See Jitterbug 4497.
   1334      *
   1335      * ICU4C 4.4 adds normalization data files again, e.g., nfc.nrm.
   1336      */
   1337     {"uprops",                   "icu", uprops_swap},
   1338     {"ucase",                    "icu", ucase_swap},
   1339     {"ubidi",                    "icu", ubidi_swap},
   1340 #endif
   1341 #if !UCONFIG_NO_NORMALIZATION && !UCONFIG_ONLY_COLLATION
   1342     {"nfc",                      "nrm", unorm2_swap},
   1343     {"confusables",              "cfu", uspoof_swap},
   1344 #endif
   1345     {"unames",                   "icu", uchar_swapNames}
   1346     /* the last item should not be #if'ed so that it can reliably omit the last comma */
   1347 };
   1348 
   1349 /* Large enough for the largest swappable data item. */
   1350 #define SWAP_BUFFER_SIZE 1800000
   1351 
   1352 static void U_CALLCONV
   1353 printError(void *context, const char *fmt, va_list args) {
   1354     vlog_info("[swap] ", fmt, args);
   1355     log_err("\n");  /* Register error */
   1356 }
   1357 
   1358 static void
   1359 TestSwapCase(UDataMemory *pData, const char *name,
   1360              UDataSwapFn *swapFn,
   1361              uint8_t *buffer, uint8_t *buffer2) {
   1362     UDataSwapper *ds;
   1363     const void *inData, *inHeader;
   1364     int32_t length, dataLength, length2, headerLength;
   1365 
   1366     UErrorCode errorCode;
   1367     UErrorCode badStatus;
   1368 
   1369     UBool inEndian, oppositeEndian;
   1370     uint8_t inCharset, oppositeCharset;
   1371 
   1372     /* First we check that swapFn handles failures as expected. */
   1373     errorCode = U_UNSUPPORTED_ERROR;
   1374     length = swapFn(NULL, NULL, 0, buffer, &errorCode);
   1375     if (length != 0 || errorCode != U_UNSUPPORTED_ERROR) {
   1376         log_err("%s() did not fail as expected - %s\n", name, u_errorName(errorCode));
   1377     }
   1378     errorCode = U_ZERO_ERROR;
   1379     length = swapFn(NULL, NULL, 0, buffer, &errorCode);
   1380     if (length != 0 || errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
   1381         log_err("%s() did not fail as expected with bad arguments - %s\n", name, u_errorName(errorCode));
   1382     }
   1383 
   1384 
   1385     /* Continue with the rest of the tests. */
   1386     errorCode = U_ZERO_ERROR;
   1387     inData=udata_getMemory(pData);
   1388 
   1389     /*
   1390      * get the data length if possible, to verify that swapping and preflighting
   1391      * handles the entire data
   1392      */
   1393     dataLength=udata_getLength(pData);
   1394 
   1395     /*
   1396      * get the header and its length
   1397      * all of the swap implementation functions require the header to be included
   1398      */
   1399     inHeader=udata_getRawMemory(pData);
   1400     headerLength=(int32_t)((const char *)inData-(const char *)inHeader);
   1401 
   1402     /* first swap to opposite endianness but same charset family */
   1403     errorCode=U_ZERO_ERROR;
   1404     ds=udata_openSwapperForInputData(inHeader, headerLength,
   1405             !U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode);
   1406     if(U_FAILURE(errorCode)) {
   1407         log_err("udata_openSwapperForInputData(%s->!isBig+same charset) failed - %s\n",
   1408                 name, u_errorName(errorCode));
   1409         return;
   1410     }
   1411 
   1412     inEndian=ds->inIsBigEndian;
   1413     inCharset=ds->inCharset;
   1414 
   1415     oppositeEndian=!inEndian;
   1416     oppositeCharset= inCharset==U_ASCII_FAMILY ? U_EBCDIC_FAMILY : U_ASCII_FAMILY;
   1417 
   1418     /* make this test work with data files that are built for a different platform */
   1419     if(inEndian!=U_IS_BIG_ENDIAN || inCharset!=U_CHARSET_FAMILY) {
   1420         udata_closeSwapper(ds);
   1421         ds=udata_openSwapper(inEndian, inCharset, oppositeEndian, inCharset, &errorCode);
   1422         if(U_FAILURE(errorCode)) {
   1423             log_err("udata_openSwapper(%s->!isBig+same charset) failed - %s\n",
   1424                     name, u_errorName(errorCode));
   1425             return;
   1426         }
   1427     }
   1428 
   1429     /*
   1430     Check error checking of swappable data not specific to this swapper.
   1431     This should always fail.
   1432     */
   1433     badStatus = U_ZERO_ERROR;
   1434     length=swapFn(ds, &gOffsetTOCAppData_dat, -1, NULL, &badStatus);
   1435     if(badStatus != U_UNSUPPORTED_ERROR) {
   1436         log_err("swapFn(%s->!isBig+same charset) unexpectedly succeeded on bad data - %s\n",
   1437                 name, u_errorName(errorCode));
   1438         udata_closeSwapper(ds);
   1439         return;
   1440     }
   1441 
   1442     /* Now allow errors to be printed */
   1443     ds->printError=printError;
   1444 
   1445     /* preflight the length */
   1446     length=swapFn(ds, inHeader, -1, NULL, &errorCode);
   1447     if(U_FAILURE(errorCode)) {
   1448         log_err("swapFn(preflight %s->!isBig+same charset) failed - %s\n",
   1449                 name, u_errorName(errorCode));
   1450         udata_closeSwapper(ds);
   1451         return;
   1452     }
   1453 
   1454     /* compare the preflighted length against the data length */
   1455     if(dataLength>=0 && (length+15)<(headerLength+dataLength)) {
   1456         log_err("swapFn(preflight %s->!isBig+same charset) length too small: %d < data length %d\n",
   1457                 name, length, (headerLength+dataLength));
   1458         udata_closeSwapper(ds);
   1459         return;
   1460     }
   1461 
   1462     /* swap, not in-place */
   1463     length2=swapFn(ds, inHeader, length, buffer, &errorCode);
   1464     udata_closeSwapper(ds);
   1465     if(U_FAILURE(errorCode)) {
   1466         log_err("swapFn(%s->!isBig+same charset) failed - %s\n",
   1467                 name, u_errorName(errorCode));
   1468         return;
   1469     }
   1470 
   1471     /* compare the swap length against the preflighted length */
   1472     if(length2!=length) {
   1473         log_err("swapFn(%s->!isBig+same charset) length differs from preflighting: %d != preflighted %d\n",
   1474                 name, length2, length);
   1475         return;
   1476     }
   1477 
   1478     /* next swap to opposite charset family */
   1479     ds=udata_openSwapper(oppositeEndian, inCharset,
   1480                          oppositeEndian, oppositeCharset,
   1481                          &errorCode);
   1482     if(U_FAILURE(errorCode)) {
   1483         log_err("udata_openSwapper(%s->!isBig+other charset) failed - %s\n",
   1484                 name, u_errorName(errorCode));
   1485         return;
   1486     }
   1487     ds->printError=printError;
   1488 
   1489     /* swap in-place */
   1490     length2=swapFn(ds, buffer, length, buffer, &errorCode);
   1491     udata_closeSwapper(ds);
   1492     if(U_FAILURE(errorCode)) {
   1493         log_err("swapFn(%s->!isBig+other charset) failed - %s\n",
   1494                 name, u_errorName(errorCode));
   1495         return;
   1496     }
   1497 
   1498     /* compare the swap length against the original length */
   1499     if(length2!=length) {
   1500         log_err("swapFn(%s->!isBig+other charset) length differs from original: %d != original %d\n",
   1501                 name, length2, length);
   1502         return;
   1503     }
   1504 
   1505     /* finally swap to original platform values */
   1506     ds=udata_openSwapper(oppositeEndian, oppositeCharset,
   1507                          inEndian, inCharset,
   1508                          &errorCode);
   1509     if(U_FAILURE(errorCode)) {
   1510         log_err("udata_openSwapper(%s->back to original) failed - %s\n",
   1511                 name, u_errorName(errorCode));
   1512         return;
   1513     }
   1514     ds->printError=printError;
   1515 
   1516     /* swap, not in-place */
   1517     length2=swapFn(ds, buffer, length, buffer2, &errorCode);
   1518     udata_closeSwapper(ds);
   1519     if(U_FAILURE(errorCode)) {
   1520         log_err("swapFn(%s->back to original) failed - %s\n",
   1521                 name, u_errorName(errorCode));
   1522         return;
   1523     }
   1524 
   1525     /* compare the swap length against the original length */
   1526     if(length2!=length) {
   1527         log_err("swapFn(%s->back to original) length differs from original: %d != original %d\n",
   1528                 name, length2, length);
   1529         return;
   1530     }
   1531 
   1532     /* compare the final contents with the original */
   1533     if(0!=uprv_memcmp(inHeader, buffer2, length)) {
   1534         const uint8_t *original;
   1535         uint8_t diff[8];
   1536         int32_t i, j;
   1537 
   1538         log_err("swapFn(%s->back to original) contents differs from original\n",
   1539                 name);
   1540 
   1541         /* find the first difference */
   1542         original=(const uint8_t *)inHeader;
   1543         for(i=0; i<length && original[i]==buffer2[i]; ++i) {}
   1544 
   1545         /* find the next byte that is the same */
   1546         for(j=i+1; j<length && original[j]!=buffer2[j]; ++j) {}
   1547         log_info("    difference at index %d=0x%x, until index %d=0x%x\n", i, i, j, j);
   1548 
   1549         /* round down to the last 4-boundary for better result output */
   1550         i&=~3;
   1551         log_info("showing bytes from index %d=0x%x (length %d=0x%x):\n", i, i, length, length);
   1552 
   1553         /* print 8 bytes but limit to the buffer contents */
   1554         length2=i+sizeof(diff);
   1555         if(length2>length) {
   1556             length2=length;
   1557         }
   1558 
   1559         /* print the original bytes */
   1560         uprv_memset(diff, 0, sizeof(diff));
   1561         for(j=i; j<length2; ++j) {
   1562             diff[j-i]=original[j];
   1563         }
   1564         log_info("    original: %02x %02x %02x %02x %02x %02x %02x %02x\n",
   1565             diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]);
   1566 
   1567         /* print the swapped bytes */
   1568         uprv_memset(diff, 0, sizeof(diff));
   1569         for(j=i; j<length2; ++j) {
   1570             diff[j-i]=buffer2[j];
   1571         }
   1572         log_info("    swapped:  %02x %02x %02x %02x %02x %02x %02x %02x\n",
   1573             diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]);
   1574     }
   1575 }
   1576 
   1577 static void U_CALLCONV
   1578 printErrorToString(void *context, const char *fmt, va_list args) {
   1579     vsprintf((char *)context, fmt, args);
   1580 }
   1581 
   1582 #if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
   1583 static void
   1584 TestSwapData() {
   1585     char name[100];
   1586     UDataSwapper *ds;
   1587     UDataMemory *pData;
   1588     uint8_t *buffer;
   1589     const char *pkg, *nm, *testPath;
   1590     UErrorCode errorCode = U_ZERO_ERROR;
   1591     int32_t i;
   1592 
   1593     buffer=(uint8_t *)malloc(2*SWAP_BUFFER_SIZE);
   1594     if(buffer==NULL) {
   1595         log_err("unable to allocate %d bytes\n", 2*SWAP_BUFFER_SIZE);
   1596         return;
   1597     }
   1598 
   1599     testPath=loadTestData(&errorCode);
   1600     if(U_FAILURE(errorCode)) {
   1601         log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(errorCode));
   1602     }
   1603 
   1604     /* Test that printError works as expected. */
   1605     errorCode=U_USELESS_COLLATOR_ERROR;
   1606     ds=udata_openSwapper(U_IS_BIG_ENDIAN, U_ASCII_FAMILY,
   1607                          !U_IS_BIG_ENDIAN, U_ASCII_FAMILY,
   1608                          &errorCode);
   1609     if (ds != NULL || errorCode != U_USELESS_COLLATOR_ERROR) {
   1610         log_err("udata_openSwapper should have returned NULL with bad argument\n", name);
   1611     }
   1612     errorCode=U_ZERO_ERROR;
   1613     ds=udata_openSwapper(U_IS_BIG_ENDIAN, U_ASCII_FAMILY,
   1614                          !U_IS_BIG_ENDIAN, U_ASCII_FAMILY,
   1615                          &errorCode);
   1616     ds->printError=printErrorToString;
   1617     ds->printErrorContext=name;
   1618     udata_printError(ds, "This %s a %s", "is", "test");
   1619     udata_closeSwapper(ds);
   1620     if (strcmp(name, "This is a test") != 0) {
   1621         log_err("udata_printError can't properly print error messages. Got = %s\n", name);
   1622     }
   1623     errorCode = U_USELESS_COLLATOR_ERROR;
   1624     ds=udata_openSwapperForInputData(NULL, 0,
   1625                          !U_IS_BIG_ENDIAN, U_ASCII_FAMILY,
   1626                          &errorCode);
   1627     if (ds != NULL || errorCode != U_USELESS_COLLATOR_ERROR) {
   1628         log_err("udata_openSwapperForInputData should have returned NULL with bad argument\n", name);
   1629     }
   1630     errorCode=U_ZERO_ERROR;
   1631     ds=udata_openSwapperForInputData(NULL, 0,
   1632                          !U_IS_BIG_ENDIAN, U_ASCII_FAMILY,
   1633                          &errorCode);
   1634     if (ds != NULL || errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
   1635         log_err("udata_openSwapperForInputData should have returned NULL with bad argument\n", name);
   1636     }
   1637     errorCode=U_ZERO_ERROR;
   1638     memset(buffer, 0, sizeof(2*SWAP_BUFFER_SIZE));
   1639     ds=udata_openSwapperForInputData(buffer, 2*SWAP_BUFFER_SIZE,
   1640                          !U_IS_BIG_ENDIAN, U_ASCII_FAMILY,
   1641                          &errorCode);
   1642     if (ds != NULL || errorCode != U_UNSUPPORTED_ERROR) {
   1643         log_err("udata_openSwapperForInputData should have returned NULL with bad argument\n", name);
   1644     }
   1645     errorCode=U_ZERO_ERROR;
   1646 
   1647     /* Test argument checking. ucol_swapBinary is normally tested via ures_swap, and isn't normally called directly. */
   1648 #if !UCONFIG_NO_COLLATION
   1649     ucol_swapBinary(NULL, NULL, -1, NULL, NULL);
   1650     ucol_swapBinary(NULL, NULL, -1, NULL, &errorCode);
   1651     if (errorCode != U_ILLEGAL_ARGUMENT_ERROR) {
   1652         log_err("ucol_swapBinary did not fail as expected\n", name);
   1653     }
   1654     errorCode=U_ZERO_ERROR;
   1655 #endif
   1656 
   1657     for(i=0; i<LENGTHOF(swapCases); ++i) {
   1658         /* build the name for logging */
   1659         errorCode=U_ZERO_ERROR;
   1660         if(swapCases[i].name[0]=='*') {
   1661             pkg=testPath;
   1662             nm=swapCases[i].name+1;
   1663             uprv_strcpy(name, "testdata");
   1664         } else if (uprv_strcmp(swapCases[i].type, "brk")==0
   1665             || uprv_strcmp(swapCases[i].type, "dict")==0) {
   1666             pkg=U_ICUDATA_BRKITR;
   1667             nm=swapCases[i].name;
   1668             uprv_strcpy(name, U_ICUDATA_BRKITR);
   1669         } else if (uprv_strcmp(swapCases[i].name, "ucadata")==0
   1670             || uprv_strcmp(swapCases[i].name, "invuca")==0) {
   1671             pkg=U_ICUDATA_COLL;
   1672             nm=swapCases[i].name;
   1673             uprv_strcpy(name, U_ICUDATA_COLL);
   1674         } else {
   1675             pkg=NULL;
   1676             nm=swapCases[i].name;
   1677             uprv_strcpy(name, "NULL");
   1678         }
   1679         uprv_strcat(name, "/");
   1680         uprv_strcat(name, nm);
   1681         uprv_strcat(name, ".");
   1682         uprv_strcat(name, swapCases[i].type);
   1683 
   1684         pData=udata_open(pkg, swapCases[i].type, nm, &errorCode);
   1685 
   1686         if(U_SUCCESS(errorCode)) {
   1687             TestSwapCase(pData, name, swapCases[i].swapFn, buffer, buffer+SWAP_BUFFER_SIZE);
   1688             udata_close(pData);
   1689         } else {
   1690             log_data_err("udata_open(%s) failed - %s\n",
   1691                 name, u_errorName(errorCode));
   1692         }
   1693     }
   1694 
   1695     free(buffer);
   1696 }
   1697 #endif
   1698 
   1699 static void PointerTableOfContents() {
   1700     UDataMemory      *dataItem;
   1701     UErrorCode        status=U_ZERO_ERROR;
   1702 
   1703     /*
   1704      * Got testdata.dat into memory, now we try setAppData using the memory image.
   1705      */
   1706 
   1707     status=U_ZERO_ERROR;
   1708     udata_setAppData("OffsetTOCAppData", &gOffsetTOCAppData_dat, &status);
   1709     if (status != U_ZERO_ERROR) {
   1710         log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData1\", fileBuf, status) \n"
   1711                 " returned status of %s\n", u_errorName(status));
   1712         return;
   1713     }
   1714 
   1715     dataItem = udata_open("OffsetTOCAppData", "", "gOffsetTOCAppDataItem1", &status);
   1716     if (U_FAILURE(status)) {
   1717         log_err("FAIL: gOffsetTOCAppDataItem1 could not be opened. status = %s\n", u_errorName(status));
   1718     }
   1719     if (udata_getMemory(dataItem) != NULL) {
   1720         log_verbose("FAIL: udata_getMemory(dataItem) passed\n");
   1721     }
   1722     else {
   1723         log_err("FAIL: udata_getMemory returned NULL\n", u_errorName(status));
   1724     }
   1725     udata_close(dataItem);
   1726 
   1727     dataItem = udata_open("OffsetTOCAppData-a", "", "b", &status);
   1728     if (U_FAILURE(status)) {
   1729         log_err("FAIL: gOffsetTOCAppDataItem1 in tree \"a\" could not be opened. status = %s\n", u_errorName(status));
   1730     }
   1731     if (udata_getMemory(dataItem) != NULL) {
   1732         log_verbose("FAIL: udata_getMemory(dataItem) in tree \"a\" passed\n");
   1733     }
   1734     else {
   1735         log_err("FAIL: udata_getMemory returned NULL\n", u_errorName(status));
   1736     }
   1737     udata_close(dataItem);
   1738 
   1739     dataItem = udata_open("OffsetTOCAppData", "", "gOffsetTOCGarbage", &status);
   1740     if (U_SUCCESS(status)) {
   1741         log_err("FAIL: gOffsetTOCGarbage should not be opened. status = %s\n", u_errorName(status));
   1742     }
   1743     dataItem = udata_open("OffsetTOCAppData", "", "gOffsetTOCNonExistent", &status);
   1744     if (U_SUCCESS(status)) {
   1745         log_err("FAIL: gOffsetTOCNonExistent should not be found. status = %s\n", u_errorName(status));
   1746     }
   1747 
   1748 }
   1749 
   1750 static void SetBadCommonData(void) {
   1751     /* It's difficult to test that udata_setCommonData really works within the test framework.
   1752        So we just test that foolish people can't do bad things. */
   1753     UErrorCode status;
   1754     char badBuffer[sizeof(gOffsetTOCAppData_dat)];
   1755 
   1756     memset(badBuffer, 0, sizeof(badBuffer));
   1757     strcpy(badBuffer, "Hello! I'm not good data.");
   1758 
   1759     /* Check that we don't do anything */
   1760     status = U_FILE_ACCESS_ERROR;
   1761     udata_setCommonData(&gOffsetTOCAppData_dat, &status);
   1762     if (status != U_FILE_ACCESS_ERROR) {
   1763         log_err("FAIL: udata_setCommonData changed the failure code.\n");
   1764     }
   1765     /* Check that we fail correctly */
   1766     status = U_ZERO_ERROR;
   1767     udata_setCommonData(NULL, &status);
   1768     if (status != U_ILLEGAL_ARGUMENT_ERROR) {
   1769         log_err("FAIL: udata_setCommonData did not fail with bad arguments.\n");
   1770     }
   1771 
   1772     /* Check that we verify that the data isn't bad */
   1773     status = U_ZERO_ERROR;
   1774     udata_setAppData("invalid path", badBuffer, &status);
   1775     if (status != U_INVALID_FORMAT_ERROR) {
   1776         log_err("FAIL: udata_setAppData doesn't verify data validity.\n");
   1777     }
   1778 }
   1779 
   1780