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