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