]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/cintltst/udatatst.c
ICU-6.2.22.tar.gz
[apple/icu.git] / icuSources / test / cintltst / udatatst.c
1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1998-2004, 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 "cmemory.h"
24 #include "cstring.h"
25 #include "filestrm.h"
26 #include "udatamem.h"
27 #include "cintltst.h"
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34
35 #ifdef WIN32
36 #include <io.h>
37 #else
38 #include <unistd.h>
39 #endif
40
41 /* includes for TestSwapData() */
42 #include "udataswp.h"
43
44 /* swapping implementations in common */
45 #include "uresdata.h"
46 #include "ucnv_io.h"
47 #include "uprops.h"
48 #include "ucase.h"
49 #include "ucol_swp.h"
50 #include "ucnv_bld.h"
51 #include "unormimp.h"
52 #include "sprpimpl.h"
53 #include "propname.h"
54 #include "rbbidata.h"
55
56 /* other definitions and prototypes */
57
58 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
59
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 TestUDataSetAppData(void);
66 static void TestErrorConditions(void);
67 static void TestAppData(void);
68 static void TestICUDataName(void);
69 static void TestSwapData(void);
70
71 void addUDataTest(TestNode** root);
72
73 void
74 addUDataTest(TestNode** root)
75 {
76 addTest(root, &TestUDataOpen, "udatatst/TestUDataOpen" );
77 addTest(root, &TestUDataOpenChoiceDemo1, "udatatst/TestUDataOpenChoiceDemo1");
78 addTest(root, &TestUDataOpenChoiceDemo2, "udatatst/TestUDataOpenChoiceDemo2");
79 addTest(root, &TestUDataGetInfo, "udatatst/TestUDataGetInfo" );
80 addTest(root, &TestUDataGetMemory, "udatatst/TestUDataGetMemory" );
81 addTest(root, &TestUDataSetAppData, "udatatst/TestUDataSetAppData" );
82 addTest(root, &TestErrorConditions, "udatatst/TestErrorConditions");
83 addTest(root, &TestAppData, "udatatst/TestAppData" );
84 addTest(root, &TestICUDataName, "udatatst/TestICUDataName" );
85 addTest(root, &TestSwapData, "udatatst/TestSwapData" );
86 }
87
88 #if 0
89 static void lots_of_mallocs()
90 {
91 int q;
92 for(q=1;q<100;q++)
93 {
94 free(malloc(q));
95 malloc(q*2);
96 }
97
98 }
99 #endif
100
101 static void TestUDataOpen(){
102 UDataMemory *result;
103 UErrorCode status=U_ZERO_ERROR;
104 const char* memMap[][2]={
105 {"root", "res"},
106 {"unorm", "icu"},
107 {"cnvalias", "icu"},
108 {"unames", "icu"},
109 {"ibm-37_P100-1995", "cnv"}
110 };
111 const char* name = "test";
112 const char* type = "icu";
113 const char dirSepString[] = {U_FILE_SEP_CHAR, 0};
114 const char pathSepString[] = {U_PATH_SEP_CHAR, 0};
115
116
117 char* path=(char*)malloc(sizeof(char) * (strlen(ctest_dataOutDir())
118 + strlen(U_ICUDATA_NAME)
119 + strlen("/build")+1 ) );
120
121 char *icuDataFilePath = 0;
122 struct stat stat_buf;
123
124 const char* testPath=loadTestData(&status);
125
126 /* lots_of_mallocs(); */
127
128 strcat(strcpy(path, ctest_dataOutDir()), U_ICUDATA_NAME);
129
130 log_verbose("Testing udata_open()\n");
131 result=udata_open(testPath, type, name, &status);
132 if(U_FAILURE(status)){
133 log_err("FAIL: udata_open() failed for path = %s, name=%s, type=%s, \n errorcode=%s\n", testPath, name, type, myErrorName(status));
134 } else {
135 log_verbose("PASS: udata_open worked\n");
136 udata_close(result);
137 }
138
139 /* If the ICU system common data file is present in this confiugration,
140 * verify that udata_open can explicitly fetch items from it.
141 * If packaging mode == dll, the file may not exist. So, if the file is
142 * missing, skip this test without error.
143 */
144 icuDataFilePath = (char *)malloc(strlen(path) + 10);
145 strcpy(icuDataFilePath, path);
146 strcat(icuDataFilePath, ".dat");
147 /* lots_of_mallocs(); */
148 if (stat(icuDataFilePath, &stat_buf) == 0)
149 {
150 int i;
151 log_verbose("Testing udata_open() on %s\n", icuDataFilePath);
152 for(i=0; i<sizeof(memMap)/sizeof(memMap[0]); i++){
153 /* lots_of_mallocs(); */
154 status=U_ZERO_ERROR;
155 result=udata_open(path, memMap[i][1], memMap[i][0], &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", path, memMap[i][0], memMap[i][1], myErrorName(status));
158 } else {
159 log_verbose("PASS: udata_open worked for path = %s, name=%s, type=%s\n", path, memMap[i][0], memMap[i][1]);
160 udata_close(result);
161 }
162 }
163 }
164 else
165 {
166 /* lots_of_mallocs(); */
167 log_verbose("Skipping tests of udata_open() on %s. File not present in this configuration.\n",
168 icuDataFilePath);
169 }
170 free(icuDataFilePath);
171 icuDataFilePath = NULL;
172 /* lots_of_mallocs(); */
173
174 /* If the ICU individual files used to build the ICU system common data are
175 * present in this configuration,
176 * verify that udata_open can explicitly open them.
177 * These data files are present in the ICU data/build directory after a build
178 * completes. Tests are most commonly run with the data directory pointing
179 * back into this directory structure, but this is not required. Soooo, if
180 * the files are missing, skip this test without error.
181 */
182 /* lots_of_mallocs(); */
183 icuDataFilePath = (char *)malloc(strlen(ctest_dataOutDir()) + 50);
184 strcpy(icuDataFilePath, ctest_dataOutDir());
185 strcat(icuDataFilePath, "build");
186 strcat(icuDataFilePath, dirSepString);
187 strcat(icuDataFilePath, U_ICUDATA_NAME);
188 strcat(icuDataFilePath, "_");
189 strcat(icuDataFilePath, "unorm.icu");
190
191 /* lots_of_mallocs(); */
192 /* if (stat(icuDataFilePath, &stat_buf) == 0)*/
193 {
194 int i;
195 log_verbose("%s exists, so..\n", icuDataFilePath);
196 strcpy(icuDataFilePath, ctest_dataOutDir());
197 strcat(icuDataFilePath, "build");
198 strcat(icuDataFilePath, dirSepString);
199 strcat(icuDataFilePath, U_ICUDATA_NAME);
200 log_verbose("Testing udata_open() on %s\n", icuDataFilePath);
201 for(i=0; i<sizeof(memMap)/sizeof(memMap[0]); i++){
202 status=U_ZERO_ERROR;
203 result=udata_open(icuDataFilePath, memMap[i][1], memMap[i][0], &status);
204 if(U_FAILURE(status)) {
205 log_data_err("FAIL: udata_open() failed for path = %s, name=%s, type=%s, \n errorcode=%s\n", icuDataFilePath, memMap[i][0], memMap[i][1], myErrorName(status));
206 } else {
207 log_verbose("PASS: udata_open worked for path = %s, name=%s, type=%s\n", icuDataFilePath, memMap[i][0], memMap[i][1]);
208 udata_close(result);
209 }
210 }
211 }
212 /* else
213 {
214 log_verbose("Skipping tests of udata_open() on %s. File not present in this configuration.\n",
215 icuDataFilePath);
216 }*/
217
218 free(icuDataFilePath);
219 icuDataFilePath = NULL;
220
221 /*
222 * Test fallback file names for open of separate data files.
223 * With these params to udata_open:
224 * path = wherever/testdata
225 * type = typ
226 * name = nam
227 * these files will be tried first:
228 * wherever/testudata_nam.typ
229 * testudata_nam.typ
230 * A test data file named testudata_nam.typ exists for the purpose of testing this.
231 */
232 log_verbose("Testing udata_open, with base_name.type style fallback to individual file.\n");
233
234 status = U_ZERO_ERROR;
235 result = udata_open( testPath, "typ", "nam", &status);
236 if (status != U_ZERO_ERROR) {
237 log_err("FAIL: udata_open( \"%s\", \"typ\", \"nam\") returned status %s\n", testPath, u_errorName(status));
238 }
239 udata_close(result);
240 free(icuDataFilePath);
241
242
243 /* This type of path is deprecated */
244 /*
245 * Another fallback test. Paths ending with a trailing directory separator
246 * take a slightly different code path, with the "base name" from the path
247 * being empty in the internal udata_open logic.
248 */
249
250 /* log_verbose("Testing udata_open, with path containing a trailing directory separator.\n"); */
251 /* icuDataFilePath = (char *)malloc(strlen(u_getDataDirectory()) + 50); */
252 /* strcpy(icuDataFilePath, testPath); */
253 /* status = U_ZERO_ERROR; */
254 /* result = udata_open( icuDataFilePath, "cnv", "test1", &status); */
255 /* if (status != U_ZERO_ERROR) { */
256 /* log_err("FAIL: udata_open( \"%s\", \"cnv\", \"test1\") returned status %s\n", icuDataFilePath, u_errorName(status)); */
257 /* } */
258 /* udata_close(result); */
259 /* free(icuDataFilePath); */
260
261
262 log_verbose("Testing udata_open() with a non existing binary file\n");
263 result=udata_open("testdata", "tst", "nonexist", &status);
264 if(status==U_FILE_ACCESS_ERROR){
265 log_verbose("Opening udata_open with non-existing file handled correctly.\n");
266 status=U_ZERO_ERROR;
267 } else {
268 log_err("calling udata_open with non-existing file [testdata | nonexist.tst] not handled correctly\n. Expected: U_FILE_ACCESS_ERROR, Got: %s\n", myErrorName(status));
269 if(U_SUCCESS(status)) {
270 udata_close(result);
271 }
272 }
273
274 if(result != NULL){
275 log_err("calling udata_open with non-existing file didn't return a null value\n");
276 } else {
277 log_verbose("calling udat_open with non-existing file returned null as expected\n");
278 }
279
280 /*
281 * Try opening data with absurdly long path and name, to trigger buffer size
282 * overflow handling code.
283 */
284 {
285 char longTestPath[1024]; /* Implementation goes to heap at length of 128. */
286 char longName[1024];
287
288 /* Try a very long nonexistent directory path.
289 * udata_open should still succeed. Opening with the path will fail,
290 * then fall back to skipping the directory portion of the path.
291 */
292 log_verbose("Testing udata_open() with really long names\n");
293 longTestPath[0] = 0;
294 strcat(longTestPath, "bogus_directory_name");
295 while (strlen(longTestPath) < 500) {
296 strcat(longTestPath, dirSepString);
297 strcat(longTestPath, "bogus_directory_name");
298 }
299 strcat(longTestPath, pathSepString);
300 strcat(longTestPath, testPath);
301 result=udata_open(longTestPath, type, name, &status);
302 if(U_FAILURE(status)){
303 log_err("FAIL: udata_open() failed for path = %s\n name=%s, type=%s, \n errorcode=%s\n",
304 longTestPath, name, type, myErrorName(status));
305 } else {
306 log_verbose("PASS: udata_open worked\n");
307 udata_close(result);
308 }
309
310 /* Try a very long name. Won't open, but shouldn't blow up.
311 */
312 longName[0] = 0;
313 while (strlen(longName) < 500) {
314 strcat(longName, name);
315 strcat(longName, "_");
316 }
317 strcat(longName, dirSepString);
318 strcat(longName, name);
319
320 result=udata_open(longTestPath, type, longName, &status);
321 if (status != U_FILE_ACCESS_ERROR) {
322 log_err("FAIL: udata_open() failed for path = %s\n name=%s, type=%s, \n errorcode=%s\n",
323 longTestPath, longName, type, myErrorName(status));
324 }
325 udata_close(result);
326 }
327
328 free(path);
329 }
330
331
332
333 static void TestUDataSetAppData(){
334 /* UDataMemory *dataItem;*/
335
336 UErrorCode status=U_ZERO_ERROR;
337 int fileHandle = 0; /* We are going to read the testdata.dat file */
338 struct stat statBuf;
339 size_t fileSize = 0;
340 char *fileBuf = 0;
341
342 size_t i;
343
344 /* Open the testdata.dat file, using normal */
345 const char* tdrelativepath = loadTestData(&status);
346 char* filePath=(char*)malloc(sizeof(char) * (strlen(tdrelativepath) + strlen(".dat") +1 +strlen(tdrelativepath)) );
347
348 strcpy(filePath, tdrelativepath);
349 strcat(filePath, ".dat");
350
351 log_verbose("Testing udata_setAppData() with %s\n", filePath);
352
353 #if defined(WIN32) || defined(U_CYGWIN)
354 fileHandle = open( filePath, O_RDONLY | O_BINARY );
355 #else
356 fileHandle = open( filePath, O_RDONLY);
357 #endif
358 if( fileHandle == -1 ) {
359 log_err("FAIL: TestUDataSetAppData() can not open(\"%s\", O_RDONLY)\n", filePath);
360 goto cleanupAndReturn;
361 }
362
363 /*
364 *Find the size of testdata.dat, and read the whole thing into memory
365 */
366 if (fstat(fileHandle, &statBuf) == 0) {
367 fileSize = statBuf.st_size;
368 }
369 if (fileSize == 0) {
370 log_err("FAIL: TestUDataSetAppData() can not find size of file \"%s\".\n", filePath);
371 goto cleanupAndReturn;
372 }
373
374 fileBuf = (char *)ctst_malloc(fileSize);
375 if (fileBuf == 0) {
376 log_err("FAIL: TestUDataSetAppData() can not malloc(%d) for file \"%s\".\n", fileSize, filePath);
377 goto cleanupAndReturn;
378 }
379
380 i = read(fileHandle, fileBuf, fileSize);
381 if (i != fileSize) {
382 log_err("FAIL: TestUDataSetAppData() error reading file \"%s\" size=%d read=%d.\n", filePath, fileSize, i);
383 goto cleanupAndReturn;
384 }
385
386 /*
387 * Got testdata.dat into memory, now we try setAppData using the memory image.
388 */
389
390 status=U_ZERO_ERROR;
391 udata_setAppData("appData1", fileBuf, &status);
392 if (status != U_ZERO_ERROR) {
393 log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData1\", fileBuf, status) "
394 " returned status of %s\n", u_errorName(status));
395 goto cleanupAndReturn;
396 }
397
398 udata_setAppData("appData2", fileBuf, &status);
399 if (status != U_ZERO_ERROR) {
400 log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData2\", fileBuf, status) "
401 " returned status of %s\n", u_errorName(status));
402 goto cleanupAndReturn;
403 }
404
405 /* If we try to setAppData with the same name a second time, we should get a
406 * a using default warning.
407 */
408 udata_setAppData("appData2", fileBuf, &status);
409 if (status != U_USING_DEFAULT_WARNING) {
410 log_err("FAIL: TestUDataSetAppData(): udata_setAppData(\"appData2\", fileBuf, status) "
411 " returned status of %s, expected U_USING_DEFAULT_WARNING.\n", u_errorName(status));
412 }
413
414
415 /** It is no longer correct to use udata_setAppData to change the
416 package of a contained item.
417
418 dataItem = udata_open("appData1", "res", "te_IN", &status); **/
419
420 cleanupAndReturn:
421 /* Note: fileBuf is not deleted because ICU retains a pointer to it
422 * forever (until ICU is shut down).
423 */
424 if (fileHandle > 0) {
425 close(fileHandle);
426 }
427 free(filePath);
428 return;
429 }
430
431
432 static UBool U_CALLCONV
433 isAcceptable1(void *context,
434 const char *type, const char *name,
435 const UDataInfo *pInfo) {
436
437 if( pInfo->size>=20 &&
438 pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
439 pInfo->charsetFamily==U_CHARSET_FAMILY &&
440 pInfo->dataFormat[0]==0x43 && /* dataFormat="CvAl" */
441 pInfo->dataFormat[1]==0x76 &&
442 pInfo->dataFormat[2]==0x41 &&
443 pInfo->dataFormat[3]==0x6c &&
444 pInfo->formatVersion[0]==3 )
445 {
446 log_verbose("The data from \"%s.%s\" IS acceptable using the verifing function isAcceptable1()\n", name, type);
447 return TRUE;
448 } else {
449 log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable1():-\n"
450 "\tsize = %d\n"
451 "\tisBigEndian = %d\n"
452 "\tcharsetFamily = %d\n"
453 "\tformatVersion[0] = %d\n"
454 "\tdataVersion[0] = %d\n"
455 "\tdataFormat = %c%c%c%c\n",
456 name, type, pInfo->size, pInfo->isBigEndian, pInfo->charsetFamily, pInfo->formatVersion[0],
457 pInfo->dataVersion[0], pInfo->dataFormat[0], pInfo->dataFormat[1], pInfo->dataFormat[2],
458 pInfo->dataFormat[3]);
459 log_verbose("Call another verifing function to accept the data\n");
460 return FALSE;
461 }
462 }
463
464 static UBool U_CALLCONV
465 isAcceptable2(void *context,
466 const char *type, const char *name,
467 const UDataInfo *pInfo){
468 UVersionInfo unicodeVersion;
469
470 u_getUnicodeVersion(unicodeVersion);
471
472 if( pInfo->size>=20 &&
473 pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
474 pInfo->charsetFamily==U_CHARSET_FAMILY &&
475 pInfo->dataFormat[0]==0x75 && /* dataFormat="unam" */
476 pInfo->dataFormat[1]==0x6e &&
477 pInfo->dataFormat[2]==0x61 &&
478 pInfo->dataFormat[3]==0x6d &&
479 pInfo->formatVersion[0]==1 &&
480 pInfo->dataVersion[0]==unicodeVersion[0] )
481 {
482 log_verbose("The data from \"%s.%s\" IS acceptable using the verifing function isAcceptable2()\n", name, type);
483 return TRUE;
484 } else {
485 log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable2()\n", name, type);
486
487 return FALSE;
488 }
489
490
491 }
492 static UBool U_CALLCONV
493 isAcceptable3(void *context,
494 const char *type, const char *name,
495 const UDataInfo *pInfo){
496
497 if( pInfo->size>=20 &&
498 pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
499 pInfo->charsetFamily==U_CHARSET_FAMILY &&
500 pInfo->dataFormat[0]==0x54 && /* dataFormat="test" */
501 pInfo->dataFormat[1]==0x65 &&
502 pInfo->dataFormat[2]==0x73 &&
503 pInfo->dataFormat[3]==0x74 &&
504 pInfo->formatVersion[0]==1 &&
505 pInfo->dataVersion[0]==1 ) {
506 log_verbose("The data from \"%s.%s\" IS acceptable using the verifing function isAcceptable3()\n", name, type);
507
508 return TRUE;
509 } else {
510 log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable3()\n", name, type);
511 return FALSE;
512 }
513
514
515 }
516
517 static void TestUDataOpenChoiceDemo1() {
518 UDataMemory *result;
519 UErrorCode status=U_ZERO_ERROR;
520
521 const char* name[]={
522 "cnvalias",
523 "unames",
524 "test"
525 };
526 const char* type="icu";
527 const char* testPath="testdata";
528
529 result=udata_openChoice(NULL, "icu", name[0], isAcceptable1, NULL, &status);
530 if(U_FAILURE(status)){
531 log_err("FAIL: udata_openChoice() failed name=%s, type=%s, \n errorcode=%s\n", name[0], type, myErrorName(status));
532 } else {
533 log_verbose("PASS: udata_openChoice worked\n");
534 udata_close(result);
535 }
536
537 result=udata_openChoice(NULL, type, name[1], isAcceptable1, NULL, &status);
538 if(U_FAILURE(status)){
539 status=U_ZERO_ERROR;
540 result=udata_openChoice(NULL, type, name[1], isAcceptable2, NULL, &status);
541 if(U_FAILURE(status)){
542 log_err("FAIL: udata_openChoice() failed name=%s, type=%s, \n errorcode=%s\n", name[1], type, myErrorName(status));
543 }
544 }
545
546 if(U_SUCCESS(status)){
547 udata_close(result);
548 }
549
550 result=udata_openChoice(testPath, type, name[2], isAcceptable1, NULL, &status);
551 if(U_FAILURE(status)){
552 status=U_ZERO_ERROR;
553 result=udata_openChoice(testPath, type, name[2], isAcceptable3, NULL, &status);
554 if(U_FAILURE(status)){
555 log_err("FAIL: udata_openChoice() failed path=%s name=%s, type=%s, \n errorcode=%s\n", testPath, name[2], type, myErrorName(status));
556 }
557 }
558
559 if(U_SUCCESS(status)){
560 udata_close(result);
561 }
562 }
563
564 static UBool U_CALLCONV
565 isAcceptable(void *context,
566 const char *type, const char *name,
567 const UDataInfo *pInfo){
568 if( pInfo->size>=20 &&
569 pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
570 pInfo->charsetFamily==U_CHARSET_FAMILY &&
571 pInfo->dataFormat[0]==0x54 && /* dataFormat="test" */
572 pInfo->dataFormat[1]==0x65 &&
573 pInfo->dataFormat[2]==0x73 &&
574 pInfo->dataFormat[3]==0x74 &&
575 pInfo->formatVersion[0]==1 &&
576 pInfo->dataVersion[0]==1 &&
577 *((int*)context) == 2 ) {
578 log_verbose("The data from\"%s.%s\" IS acceptable using the verifing function isAcceptable()\n", name, type);
579
580 return TRUE;
581 } else {
582 log_verbose("The data from \"%s.%s\" IS NOT acceptable using the verifing function isAcceptable()\n", name, type);
583 return FALSE;
584 }
585 }
586
587
588 /* This test checks to see if the isAcceptable function is being called correctly. */
589
590 static void TestUDataOpenChoiceDemo2() {
591 UDataMemory *result;
592 UErrorCode status=U_ZERO_ERROR;
593 int i;
594 int p=2;
595
596 const char* name="test";
597 const char* type="icu";
598 const char* path = loadTestData(&status);
599
600 result=udata_openChoice(path, type, name, isAcceptable, &p, &status);
601 if(U_FAILURE(status)){
602 log_err("failed to load data at p=%s t=%s n=%s, isAcceptable", path, type, name);
603 }
604 if(U_SUCCESS(status) ) {
605 udata_close(result);
606 }
607
608 p=0;
609 for(i=0;i<2; i++){
610 result=udata_openChoice(path, type, name, isAcceptable, &p, &status);
611 if(p<2) {
612 if(U_FAILURE(status) && status==U_INVALID_FORMAT_ERROR){
613 log_verbose("Loads the data but rejects it as expected %s\n", myErrorName(status));
614 status=U_ZERO_ERROR;
615 p++;
616 }
617 else {
618 log_err("FAIL: failed to either load the data or to reject the loaded data. ERROR=%s\n", myErrorName(status) );
619 }
620 }
621 else if(p == 2) {
622 if(U_FAILURE(status)) {
623 log_err("FAIL: failed to load the data and accept it. ERROR=%s\n", myErrorName(status) );
624 }
625 else {
626 log_verbose("Loads the data and accepts it for p==2 as expected\n");
627 udata_close(result);
628 }
629 }
630 }
631 }
632
633
634 static void TestUDataGetInfo() {
635
636 UDataMemory *result;
637 /* UDataInfo cf. udata.h */
638 static UDataInfo dataInfo={
639 30, /*sizeof(UDataInfo),*/
640 0,
641
642 U_IS_BIG_ENDIAN,
643 U_CHARSET_FAMILY,
644 sizeof(UChar),
645 0,
646
647 {0x54, 0x65, 0x73, 0x74}, /* dataFormat="Test" */
648 {9, 0, 0, 0}, /* formatVersion */
649 {4, 0, 0, 0} /* dataVersion */
650 };
651 UErrorCode status=U_ZERO_ERROR;
652 const char* name="cnvalias";
653 const char* name2="test";
654 const char* type="icu";
655
656 const char* testPath=loadTestData(&status);
657
658 log_verbose("Testing udata_getInfo() for cnvalias.icu\n");
659 result=udata_open(NULL, "icu", name, &status);
660 if(U_FAILURE(status)){
661 log_err("FAIL: udata_open() failed for path = NULL, name=%s, type=%s, \n errorcode=%s\n", name, type, myErrorName(status));
662 return;
663 }
664 udata_getInfo(result, &dataInfo);
665 if(dataInfo.size==20 && dataInfo.size!=30 &&
666 dataInfo.isBigEndian==U_IS_BIG_ENDIAN &&
667 dataInfo.charsetFamily==U_CHARSET_FAMILY &&
668 dataInfo.dataFormat[0]==0x43 && dataInfo.dataFormat[0]!=0x54 && /* dataFormat="CvAl" and not "Test". The values are set for cnvalias.dat*/
669 dataInfo.dataFormat[1]==0x76 && dataInfo.dataFormat[1]!=0x65 &&
670 dataInfo.dataFormat[2]==0x41 && dataInfo.dataFormat[2]!=0x73 &&
671 dataInfo.dataFormat[3]==0x6c && dataInfo.dataFormat[3]!=0x74 &&
672 dataInfo.formatVersion[0]!=9 && /*formatVersion is also set to the one for cnvalias*/
673 dataInfo.dataVersion[0]!=4 && /*dataVersion*/
674 dataInfo.dataVersion[1]!=0 ){
675 log_verbose("PASS: udata_getInfo() filled in the right values\n");
676 } else {
677 log_err("FAIL: udata_getInfo() filled in the wrong values\n");
678 }
679 udata_close(result);
680
681
682 log_verbose("Testing udata_getInfo() for test.icu\n");
683 result=udata_open(testPath, type, name2, &status);
684 if(U_FAILURE(status)) {
685 log_err("FAIL: udata_open() failed for path=%s name2=%s, type=%s, \n errorcode=%s\n", testPath, name2, type, myErrorName(status));
686 return;
687 }
688 udata_getInfo(result, &dataInfo);
689 if(dataInfo.size==20 &&
690 dataInfo.isBigEndian==U_IS_BIG_ENDIAN &&
691 dataInfo.charsetFamily==U_CHARSET_FAMILY &&
692 dataInfo.dataFormat[0]==0x54 && /* dataFormat="Test". The values are set for test.dat*/
693 dataInfo.dataFormat[1]==0x65 &&
694 dataInfo.dataFormat[2]==0x73 &&
695 dataInfo.dataFormat[3]==0x74 &&
696 dataInfo.formatVersion[0]==1 && /*formatVersion is also set to the one for test*/
697 dataInfo.dataVersion[0]==1 && /*dataVersion*/
698 dataInfo.dataVersion[1]==0 )
699 {
700 log_verbose("PASS: udata_getInfo() filled in the right values\n");
701 } else {
702 log_err("FAIL: udata_getInfo() filled in the wrong values\n");
703 }
704 udata_close(result);
705 }
706
707 static void TestUDataGetMemory() {
708
709 UDataMemory *result;
710 const int32_t *table=NULL;
711 uint16_t* intValue=0;
712 UErrorCode status=U_ZERO_ERROR;
713 const char* name="cnvalias";
714 const char* type;
715
716 const char* name2="test";
717
718 const char* testPath = loadTestData(&status);
719
720 type="icu";
721 log_verbose("Testing udata_getMemory() for \"cnvalias.icu\"\n");
722 result=udata_openChoice(NULL, type, name, isAcceptable1, NULL, &status);
723 if(U_FAILURE(status)){
724 log_err("FAIL: udata_openChoice() failed for name=%s, type=%s, \n errorcode=%s\n", name, type, myErrorName(status));
725 return;
726 }
727 table=(const int32_t *)udata_getMemory(result);
728
729 /* The alias table may list more converters than what's actually available now. [grhoten] */
730 if(ucnv_countAvailable() > table[1]) /*???*/
731 log_err("FAIL: udata_getMemory() failed ucnv_countAvailable returned = %d, expected = %d\n", ucnv_countAvailable(), table[1+2*(*table)]);
732
733 udata_close(result);
734
735 type="icu";
736 log_verbose("Testing udata_getMemory for \"test.icu\"()\n");
737 result=udata_openChoice(testPath, type, name2, isAcceptable3, NULL, &status);
738 if(U_FAILURE(status)){
739 log_err("FAIL: udata_openChoice() failed for path=%s name=%s, type=%s, \n errorcode=%s\n", testPath, name2, type, myErrorName(status));
740 return;
741 }
742 intValue=(uint16_t *)udata_getMemory(result);
743 /*printf("%d ..... %s", *(intValue), intValue+1));*/
744 if( *intValue != 2000 || strcmp((char*)(intValue+1), "YEAR") != 0 )
745 log_err("FAIL: udata_getMemory() failed: intValue :- Expected:2000 Got:%d \n\tstringValue:- Expected:YEAR Got:%s\n", *intValue, (intValue+1));
746
747 udata_close(result);
748
749 }
750
751 static void TestErrorConditions(){
752
753 UDataMemory *result=NULL;
754 UErrorCode status=U_ZERO_ERROR;
755 uint16_t* intValue=0;
756 static UDataInfo dataInfo={
757 30, /*sizeof(UDataInfo),*/
758 0,
759
760 U_IS_BIG_ENDIAN,
761 U_CHARSET_FAMILY,
762 sizeof(UChar),
763 0,
764
765 {0x54, 0x65, 0x73, 0x74}, /* dataFormat="Test" */
766 {9, 0, 0, 0}, /* formatVersion */
767 {4, 0, 0, 0} /* dataVersion */
768 };
769
770 const char* name = "test";
771 const char* type="icu";
772
773 const char *testPath = loadTestData(&status);
774
775 status = U_ILLEGAL_ARGUMENT_ERROR;
776 /*Try udata_open with status != U_ZERO_ERROR*/
777 log_verbose("Testing udata_open() with status != U_ZERO_ERROR\n");
778 result=udata_open(testPath, type, name, &status);
779 if(result != NULL){
780 log_err("FAIL: udata_open() is supposed to fail for path = %s, name=%s, type=%s, \n errorcode !=U_ZERO_ERROR\n", testPath, name, type);
781 udata_close(result);
782
783 } else {
784 log_verbose("PASS: udata_open with errorCode != U_ZERO_ERROR failed as expected\n");
785 }
786
787 /*Try udata_open with data name=NULL*/
788 log_verbose("Testing udata_open() with data name=NULL\n");
789 status=U_ZERO_ERROR;
790 result=udata_open(testPath, type, NULL, &status);
791 if(U_FAILURE(status)){
792 if(status != U_ILLEGAL_ARGUMENT_ERROR || result != NULL){
793 log_err("FAIL: udata_open() with name=NULL should return NULL and errocode U_ILLEGAL_ARGUMENT_ERROR, GOT: errorcode=%s\n", myErrorName(status));
794 }else{
795 log_verbose("PASS: udata_open with name=NULL failed as expected and errorcode = %s as expected\n", myErrorName(status));
796 }
797 }else{
798 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);
799 udata_close(result);
800 }
801
802
803 /*Try udata_openChoice with status != U_ZERO_ERROR*/
804 log_verbose("Testing udata_openChoice() with status != U_ZERO_ERROR\n");
805 status=U_ILLEGAL_ARGUMENT_ERROR;
806 result=udata_openChoice(testPath, type, name, isAcceptable3, NULL, &status);
807 if(result != NULL){
808 log_err("FAIL: udata_openChoice() is supposed to fail for path = %s, name=%s, type=%s, \n errorcode != U_ZERO_ERROR\n", testPath, name, type);
809 udata_close(result);
810 } else {
811 log_verbose("PASS: udata_openChoice() with errorCode != U_ZERO_ERROR failed as expected\n");
812 }
813
814 /*Try udata_open with data name=NULL*/
815 log_verbose("Testing udata_openChoice() with data name=NULL\n");
816 status=U_ZERO_ERROR;
817 result=udata_openChoice(testPath, type, NULL, isAcceptable3, NULL, &status);
818 if(U_FAILURE(status)){
819 if(status != U_ILLEGAL_ARGUMENT_ERROR || result != NULL){
820 log_err("FAIL: udata_openChoice() with name=NULL should return NULL and errocode U_ILLEGAL_ARGUMENT_ERROR, GOT: errorcode=%s\n", myErrorName(status));
821 }else{
822 log_verbose("PASS: udata_openChoice with name=NULL failed as expected and errorcode = %s as expected\n", myErrorName(status));
823 }
824 }else{
825 log_err("FAIL: udata_openChoice() with data name=NULL is supposed to fail for path = %s, name=NULL type=%s errorcode=U_ZERO_ERROR \n", testPath, type);
826 udata_close(result);
827 }
828
829 /*Try udata_getMemory with UDataMemory=NULL*/
830 log_verbose("Testing udata_getMemory with UDataMemory=NULL\n");
831 intValue=(uint16_t*)udata_getMemory(NULL);
832 if(intValue != NULL){
833 log_err("FAIL: udata_getMemory with UDataMemory = NULL is supposed to fail\n");
834 }
835
836 /*Try udata_getInfo with UDataMemory=NULL*/
837 status=U_ZERO_ERROR;
838 udata_getInfo(NULL, &dataInfo);
839 if(dataInfo.size != 0){
840 log_err("FAIL : udata_getInfo with UDataMemory = NULL us supposed to fail\n");
841 }
842
843 /*Try udata_openChoice with a non existing binary file*/
844 log_verbose("Testing udata_openChoice() with a non existing binary file\n");
845 result=udata_openChoice(testPath, "tst", "nonexist", isAcceptable3, NULL, &status);
846 if(status==U_FILE_ACCESS_ERROR){
847 log_verbose("Opening udata_openChoice with non-existing file handled correctly.\n");
848 status=U_ZERO_ERROR;
849 } else {
850 log_err("calling udata_open with non-existing file not handled correctly\n. Expected: U_FILE_ACCESS_ERROR, Got: %s\n", myErrorName(status));
851 if(U_SUCCESS(status)) {
852 udata_close(result);
853 }
854 }
855
856 if(result != NULL){
857 log_err("calling udata_open with non-existing file didn't return a null value\n");
858 } else {
859 log_verbose("calling udat_open with non-existing file returned null as expected\n");
860 }
861 }
862
863 /* Test whether apps and ICU can each have their own root.res */
864 static void TestAppData()
865 {
866 UResourceBundle *icu, *app;
867 UResourceBundle *tmp = NULL;
868 UResourceBundle *tmp2 = NULL;
869
870 const UChar *appString;
871 const UChar *icuString;
872
873 int32_t len;
874
875 UErrorCode status = U_ZERO_ERROR;
876 char testMsgBuf[256];
877
878 const char* testPath=loadTestData(&status);
879
880 icu = ures_open(NULL, "root", &status);
881 if(U_FAILURE(status))
882 {
883 log_err("%s:%d: Couldn't open root ICU bundle- %s", __FILE__, __LINE__, u_errorName(status));
884 return;
885 }
886 /* log_info("Open icu root: %s size_%d\n", u_errorName(status), ures_getSize(icu)); */
887 status = U_ZERO_ERROR;
888
889 app = ures_open(testPath, "root", &status);
890 if(U_FAILURE(status))
891 {
892 log_err("%s:%d: Couldn't open app ICU bundle [%s]- %s", __FILE__, __LINE__, testPath, u_errorName(status));
893 return;
894 }
895 /* log_info("Open app: %s, size %d\n", u_errorName(status), ures_getSize(app)); */
896
897 tmp = ures_getByKey(icu, "Version", tmp, &status);
898 if(U_FAILURE(status))
899 {
900 log_err("%s:%d: Couldn't get Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status));
901 return;
902 }
903
904 icuString = ures_getString(tmp, &len, &status);
905 if(U_FAILURE(status))
906 {
907 log_err("%s:%d: Couldn't get string from Version string from ICU root bundle- %s", __FILE__, __LINE__, u_errorName(status));
908 return;
909 }
910 /* log_info("icuString=%p - %s\n", icuString, austrdup(icuString)); */
911
912
913 tmp2 = ures_getByKey(app, "Version", tmp2, &status);
914 if(U_FAILURE(status))
915 {
916 log_err("%s:%d: Couldn't get Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status));
917 return;
918 }
919
920 appString = ures_getString(tmp2, &len, &status);
921 if(U_FAILURE(status))
922 {
923 log_err("%s:%d: Couldn't get string from Version string from App root bundle- %s", __FILE__, __LINE__, u_errorName(status));
924 return;
925 }
926
927 /* log_info("appString=%p - %s\n", appString, austrdup(appString)); */
928
929
930 if(!u_strcmp(icuString, appString))
931 {
932 log_err("%s:%d: Error! Expected ICU and App root version strings to be DIFFERENT but they are both %s and %s\n", __FILE__, __LINE__, austrdup(icuString),
933 austrdup(appString));
934 }
935 else
936 {
937 log_verbose("%s:%d: appstr=%s, icustr=%s\n", __FILE__,
938 __LINE__, u_austrcpy(testMsgBuf, appString), u_austrcpy(testMsgBuf, icuString));
939 }
940
941 ures_close(tmp);
942 ures_close(tmp2);
943 ures_close(icu);
944 ures_close(app);
945 }
946
947 static void TestICUDataName()
948 {
949 UVersionInfo icuVersion;
950 char expectDataName[20];
951 unsigned int expectLen = 8;
952
953 char typeChar = '?';
954
955 /* Print out the version # we have .. */
956 log_verbose("utypes.h says U_ICUDATA_NAME = %s\n", U_ICUDATA_NAME);
957
958 /* Build up the version # we expect to get */
959 u_getVersion(icuVersion);
960
961 switch(U_CHARSET_FAMILY)
962 {
963 case U_ASCII_FAMILY:
964 switch(U_IS_BIG_ENDIAN)
965 {
966 case 1:
967 typeChar = 'b';
968 break;
969 case 0:
970 typeChar = 'l';
971 break;
972 default:
973 log_err("Expected 1 or 0 for U_IS_BIG_ENDIAN, got %d!\n", (int)U_IS_BIG_ENDIAN);
974 /* return; */
975 }
976 break;
977 case U_EBCDIC_FAMILY:
978 typeChar = 'e';
979 break;
980 }
981
982 sprintf(expectDataName, "%s%d%d%c",
983 "icudt",
984 (int)icuVersion[0],
985 (int)icuVersion[1],
986 typeChar);
987
988 log_verbose("Expected: %s\n", expectDataName);
989 if(uprv_strlen(expectDataName) != expectLen)
990 {
991 log_err("*Expected* length is wrong (test err?), should be %d is %d\n",
992 expectLen, uprv_strlen(expectDataName));
993 }
994
995 if(uprv_strlen(U_ICUDATA_NAME) != expectLen)
996 {
997 log_err("U_ICUDATA_NAME length should be %d is %d\n",
998 expectLen, uprv_strlen(U_ICUDATA_NAME));
999 }
1000
1001 if(uprv_strcmp(U_ICUDATA_NAME, expectDataName))
1002 {
1003 log_err("U_ICUDATA_NAME should be %s but is %s\n",
1004 expectDataName, U_ICUDATA_NAME);
1005 }
1006
1007 /* ICUDATA_NAME comes from the build system on *nix */
1008 #ifdef ICUDATA_NAME
1009 if(uprv_strcmp(U_ICUDATA_NAME, ICUDATA_NAME))
1010 {
1011 log_err("ICUDATA_NAME and U_ICUDATA_NAME don't match: "
1012 "ICUDATA_NAME=%s, U_ICUDATA_NAME=%s. Check configure.in, icudefs.mk.in, utypes.h...\n", ICUDATA_NAME, U_ICUDATA_NAME);
1013 }
1014 else
1015 {
1016 log_verbose("ICUDATA_NAME=%s (from icudefs.mk), U_ICUDATA_NAME=%s (from utypes.h)\n", ICUDATA_NAME, U_ICUDATA_NAME);
1017 }
1018 #endif
1019
1020 }
1021
1022 /* test data swapping ------------------------------------------------------- */
1023
1024 /* test cases for maximum data swapping code coverage */
1025 static const struct {
1026 const char *name, *type;
1027 UDataSwapFn *swapFn;
1028 } swapCases[]={
1029 /* resource bundles */
1030
1031 /* resource bundle with many data types */
1032 {"*testtypes", "res", ures_swap},
1033 /* resource bundle with collation data */
1034 {"ja", "res", ures_swap},
1035 /* resource bundle with options-only collation data */
1036 {"ru", "res", ures_swap},
1037 {"el", "res", ures_swap},
1038 /* ICU's root */
1039 {"root", "res", ures_swap},
1040
1041 /* ICU 2.6 resource bundle - data format 1.0, without indexes[] (little-endian ASCII) */
1042 {"*icu26_testtypes", "res", ures_swap},
1043 /* same for big-endian EBCDIC */
1044 {"*icu26e_testtypes", "res", ures_swap},
1045
1046 #if !UCONFIG_NO_COLLATION
1047 /* standalone collation data files */
1048 {"ucadata", "icu", ucol_swap},
1049 {"invuca", "icu", ucol_swapInverseUCA},
1050 #endif
1051
1052 #if !UCONFIG_NO_LEGACY_CONVERSION
1053 /* conversion table files */
1054
1055 /* SBCS conversion table file without extension */
1056 {"ibm-913_P100-2000", "cnv", ucnv_swap},
1057 /* EBCDIC_STATEFUL conversion table file with extension */
1058 {"ibm-1390_P110-2003", "cnv", ucnv_swap},
1059 /* DBCS extension-only conversion table file */
1060 {"ibm-16684_P110-2003", "cnv", ucnv_swap},
1061 /* EUC-TW (3-byte) conversion table file without extension */
1062 {"ibm-964_P110-1999", "cnv", ucnv_swap},
1063 /* GB 18030 (4-byte) conversion table file without extension */
1064 {"gb18030", "cnv", ucnv_swap},
1065 /* MBCS conversion table file with extension */
1066 {"*test4x", "cnv", ucnv_swap},
1067
1068 /* alias table */
1069 {"cnvalias", "icu", ucnv_swapAliases},
1070 #endif
1071
1072 #if !UCONFIG_NO_IDNA
1073 {"uidna", "spp", usprep_swap},
1074 #endif
1075
1076 #if !UCONFIG_NO_BREAK_ITERATION
1077 {"char", "brk", ubrk_swap},
1078 #endif
1079
1080 /* the last item should not be #if'ed so that it can reliably omit the last comma */
1081
1082 /* Unicode properties */
1083 {"unames", "icu", uchar_swapNames},
1084 {"pnames", "icu", upname_swap},
1085 #if !UCONFIG_NO_NORMALIZATION
1086 {"unorm", "icu", unorm_swap},
1087 #endif
1088 {"uprops", "icu", uprops_swap},
1089 {"ucase", "icu", ucase_swap}
1090 };
1091
1092 #define SWAP_BUFFER_SIZE 1000000
1093
1094 static void U_CALLCONV
1095 printError(void *context, const char *fmt, va_list args) {
1096 vlog_info("[swap] ", fmt, args);
1097 }
1098
1099 static void
1100 TestSwapCase(UDataMemory *pData, const char *name,
1101 UDataSwapFn *swapFn,
1102 uint8_t *buffer, uint8_t *buffer2) {
1103 UDataSwapper *ds;
1104 const void *inData, *inHeader;
1105 int32_t length, dataLength, length2, headerLength;
1106
1107 UErrorCode errorCode;
1108
1109 UBool inEndian, oppositeEndian;
1110 uint8_t inCharset, oppositeCharset;
1111
1112 inData=udata_getMemory(pData);
1113
1114 /*
1115 * get the data length if possible, to verify that swapping and preflighting
1116 * handles the entire data
1117 */
1118 dataLength=udata_getLength(pData);
1119
1120 /*
1121 * get the header and its length
1122 * all of the swap implementation functions require the header to be included
1123 */
1124 inHeader=udata_getRawMemory(pData);
1125 headerLength=(int32_t)((const char *)inData-(const char *)inHeader);
1126
1127 /* first swap to opposite endianness but same charset family */
1128 errorCode=U_ZERO_ERROR;
1129 ds=udata_openSwapperForInputData(inHeader, headerLength,
1130 !U_IS_BIG_ENDIAN, U_CHARSET_FAMILY, &errorCode);
1131 if(U_FAILURE(errorCode)) {
1132 log_err("udata_openSwapperForInputData(%s->!isBig+same charset) failed - %s\n",
1133 name, u_errorName(errorCode));
1134 return;
1135 }
1136
1137 inEndian=ds->inIsBigEndian;
1138 inCharset=ds->inCharset;
1139
1140 oppositeEndian=!inEndian;
1141 oppositeCharset= inCharset==U_ASCII_FAMILY ? U_EBCDIC_FAMILY : U_ASCII_FAMILY;
1142
1143 /* make this test work with data files that are built for a different platform */
1144 if(inEndian!=U_IS_BIG_ENDIAN || inCharset!=U_CHARSET_FAMILY) {
1145 udata_closeSwapper(ds);
1146 ds=udata_openSwapper(inEndian, inCharset, oppositeEndian, inCharset, &errorCode);
1147 if(U_FAILURE(errorCode)) {
1148 log_err("udata_openSwapper(%s->!isBig+same charset) failed - %s\n",
1149 name, u_errorName(errorCode));
1150 return;
1151 }
1152 }
1153
1154 ds->printError=printError;
1155
1156 /* preflight the length */
1157 length=swapFn(ds, inHeader, -1, NULL, &errorCode);
1158 if(U_FAILURE(errorCode)) {
1159 log_err("swapFn(preflight %s->!isBig+same charset) failed - %s\n",
1160 name, u_errorName(errorCode));
1161 udata_closeSwapper(ds);
1162 return;
1163 }
1164
1165 /* compare the preflighted length against the data length */
1166 if(dataLength>=0 && (length+15)<(headerLength+dataLength)) {
1167 log_err("swapFn(preflight %s->!isBig+same charset) length too small: %d < data length %d\n",
1168 name, length, (headerLength+dataLength));
1169 udata_closeSwapper(ds);
1170 return;
1171 }
1172
1173 /* swap, not in-place */
1174 length2=swapFn(ds, inHeader, length, buffer, &errorCode);
1175 udata_closeSwapper(ds);
1176 if(U_FAILURE(errorCode)) {
1177 log_err("swapFn(%s->!isBig+same charset) failed - %s\n",
1178 name, u_errorName(errorCode));
1179 return;
1180 }
1181
1182 /* compare the swap length against the preflighted length */
1183 if(length2!=length) {
1184 log_err("swapFn(%s->!isBig+same charset) length differs from preflighting: %d != preflighted %d\n",
1185 name, length2, length);
1186 return;
1187 }
1188
1189 /* next swap to opposite charset family */
1190 ds=udata_openSwapper(oppositeEndian, inCharset,
1191 oppositeEndian, oppositeCharset,
1192 &errorCode);
1193 if(U_FAILURE(errorCode)) {
1194 log_err("udata_openSwapper(%s->!isBig+other charset) failed - %s\n",
1195 name, u_errorName(errorCode));
1196 return;
1197 }
1198 ds->printError=printError;
1199
1200 /* swap in-place */
1201 length2=swapFn(ds, buffer, length, buffer, &errorCode);
1202 udata_closeSwapper(ds);
1203 if(U_FAILURE(errorCode)) {
1204 log_err("swapFn(%s->!isBig+other charset) failed - %s\n",
1205 name, u_errorName(errorCode));
1206 return;
1207 }
1208
1209 /* compare the swap length against the original length */
1210 if(length2!=length) {
1211 log_err("swapFn(%s->!isBig+other charset) length differs from original: %d != original %d\n",
1212 name, length2, length);
1213 return;
1214 }
1215
1216 /* finally swap to original platform values */
1217 ds=udata_openSwapper(oppositeEndian, oppositeCharset,
1218 inEndian, inCharset,
1219 &errorCode);
1220 if(U_FAILURE(errorCode)) {
1221 log_err("udata_openSwapper(%s->back to original) failed - %s\n",
1222 name, u_errorName(errorCode));
1223 return;
1224 }
1225 ds->printError=printError;
1226
1227 /* swap, not in-place */
1228 length2=swapFn(ds, buffer, length, buffer2, &errorCode);
1229 udata_closeSwapper(ds);
1230 if(U_FAILURE(errorCode)) {
1231 log_err("swapFn(%s->back to original) failed - %s\n",
1232 name, u_errorName(errorCode));
1233 return;
1234 }
1235
1236 /* compare the swap length against the original length */
1237 if(length2!=length) {
1238 log_err("swapFn(%s->back to original) length differs from original: %d != original %d\n",
1239 name, length2, length);
1240 return;
1241 }
1242
1243 /* compare the final contents with the original */
1244 if(0!=uprv_memcmp(inHeader, buffer2, length)) {
1245 const uint8_t *original;
1246 uint8_t diff[8];
1247 int32_t i, j;
1248
1249 log_err("swapFn(%s->back to original) contents differs from original\n",
1250 name);
1251
1252 /* find the first difference */
1253 original=(const uint8_t *)inHeader;
1254 for(i=0; i<length && original[i]==buffer2[i]; ++i) {}
1255
1256 /* find the next byte that is the same */
1257 for(j=i+1; j<length && original[j]!=buffer2[j]; ++j) {}
1258 log_info(" difference at index %d=0x%x, until index %d=0x%x\n", i, i, j, j);
1259
1260 /* round down to the last 4-boundary for better result output */
1261 i&=~3;
1262 log_info("showing bytes from index %d=0x%x (length %d=0x%x):\n", i, i, length, length);
1263
1264 /* print 8 bytes but limit to the buffer contents */
1265 length2=i+sizeof(diff);
1266 if(length2>length) {
1267 length2=length;
1268 }
1269
1270 /* print the original bytes */
1271 uprv_memset(diff, 0, sizeof(diff));
1272 for(j=i; j<length2; ++j) {
1273 diff[j-i]=original[j];
1274 }
1275 log_info(" original: %02x %02x %02x %02x %02x %02x %02x %02x\n",
1276 diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]);
1277
1278 /* print the swapped bytes */
1279 uprv_memset(diff, 0, sizeof(diff));
1280 for(j=i; j<length2; ++j) {
1281 diff[j-i]=buffer2[j];
1282 }
1283 log_info(" swapped: %02x %02x %02x %02x %02x %02x %02x %02x\n",
1284 diff[0], diff[1], diff[2], diff[3], diff[4], diff[5], diff[6], diff[7]);
1285 }
1286 }
1287
1288 static void
1289 TestSwapData() {
1290 char name[100];
1291 UDataMemory *pData;
1292 uint8_t *buffer;
1293 const char *pkg, *nm;
1294
1295 UErrorCode errorCode;
1296 int32_t i;
1297
1298 buffer=(uint8_t *)uprv_malloc(2*SWAP_BUFFER_SIZE);
1299 if(buffer==NULL) {
1300 log_err("unable to allocate %d bytes\n", 2*SWAP_BUFFER_SIZE);
1301 return;
1302 }
1303
1304 for(i=0; i<LENGTHOF(swapCases); ++i) {
1305 /* build the name for logging */
1306 errorCode=U_ZERO_ERROR;
1307 if(swapCases[i].name[0]=='*') {
1308 pkg=loadTestData(&errorCode);
1309 nm=swapCases[i].name+1;
1310 uprv_strcpy(name, "testdata");
1311 } else {
1312 pkg=NULL;
1313 nm=swapCases[i].name;
1314 uprv_strcpy(name, "NULL");
1315 }
1316 uprv_strcat(name, "/");
1317 uprv_strcat(name, nm);
1318 uprv_strcat(name, ".");
1319 uprv_strcat(name, swapCases[i].type);
1320
1321 pData=udata_open(pkg, swapCases[i].type, nm, &errorCode);
1322 if(U_SUCCESS(errorCode)) {
1323 TestSwapCase(pData, name, swapCases[i].swapFn, buffer, buffer+SWAP_BUFFER_SIZE);
1324 udata_close(pData);
1325 } else {
1326 log_data_err("udata_open(%s) failed - %s\n",
1327 name, u_errorName(errorCode));
1328 }
1329 }
1330
1331 uprv_free(buffer);
1332 }