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