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