1/******************************************************************** 2 * COPYRIGHT: 3 * Copyright (c) 1998-2013, 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#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 {"invuca", "icu", ucol_swapInverseUCA}, 1308#endif 1309 1310#if !UCONFIG_NO_LEGACY_CONVERSION 1311 /* conversion table files */ 1312 1313 /* SBCS conversion table file without extension */ 1314 {"ibm-913_P100-2000", "cnv", ucnv_swap}, 1315 /* EBCDIC_STATEFUL conversion table file with extension */ 1316 {"ibm-1390_P110-2003", "cnv", ucnv_swap}, 1317 /* DBCS extension-only conversion table file */ 1318 {"ibm-16684_P110-2003", "cnv", ucnv_swap}, 1319 /* EUC-TW (3-byte) conversion table file without extension */ 1320 {"ibm-964_P110-1999", "cnv", ucnv_swap}, 1321 /* GB 18030 (4-byte) conversion table file without extension */ 1322 {"gb18030", "cnv", ucnv_swap}, 1323 /* MBCS conversion table file with extension */ 1324 {"*test4x", "cnv", ucnv_swap}, 1325 /* 1326 * MBCS conversion table file without extension, 1327 * to test swapping and preflighting of UTF-8-friendly mbcsIndex[]. 1328 */ 1329 {"jisx-212", "cnv", ucnv_swap}, 1330#endif 1331 1332#if !UCONFIG_NO_CONVERSION 1333 /* alias table */ 1334 {"cnvalias", "icu", ucnv_swapAliases}, 1335#endif 1336 1337#if !UCONFIG_NO_IDNA 1338 {"rfc3491", "spp", usprep_swap}, 1339#endif 1340 1341#if !UCONFIG_NO_BREAK_ITERATION 1342 {"char", "brk", ubrk_swap}, 1343 {"thaidict", "dict",udict_swap}, 1344#endif 1345 1346#if 0 1347 /* 1348 * Starting with ICU 4.8, the Unicode property (value) aliases data 1349 * is hardcoded in the ICU4C common library. 1350 * The swapper was moved to the toolutil library for swapping for ICU4J. 1351 */ 1352 /* Unicode properties */ 1353 {"pnames", "icu", upname_swap}, 1354#endif 1355 1356#if 0 1357 /* 1358 * Starting with ICU4C 3.4, the core Unicode properties files 1359 * (uprops.icu, ucase.icu, ubidi.icu, unorm.icu) 1360 * are hardcoded in the common DLL and therefore not included 1361 * in the data package any more. 1362 * Their swapping code is moved from the common DLL to the icuswap tool so that 1363 * we need not jump through hoops (like adding snapshots of these files 1364 * to testdata) for code coverage in tests. 1365 * See Jitterbug 4497. 1366 * 1367 * ICU4C 4.4 adds normalization data files again, e.g., nfc.nrm. 1368 */ 1369 {"uprops", "icu", uprops_swap}, 1370 {"ucase", "icu", ucase_swap}, 1371 {"ubidi", "icu", ubidi_swap}, 1372#endif 1373#if !UCONFIG_NO_NORMALIZATION && !UCONFIG_ONLY_COLLATION 1374 {"nfc", "nrm", unorm2_swap}, 1375 {"confusables", "cfu", uspoof_swap}, 1376#endif 1377 {"unames", "icu", uchar_swapNames} 1378 /* the last item should not be #if'ed so that it can reliably omit the last comma */ 1379}; 1380 1381/* Large enough for the largest swappable data item. */ 1382#define SWAP_BUFFER_SIZE 1800000 1383 1384static void U_CALLCONV 1385printError(void *context, const char *fmt, va_list args) { 1386 vlog_info("[swap] ", fmt, args); 1387 log_err("\n"); /* Register error */ 1388} 1389 1390static void 1391TestSwapCase(UDataMemory *pData, const char *name, 1392 UDataSwapFn *swapFn, 1393 uint8_t *buffer, uint8_t *buffer2) { 1394 UDataSwapper *ds; 1395 const void *inData, *inHeader; 1396 int32_t length, dataLength, length2, headerLength; 1397 1398 UErrorCode errorCode; 1399 UErrorCode badStatus; 1400 1401 UBool inEndian, oppositeEndian; 1402 uint8_t inCharset, oppositeCharset; 1403 1404 /* First we check that swapFn handles failures as expected. */ 1405 errorCode = U_UNSUPPORTED_ERROR; 1406 length = swapFn(NULL, NULL, 0, buffer, &errorCode); 1407 if (length != 0 || errorCode != U_UNSUPPORTED_ERROR) { 1408 log_err("%s() did not fail as expected - %s\n", name, u_errorName(errorCode)); 1409 } 1410 errorCode = U_ZERO_ERROR; 1411 length = swapFn(NULL, NULL, 0, buffer, &errorCode); 1412 if (length != 0 || errorCode != U_ILLEGAL_ARGUMENT_ERROR) { 1413 log_err("%s() did not fail as expected with bad arguments - %s\n", name, u_errorName(errorCode)); 1414 } 1415 1416 1417 /* Continue with the rest of the tests. */ 1418 errorCode = U_ZERO_ERROR; 1419 inData=udata_getMemory(pData); 1420 1421 /* 1422 * get the data length if possible, to verify that swapping and preflighting 1423 * handles the entire data 1424 */ 1425 dataLength=udata_getLength(pData); 1426 1427 /* 1428 * get the header and its length 1429 * all of the swap implementation functions require the header to be included 1430 */ 1431 inHeader=udata_getRawMemory(pData); 1432 headerLength=(int32_t)((const char *)inData-(const char *)inHeader); 1433 1434 /* first swap to opposite endianness but same charset family */ 1435 errorCode=U_ZERO_ERROR; 1436 ds=udata_openSwapperForInputData(inHeader, headerLength, 1437 !U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode); 1438 if(U_FAILURE(errorCode)) { 1439 log_err("udata_openSwapperForInputData(%s->!isBig+same charset) failed - %s\n", 1440 name, u_errorName(errorCode)); 1441 return; 1442 } 1443 1444 inEndian=ds->inIsBigEndian; 1445 inCharset=ds->inCharset; 1446 1447 oppositeEndian=!inEndian; 1448 oppositeCharset= inCharset==U_ASCII_FAMILY ? U_EBCDIC_FAMILY : U_ASCII_FAMILY; 1449 1450 /* make this test work with data files that are built for a different platform */ 1451 if(inEndian!=U_IS_BIG_ENDIAN || inCharset!=U_CHARSET_FAMILY) { 1452 udata_closeSwapper(ds); 1453 ds=udata_openSwapper(inEndian, inCharset, oppositeEndian, inCharset, &errorCode); 1454 if(U_FAILURE(errorCode)) { 1455 log_err("udata_openSwapper(%s->!isBig+same charset) failed - %s\n", 1456 name, u_errorName(errorCode)); 1457 return; 1458 } 1459 } 1460 1461 /* 1462 Check error checking of swappable data not specific to this swapper. 1463 This should always fail. 1464 */ 1465 badStatus = U_ZERO_ERROR; 1466 length=swapFn(ds, &gOffsetTOCAppData_dat, -1, NULL, &badStatus); 1467 if(badStatus != U_UNSUPPORTED_ERROR) { 1468 log_err("swapFn(%s->!isBig+same charset) unexpectedly succeeded on bad data - %s\n", 1469 name, u_errorName(errorCode)); 1470 udata_closeSwapper(ds); 1471 return; 1472 } 1473 1474 /* Now allow errors to be printed */ 1475 ds->printError=printError; 1476 1477 /* preflight the length */ 1478 length=swapFn(ds, inHeader, -1, NULL, &errorCode); 1479 if(U_FAILURE(errorCode)) { 1480 log_err("swapFn(preflight %s->!isBig+same charset) failed - %s\n", 1481 name, u_errorName(errorCode)); 1482 udata_closeSwapper(ds); 1483 return; 1484 } 1485 1486 /* compare the preflighted length against the data length */ 1487 if(dataLength>=0 && (length+15)<(headerLength+dataLength)) { 1488 log_err("swapFn(preflight %s->!isBig+same charset) length too small: %d < data length %d\n", 1489 name, length, (headerLength+dataLength)); 1490 udata_closeSwapper(ds); 1491 return; 1492 } 1493 1494 /* swap, not in-place */ 1495 length2=swapFn(ds, inHeader, length, buffer, &errorCode); 1496 udata_closeSwapper(ds); 1497 if(U_FAILURE(errorCode)) { 1498 log_err("swapFn(%s->!isBig+same charset) failed - %s\n", 1499 name, u_errorName(errorCode)); 1500 return; 1501 } 1502 1503 /* compare the swap length against the preflighted length */ 1504 if(length2!=length) { 1505 log_err("swapFn(%s->!isBig+same charset) length differs from preflighting: %d != preflighted %d\n", 1506 name, length2, length); 1507 return; 1508 } 1509 1510 /* next swap to opposite charset family */ 1511 ds=udata_openSwapper(oppositeEndian, inCharset, 1512 oppositeEndian, oppositeCharset, 1513 &errorCode); 1514 if(U_FAILURE(errorCode)) { 1515 log_err("udata_openSwapper(%s->!isBig+other charset) failed - %s\n", 1516 name, u_errorName(errorCode)); 1517 return; 1518 } 1519 ds->printError=printError; 1520 1521 /* swap in-place */ 1522 length2=swapFn(ds, buffer, length, buffer, &errorCode); 1523 udata_closeSwapper(ds); 1524 if(U_FAILURE(errorCode)) { 1525 log_err("swapFn(%s->!isBig+other charset) failed - %s\n", 1526 name, u_errorName(errorCode)); 1527 return; 1528 } 1529 1530 /* compare the swap length against the original length */ 1531 if(length2!=length) { 1532 log_err("swapFn(%s->!isBig+other charset) length differs from original: %d != original %d\n", 1533 name, length2, length); 1534 return; 1535 } 1536 1537 /* finally swap to original platform values */ 1538 ds=udata_openSwapper(oppositeEndian, oppositeCharset, 1539 inEndian, inCharset, 1540 &errorCode); 1541 if(U_FAILURE(errorCode)) { 1542 log_err("udata_openSwapper(%s->back to original) failed - %s\n", 1543 name, u_errorName(errorCode)); 1544 return; 1545 } 1546 ds->printError=printError; 1547 1548 /* swap, not in-place */ 1549 length2=swapFn(ds, buffer, length, buffer2, &errorCode); 1550 udata_closeSwapper(ds); 1551 if(U_FAILURE(errorCode)) { 1552 log_err("swapFn(%s->back to original) failed - %s\n", 1553 name, u_errorName(errorCode)); 1554 return; 1555 } 1556 1557 /* compare the swap length against the original length */ 1558 if(length2!=length) { 1559 log_err("swapFn(%s->back to original) length differs from original: %d != original %d\n", 1560 name, length2, length); 1561 return; 1562 } 1563 1564 /* compare the final contents with the original */ 1565 if(0!=uprv_memcmp(inHeader, buffer2, length)) { 1566 const uint8_t *original; 1567 uint8_t diff[8]; 1568 int32_t i, j; 1569 1570 log_err("swapFn(%s->back to original) contents differs from original\n", 1571 name); 1572 1573 /* find the first difference */ 1574 original=(const uint8_t *)inHeader; 1575 for(i=0; i<length && original[i]==buffer2[i]; ++i) {} 1576 1577 /* find the next byte that is the same */ 1578 for(j=i+1; j<length && original[j]!=buffer2[j]; ++j) {} 1579 log_info(" difference at index %d=0x%x, until index %d=0x%x\n", i, i, j, j); 1580 1581 /* round down to the last 4-boundary for better result output */ 1582 i&=~3; 1583 log_info("showing bytes from index %d=0x%x (length %d=0x%x):\n", i, i, length, length); 1584 1585 /* print 8 bytes but limit to the buffer contents */ 1586 length2=i+sizeof(diff); 1587 if(length2>length) { 1588 length2=length; 1589 } 1590 1591 /* print the original bytes */ 1592 uprv_memset(diff, 0, sizeof(diff)); 1593 for(j=i; j<length2; ++j) { 1594 diff[j-i]=original[j]; 1595 } 1596 log_info(" original: %02x %02x %02x %02x %02x %02x %02x %02x\n", 1597 diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]); 1598 1599 /* print the swapped bytes */ 1600 uprv_memset(diff, 0, sizeof(diff)); 1601 for(j=i; j<length2; ++j) { 1602 diff[j-i]=buffer2[j]; 1603 } 1604 log_info(" swapped: %02x %02x %02x %02x %02x %02x %02x %02x\n", 1605 diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]); 1606 } 1607} 1608 1609static void U_CALLCONV 1610printErrorToString(void *context, const char *fmt, va_list args) { 1611 vsprintf((char *)context, fmt, args); 1612} 1613 1614#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION 1615static void 1616TestSwapData() { 1617 char name[100]; 1618 UDataSwapper *ds; 1619 UDataMemory *pData; 1620 uint8_t *buffer; 1621 const char *pkg, *nm, *testPath; 1622 UErrorCode errorCode = U_ZERO_ERROR; 1623 int32_t i; 1624 1625 buffer=(uint8_t *)malloc(2*SWAP_BUFFER_SIZE); 1626 if(buffer==NULL) { 1627 log_err("unable to allocate %d bytes\n", 2*SWAP_BUFFER_SIZE); 1628 return; 1629 } 1630 1631 testPath=loadTestData(&errorCode); 1632 if(U_FAILURE(errorCode)) { 1633 log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(errorCode)); 1634 } 1635 1636 /* Test that printError works as expected. */ 1637 errorCode=U_USELESS_COLLATOR_ERROR; 1638 ds=udata_openSwapper(U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1639 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1640 &errorCode); 1641 if (ds != NULL || errorCode != U_USELESS_COLLATOR_ERROR) { 1642 log_err("udata_openSwapper should have returned NULL with bad argument\n", name); 1643 } 1644 errorCode=U_ZERO_ERROR; 1645 ds=udata_openSwapper(U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1646 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1647 &errorCode); 1648 ds->printError=printErrorToString; 1649 ds->printErrorContext=name; 1650 udata_printError(ds, "This %s a %s", "is", "test"); 1651 udata_closeSwapper(ds); 1652 if (strcmp(name, "This is a test") != 0) { 1653 log_err("udata_printError can't properly print error messages. Got = %s\n", name); 1654 } 1655 errorCode = U_USELESS_COLLATOR_ERROR; 1656 ds=udata_openSwapperForInputData(NULL, 0, 1657 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1658 &errorCode); 1659 if (ds != NULL || errorCode != U_USELESS_COLLATOR_ERROR) { 1660 log_err("udata_openSwapperForInputData should have returned NULL with bad argument\n", name); 1661 } 1662 errorCode=U_ZERO_ERROR; 1663 ds=udata_openSwapperForInputData(NULL, 0, 1664 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1665 &errorCode); 1666 if (ds != NULL || errorCode != U_ILLEGAL_ARGUMENT_ERROR) { 1667 log_err("udata_openSwapperForInputData should have returned NULL with bad argument\n", name); 1668 } 1669 errorCode=U_ZERO_ERROR; 1670 memset(buffer, 0, sizeof(2*SWAP_BUFFER_SIZE)); 1671 ds=udata_openSwapperForInputData(buffer, 2*SWAP_BUFFER_SIZE, 1672 !U_IS_BIG_ENDIAN, U_ASCII_FAMILY, 1673 &errorCode); 1674 if (ds != NULL || errorCode != U_UNSUPPORTED_ERROR) { 1675 log_err("udata_openSwapperForInputData should have returned NULL with bad argument\n", name); 1676 } 1677 errorCode=U_ZERO_ERROR; 1678 1679 /* Test argument checking. ucol_swapBinary is normally tested via ures_swap, and isn't normally called directly. */ 1680#if !UCONFIG_NO_COLLATION 1681 ucol_swapBinary(NULL, NULL, -1, NULL, NULL); 1682 ucol_swapBinary(NULL, NULL, -1, NULL, &errorCode); 1683 if (errorCode != U_ILLEGAL_ARGUMENT_ERROR) { 1684 log_err("ucol_swapBinary did not fail as expected\n", name); 1685 } 1686 errorCode=U_ZERO_ERROR; 1687#endif 1688 1689 for(i=0; i<LENGTHOF(swapCases); ++i) { 1690 /* build the name for logging */ 1691 errorCode=U_ZERO_ERROR; 1692 if(swapCases[i].name[0]=='*') { 1693 pkg=testPath; 1694 nm=swapCases[i].name+1; 1695 uprv_strcpy(name, "testdata"); 1696 } else if (uprv_strcmp(swapCases[i].type, "brk")==0 1697 || uprv_strcmp(swapCases[i].type, "dict")==0) { 1698 pkg=U_ICUDATA_BRKITR; 1699 nm=swapCases[i].name; 1700 uprv_strcpy(name, U_ICUDATA_BRKITR); 1701 } else if (uprv_strcmp(swapCases[i].name, "ucadata")==0 1702 || uprv_strcmp(swapCases[i].name, "invuca")==0) { 1703 pkg=U_ICUDATA_COLL; 1704 nm=swapCases[i].name; 1705 uprv_strcpy(name, U_ICUDATA_COLL); 1706 } else { 1707 pkg=NULL; 1708 nm=swapCases[i].name; 1709 uprv_strcpy(name, "NULL"); 1710 } 1711 uprv_strcat(name, "/"); 1712 uprv_strcat(name, nm); 1713 uprv_strcat(name, "."); 1714 uprv_strcat(name, swapCases[i].type); 1715 1716 pData=udata_open(pkg, swapCases[i].type, nm, &errorCode); 1717 1718 if(U_SUCCESS(errorCode)) { 1719 TestSwapCase(pData, name, swapCases[i].swapFn, buffer, buffer+SWAP_BUFFER_SIZE); 1720 udata_close(pData); 1721 } else { 1722 log_data_err("udata_open(%s) failed - %s\n", 1723 name, u_errorName(errorCode)); 1724 } 1725 } 1726 1727 free(buffer); 1728} 1729#endif 1730 1731static void PointerTableOfContents() { 1732 UDataMemory *dataItem; 1733 UErrorCode status=U_ZERO_ERROR; 1734 1735 /* 1736 * Got testdata.dat into memory, now we try setAppData using the memory image. 1737 */ 1738 1739 status=U_ZERO_ERROR; 1740 udata_setAppData("OffsetTOCAppData", &gOffsetTOCAppData_dat, &status); 1741 if (status != U_ZERO_ERROR) { 1742 log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData1\", fileBuf, status) \n" 1743 " returned status of %s\n", u_errorName(status)); 1744 return; 1745 } 1746 1747 dataItem = udata_open("OffsetTOCAppData", "", "gOffsetTOCAppDataItem1", &status); 1748 if (U_FAILURE(status)) { 1749 log_err("FAIL: gOffsetTOCAppDataItem1 could not be opened. status = %s\n", u_errorName(status)); 1750 } 1751 if (udata_getMemory(dataItem) != NULL) { 1752 log_verbose("FAIL: udata_getMemory(dataItem) passed\n"); 1753 } 1754 else { 1755 log_err("FAIL: udata_getMemory returned NULL\n", u_errorName(status)); 1756 } 1757 udata_close(dataItem); 1758 1759 dataItem = udata_open("OffsetTOCAppData-a", "", "b", &status); 1760 if (U_FAILURE(status)) { 1761 log_err("FAIL: gOffsetTOCAppDataItem1 in tree \"a\" could not be opened. status = %s\n", u_errorName(status)); 1762 } 1763 if (udata_getMemory(dataItem) != NULL) { 1764 log_verbose("FAIL: udata_getMemory(dataItem) in tree \"a\" passed\n"); 1765 } 1766 else { 1767 log_err("FAIL: udata_getMemory returned NULL\n", u_errorName(status)); 1768 } 1769 udata_close(dataItem); 1770 1771 dataItem = udata_open("OffsetTOCAppData", "", "gOffsetTOCGarbage", &status); 1772 if (U_SUCCESS(status)) { 1773 log_err("FAIL: gOffsetTOCGarbage should not be opened. status = %s\n", u_errorName(status)); 1774 } 1775 dataItem = udata_open("OffsetTOCAppData", "", "gOffsetTOCNonExistent", &status); 1776 if (U_SUCCESS(status)) { 1777 log_err("FAIL: gOffsetTOCNonExistent should not be found. status = %s\n", u_errorName(status)); 1778 } 1779 1780} 1781 1782static void SetBadCommonData(void) { 1783 /* It's difficult to test that udata_setCommonData really works within the test framework. 1784 So we just test that foolish people can't do bad things. */ 1785 UErrorCode status; 1786 char badBuffer[sizeof(gOffsetTOCAppData_dat)]; 1787 1788 memset(badBuffer, 0, sizeof(badBuffer)); 1789 strcpy(badBuffer, "Hello! I'm not good data."); 1790 1791 /* Check that we don't do anything */ 1792 status = U_FILE_ACCESS_ERROR; 1793 udata_setCommonData(&gOffsetTOCAppData_dat, &status); 1794 if (status != U_FILE_ACCESS_ERROR) { 1795 log_err("FAIL: udata_setCommonData changed the failure code.\n"); 1796 } 1797 /* Check that we fail correctly */ 1798 status = U_ZERO_ERROR; 1799 udata_setCommonData(NULL, &status); 1800 if (status != U_ILLEGAL_ARGUMENT_ERROR) { 1801 log_err("FAIL: udata_setCommonData did not fail with bad arguments.\n"); 1802 } 1803 1804 /* Check that we verify that the data isn't bad */ 1805 status = U_ZERO_ERROR; 1806 udata_setAppData("invalid path", badBuffer, &status); 1807 if (status != U_INVALID_FORMAT_ERROR) { 1808 log_err("FAIL: udata_setAppData doesn't verify data validity.\n"); 1809 } 1810} 1811 1812