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