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