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