• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
addUDataTest(TestNode ** root)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
TestUDataOpen()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 
TestUDataSetAppData()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 
safeGetICUDataDirectory()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 
TestUDataFileAccess()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
isAcceptable1(void * context,const char * type,const char * name,const UDataInfo * pInfo)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
isAcceptable2(void * context,const char * type,const char * name,const UDataInfo * pInfo)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
isAcceptable3(void * context,const char * type,const char * name,const UDataInfo * pInfo)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
TestUDataOpenChoiceDemo1()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
isAcceptable(void * context,const char * type,const char * name,const UDataInfo * pInfo)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 
TestUDataOpenChoiceDemo2()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 
TestUDataGetInfo()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 
TestUDataGetMemory()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 
TestErrorConditions()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 */
TestAppData()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 
TestICUDataName()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
printError(void * context,const char * fmt,va_list args)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
TestSwapCase(UDataMemory * pData,const char * name,UDataSwapFn * swapFn,uint8_t * buffer,uint8_t * buffer2)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
printErrorToString(void * context,const char * fmt,va_list args)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
TestSwapData()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 
PointerTableOfContents()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 
SetBadCommonData(void)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