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