1/********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2014, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6/*******************************************************************************
7*
8* File CRESTST.C
9*
10* Modification History:
11*        Name                     Description
12*     Madhu Katragadda            Ported for C API
13*  06/14/99     stephen           Updated for RB API changes (no suffix).
14********************************************************************************
15*/
16
17
18#include "unicode/utypes.h"
19#include "cintltst.h"
20#include "unicode/ustring.h"
21#include "cstring.h"
22#include "filestrm.h"
23#include <stdlib.h>
24
25#define RESTEST_HEAP_CHECK 0
26
27#include "unicode/ures.h"
28#include "crestst.h"
29#include "unicode/ctest.h"
30
31#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
32
33static void TestOpenDirect(void);
34static void TestFallback(void);
35static void TestTable32(void);
36static void TestFileStream(void);
37/*****************************************************************************/
38
39const UChar kERROR[] = { 0x0045 /*E*/, 0x0052 /*'R'*/, 0x0052 /*'R'*/,
40             0x004F /*'O'*/, 0x0052/*'R'*/, 0x0000 /*'\0'*/};
41
42/*****************************************************************************/
43
44enum E_Where
45{
46  e_Root,
47  e_te,
48  e_te_IN,
49  e_Where_count
50};
51typedef enum E_Where E_Where;
52/*****************************************************************************/
53
54#define CONFIRM_EQ(actual,expected) if (u_strcmp(expected,actual)==0){ record_pass(); } else { record_fail(); log_err("%s  returned  %s  instead of %s\n", action, austrdup(actual), austrdup(expected)); }
55
56#define CONFIRM_ErrorCode(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail();  log_err("%s returned  %s  instead of %s\n", action, myErrorName(actual), myErrorName(expected)); }
57
58
59/* Array of our test objects */
60
61static struct
62{
63  const char* name;
64  UErrorCode expected_constructor_status;
65  E_Where where;
66  UBool like[e_Where_count];
67  UBool inherits[e_Where_count];
68} param[] =
69{
70  /* "te" means test */
71  /* "IN" means inherits */
72  /* "NE" or "ne" means "does not exist" */
73
74  { "root",         U_ZERO_ERROR,             e_Root,    { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } },
75  { "te",           U_ZERO_ERROR,             e_te,      { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
76  { "te_IN",        U_ZERO_ERROR,             e_te_IN,   { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
77  { "te_NE",        U_USING_FALLBACK_WARNING, e_te,      { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE } },
78  { "te_IN_NE",     U_USING_FALLBACK_WARNING, e_te_IN,   { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE } },
79  { "ne",           U_USING_DEFAULT_WARNING,  e_Root,    { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } }
80};
81
82static int32_t bundles_count = sizeof(param) / sizeof(param[0]);
83
84
85
86/***************************************************************************************/
87
88/* Array of our test objects */
89
90void addResourceBundleTest(TestNode** root);
91
92void addResourceBundleTest(TestNode** root)
93{
94#if !UCONFIG_NO_FILE_IO && !UCONFIG_NO_LEGACY_CONVERSION
95    addTest(root, &TestConstruction1, "tsutil/crestst/TestConstruction1");
96    addTest(root, &TestOpenDirect, "tsutil/crestst/TestOpenDirect");
97    addTest(root, &TestResourceBundles, "tsutil/crestst/TestResourceBundles");
98    addTest(root, &TestTable32, "tsutil/crestst/TestTable32");
99    addTest(root, &TestFileStream, "tsutil/crestst/TestFileStream");
100    addTest(root, &TestGetSize, "tsutil/crestst/TestGetSize");
101    addTest(root, &TestGetLocaleByType, "tsutil/crestst/TestGetLocaleByType");
102#endif
103    addTest(root, &TestFallback, "tsutil/crestst/TestFallback");
104    addTest(root, &TestAliasConflict, "tsutil/crestst/TestAliasConflict");
105
106}
107
108
109/***************************************************************************************/
110void TestAliasConflict(void) {
111    UErrorCode status = U_ZERO_ERROR;
112    UResourceBundle *he = NULL;
113    UResourceBundle *iw = NULL;
114    const UChar *result = NULL;
115    int32_t resultLen;
116
117    he = ures_open(NULL, "he", &status);
118    iw = ures_open(NULL, "iw", &status);
119    if(U_FAILURE(status)) {
120        log_err_status(status, "Failed to get resource with %s\n", myErrorName(status));
121    }
122    ures_close(iw);
123    result = ures_getStringByKey(he, "ExemplarCharacters", &resultLen, &status);
124    if(U_FAILURE(status) || result == NULL) {
125        log_err_status(status, "Failed to get resource with %s\n", myErrorName(status));
126    }
127    ures_close(he);
128}
129
130
131void TestResourceBundles()
132{
133    UErrorCode status = U_ZERO_ERROR;
134    loadTestData(&status);
135    if(U_FAILURE(status)) {
136        log_data_err("Could not load testdata.dat, status = %s\n", u_errorName(status));
137        return;
138    }
139
140    testTag("only_in_Root", TRUE, FALSE, FALSE);
141    testTag("in_Root_te", TRUE, TRUE, FALSE);
142    testTag("in_Root_te_te_IN", TRUE, TRUE, TRUE);
143    testTag("in_Root_te_IN", TRUE, FALSE, TRUE);
144    testTag("only_in_te", FALSE, TRUE, FALSE);
145    testTag("only_in_te_IN", FALSE, FALSE, TRUE);
146    testTag("in_te_te_IN", FALSE, TRUE, TRUE);
147    testTag("nonexistent", FALSE, FALSE, FALSE);
148
149    log_verbose("Passed:=  %d   Failed=   %d \n", pass, fail);
150}
151
152void TestConstruction1()
153{
154    UResourceBundle *test1 = 0, *test2 = 0;
155    const UChar *result1, *result2;
156    int32_t resultLen;
157    UChar temp[7];
158
159    UErrorCode   err = U_ZERO_ERROR;
160    const char* testdatapath ;
161    const char*      locale="te_IN";
162
163    log_verbose("Testing ures_open()......\n");
164
165
166    testdatapath=loadTestData(&err);
167    if(U_FAILURE(err))
168    {
169        log_data_err("Could not load testdata.dat %s \n",myErrorName(err));
170        return;
171    }
172
173    test1=ures_open(testdatapath, NULL, &err);
174    if(U_FAILURE(err))
175    {
176        log_err("construction of %s did not succeed :  %s \n",NULL, myErrorName(err));
177        return;
178    }
179
180
181    test2=ures_open(testdatapath, locale, &err);
182    if(U_FAILURE(err))
183    {
184        log_err("construction of %s did not succeed :  %s \n",locale, myErrorName(err));
185        return;
186    }
187    result1= ures_getStringByKey(test1, "string_in_Root_te_te_IN", &resultLen, &err);
188    result2= ures_getStringByKey(test2, "string_in_Root_te_te_IN", &resultLen, &err);
189
190
191    if (U_FAILURE(err)) {
192        log_err("Something threw an error in TestConstruction(): %s\n", myErrorName(err));
193        return;
194    }
195
196    u_uastrcpy(temp, "TE_IN");
197
198    if(u_strcmp(result2, temp)!=0)
199    {
200        int n;
201
202        log_err("Construction test failed for ures_open();\n");
203        if(!getTestOption(VERBOSITY_OPTION))
204            log_info("(run verbose for more information)\n");
205
206        log_verbose("\nGot->");
207        for(n=0;result2[n];n++)
208        {
209            log_verbose("%04X ",result2[n]);
210        }
211        log_verbose("<\n");
212
213        log_verbose("\nWant>");
214        for(n=0;temp[n];n++)
215        {
216            log_verbose("%04X ",temp[n]);
217        }
218        log_verbose("<\n");
219
220    }
221
222    log_verbose("for string_in_Root_te_te_IN, default.txt had  %s\n", austrdup(result1));
223    log_verbose("for string_in_Root_te_te_IN, te_IN.txt had %s\n", austrdup(result2));
224
225    /* Test getVersionNumber*/
226    log_verbose("Testing version number\n");
227    log_verbose("for getVersionNumber :  %s\n", ures_getVersionNumber(test1));
228
229    ures_close(test1);
230    ures_close(test2);
231}
232
233/*****************************************************************************/
234/*****************************************************************************/
235
236UBool testTag(const char* frag,
237           UBool in_Root,
238           UBool in_te,
239           UBool in_te_IN)
240{
241    int32_t passNum=pass;
242
243    /* Make array from input params */
244
245    UBool is_in[3];
246    const char *NAME[] = { "ROOT", "TE", "TE_IN" };
247
248    /* Now try to load the desired items */
249    UResourceBundle* theBundle = NULL;
250    char tag[99];
251    char action[256];
252    UErrorCode status = U_ZERO_ERROR,expected_resource_status = U_ZERO_ERROR;
253    UChar* base = NULL;
254    UChar* expected_string = NULL;
255    const UChar* string = NULL;
256    char item_tag[10];
257    int32_t i,j;
258    int32_t actual_bundle;
259    int32_t resultLen;
260    const char *testdatapath = loadTestData(&status);
261
262    is_in[0] = in_Root;
263    is_in[1] = in_te;
264    is_in[2] = in_te_IN;
265
266    strcpy(item_tag, "tag");
267
268    status = U_ZERO_ERROR;
269    theBundle = ures_open(testdatapath, "root", &status);
270    if(U_FAILURE(status))
271    {
272        ures_close(theBundle);
273        log_err("Couldn't open root bundle in %s", testdatapath);
274        return FALSE;
275    }
276    ures_close(theBundle);
277    theBundle = NULL;
278
279
280    for (i=0; i<bundles_count; ++i)
281    {
282        strcpy(action,"construction for");
283        strcat(action, param[i].name);
284
285
286        status = U_ZERO_ERROR;
287
288        theBundle = ures_open(testdatapath, param[i].name, &status);
289        /*theBundle = ures_open("c:\\icu\\icu\\source\\test\\testdata\\testdata", param[i].name, &status);*/
290
291        CONFIRM_ErrorCode(status,param[i].expected_constructor_status);
292
293
294
295        if(i == 5)
296            actual_bundle = 0; /* ne -> default */
297        else if(i == 3)
298            actual_bundle = 1; /* te_NE -> te */
299        else if(i == 4)
300            actual_bundle = 2; /* te_IN_NE -> te_IN */
301        else
302            actual_bundle = i;
303
304        expected_resource_status = U_MISSING_RESOURCE_ERROR;
305        for (j=e_te_IN; j>=e_Root; --j)
306        {
307            if (is_in[j] && param[i].inherits[j])
308            {
309
310                if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */
311                    expected_resource_status = U_ZERO_ERROR;
312                else if(j == 0)
313                    expected_resource_status = U_USING_DEFAULT_WARNING;
314                else
315                    expected_resource_status = U_USING_FALLBACK_WARNING;
316
317                log_verbose("%s[%d]::%s: in<%d:%s> inherits<%d:%s>.  actual_bundle=%s\n",
318                            param[i].name,
319                            i,
320                            frag,
321                            j,
322                            is_in[j]?"Yes":"No",
323                            j,
324                            param[i].inherits[j]?"Yes":"No",
325                            param[actual_bundle].name);
326
327                break;
328            }
329        }
330
331        for (j=param[i].where; j>=0; --j)
332        {
333            if (is_in[j])
334            {
335                if(base != NULL) {
336                    free(base);
337                    base = NULL;
338                }
339
340                base=(UChar*)malloc(sizeof(UChar)*(strlen(NAME[j]) + 1));
341                u_uastrcpy(base,NAME[j]);
342
343                break;
344            }
345            else {
346                if(base != NULL) {
347                    free(base);
348                    base = NULL;
349                }
350                base = (UChar*) malloc(sizeof(UChar) * 1);
351                *base = 0x0000;
352            }
353        }
354
355        /*-------------------------------------------------------------------- */
356        /* string */
357
358        strcpy(tag,"string_");
359        strcat(tag,frag);
360
361        strcpy(action,param[i].name);
362        strcat(action, ".ures_get(" );
363        strcat(action,tag);
364        strcat(action, ")");
365
366        string=    kERROR;
367
368        status = U_ZERO_ERROR;
369
370        ures_getStringByKey(theBundle, tag, &resultLen, &status);
371        if(U_SUCCESS(status))
372        {
373            status = U_ZERO_ERROR;
374            string=ures_getStringByKey(theBundle, tag, &resultLen, &status);
375        }
376
377        log_verbose("%s got %d, expected %d\n", action, status, expected_resource_status);
378
379        CONFIRM_ErrorCode(status, expected_resource_status);
380
381
382        if(U_SUCCESS(status)){
383            expected_string=(UChar*)malloc(sizeof(UChar)*(u_strlen(base) + 3));
384            u_strcpy(expected_string,base);
385
386        }
387        else
388        {
389            expected_string = (UChar*)malloc(sizeof(UChar)*(u_strlen(kERROR) + 1));
390            u_strcpy(expected_string,kERROR);
391
392        }
393
394        CONFIRM_EQ(string, expected_string);
395
396        free(expected_string);
397        ures_close(theBundle);
398    }
399    free(base);
400    return (UBool)(passNum == pass);
401}
402
403void record_pass()
404{
405  ++pass;
406}
407
408void record_fail()
409{
410  ++fail;
411}
412
413/**
414 * Test to make sure that the U_USING_FALLBACK_ERROR and U_USING_DEFAULT_ERROR
415 * are set correctly
416 */
417
418static void TestFallback()
419{
420    UErrorCode status = U_ZERO_ERROR;
421    UResourceBundle *fr_FR = NULL;
422    UResourceBundle *subResource = NULL;
423    const UChar *junk; /* ignored */
424    int32_t resultLen;
425
426    log_verbose("Opening fr_FR..");
427    fr_FR = ures_open(NULL, "fr_FR", &status);
428    if(U_FAILURE(status))
429    {
430        log_err_status(status, "Couldn't open fr_FR - %s\n", u_errorName(status));
431        return;
432    }
433
434    status = U_ZERO_ERROR;
435
436
437    /* clear it out..  just do some calls to get the gears turning */
438    junk = ures_getStringByKey(fr_FR, "LocaleID", &resultLen, &status);
439    (void)junk;    /* Suppress set but not used warning. */
440    status = U_ZERO_ERROR;
441    junk = ures_getStringByKey(fr_FR, "LocaleString", &resultLen, &status);
442    status = U_ZERO_ERROR;
443    junk = ures_getStringByKey(fr_FR, "LocaleID", &resultLen, &status);
444    status = U_ZERO_ERROR;
445
446    /* OK first one. This should be a Default value. */
447    subResource = ures_getByKey(fr_FR, "layout", NULL, &status);
448    if(status != U_USING_DEFAULT_WARNING)
449    {
450        log_data_err("Expected U_USING_DEFAULT_ERROR when trying to get layout from fr_FR, got %s\n",
451            u_errorName(status));
452    }
453    ures_close(subResource);
454    status = U_ZERO_ERROR;
455
456    /* and this is a Fallback, to fr */
457    junk = ures_getStringByKey(fr_FR, "ExemplarCharacters", &resultLen, &status);
458    if(status != U_USING_FALLBACK_WARNING)
459    {
460        log_data_err("Expected U_USING_FALLBACK_ERROR when trying to get ExemplarCharacters from fr_FR, got %s\n",
461            u_errorName(status));
462    }
463
464    status = U_ZERO_ERROR;
465
466    ures_close(fr_FR);
467}
468
469static void
470TestOpenDirect(void) {
471    UResourceBundle *idna_rules, *casing, *te_IN, *ne, *item;
472    UErrorCode errorCode;
473
474    /*
475     * test that ures_openDirect() opens a resource bundle
476     * where one can look up its own items but not fallback items
477     * from root or similar
478     */
479    errorCode=U_ZERO_ERROR;
480    idna_rules=ures_openDirect(loadTestData(&errorCode), "idna_rules", &errorCode);
481    if(U_FAILURE(errorCode)) {
482        log_data_err("ures_openDirect(\"idna_rules\") failed: %s\n", u_errorName(errorCode));
483        return;
484    }
485
486    if(0!=uprv_strcmp("idna_rules", ures_getLocale(idna_rules, &errorCode))) {
487        log_err("ures_openDirect(\"idna_rules\").getLocale()!=idna_rules\n");
488    }
489    errorCode=U_ZERO_ERROR;
490
491    /* try an item in idna_rules, must work */
492    item=ures_getByKey(idna_rules, "UnassignedSet", NULL, &errorCode);
493    if(U_FAILURE(errorCode)) {
494        log_err("translit_index.getByKey(local key) failed: %s\n", u_errorName(errorCode));
495        errorCode=U_ZERO_ERROR;
496    } else {
497        ures_close(item);
498    }
499
500    /* try an item in root, must fail */
501    item=ures_getByKey(idna_rules, "ShortLanguage", NULL, &errorCode);
502    if(U_FAILURE(errorCode)) {
503        errorCode=U_ZERO_ERROR;
504    } else {
505        log_err("idna_rules.getByKey(root key) succeeded!\n");
506        ures_close(item);
507    }
508    ures_close(idna_rules);
509
510    /* now make sure that "idna_rules" will not work with ures_open() */
511    errorCode=U_ZERO_ERROR;
512    idna_rules=ures_open("testdata", "idna_rules", &errorCode);
513    if(U_FAILURE(errorCode) || errorCode==U_USING_DEFAULT_WARNING || errorCode==U_USING_FALLBACK_WARNING) {
514        /* falling back to default or root is ok */
515        errorCode=U_ZERO_ERROR;
516    } else if(0!=uprv_strcmp("idna_rules", ures_getLocale(idna_rules, &errorCode))) {
517        /* Opening this file will work in "files mode" on Windows and the Mac,
518           which have case insensitive file systems */
519        log_err("ures_open(\"idna_rules\") succeeded, should fail! Got: %s\n", u_errorName(errorCode));
520    }
521    ures_close(idna_rules);
522
523    /* ures_openDirect("translit_index_WronG") must fail */
524    idna_rules=ures_openDirect(NULL, "idna_rules_WronG", &errorCode);
525    if(U_FAILURE(errorCode)) {
526        errorCode=U_ZERO_ERROR;
527    } else {
528        log_err("ures_openDirect(\"idna_rules_WronG\") succeeded, should fail!\n");
529    }
530    ures_close(idna_rules);
531
532    errorCode = U_USING_FALLBACK_WARNING;;
533    idna_rules=ures_openDirect("testdata", "idna_rules", &errorCode);
534    if(U_FAILURE(errorCode)) {
535        log_data_err("ures_openDirect(\"idna_rules\") failed when U_USING_FALLBACK_WARNING was set prior to call: %s\n", u_errorName(errorCode));
536        return;
537    }
538    ures_close(idna_rules);
539
540    /*
541     * ICU 3.6 has new resource bundle syntax and data for bundles that do not
542     * participate in locale fallback. Now,
543     * - ures_open() works like ures_openDirect() on a bundle with a top-level
544     *   type of ":table(nofallback)" _if_ the bundle exists
545     * - ures_open() will continue to find a root bundle if the requested one
546     *   does not exist, unlike ures_openDirect()
547     *
548     * Test with a different bundle than above to avoid confusion in the cache.
549     */
550
551    /*
552     * verify that ures_open("casing"), which now has a nofallback declaration,
553     * does not enable fallbacks
554     */
555    errorCode=U_ZERO_ERROR;
556    casing=ures_open("testdata", "casing", &errorCode);
557    if(U_FAILURE(errorCode)) {
558        log_data_err("ures_open(\"casing\") failed: %s\n", u_errorName(errorCode));
559        return;
560    }
561
562    errorCode=U_ZERO_ERROR;
563    item=ures_getByKey(casing, "Info", NULL, &errorCode);
564    if(U_FAILURE(errorCode)) {
565        log_err("casing.getByKey(Info) failed - %s\n", u_errorName(errorCode));
566    } else {
567        ures_close(item);
568    }
569
570    errorCode=U_ZERO_ERROR;
571    item=ures_getByKey(casing, "ShortLanguage", NULL, &errorCode);
572    if(U_SUCCESS(errorCode)) {
573        log_err("casing.getByKey(root key) succeeded despite nofallback declaration - %s\n", u_errorName(errorCode));
574        ures_close(item);
575    }
576    ures_close(casing);
577
578    /*
579     * verify that ures_open("ne") finds the root bundle but
580     * ures_openDirect("ne") does not
581     */
582    errorCode=U_ZERO_ERROR;
583    ne=ures_open("testdata", "ne", &errorCode);
584    if(U_FAILURE(errorCode)) {
585        log_data_err("ures_open(\"ne\") failed (expected to get root): %s\n", u_errorName(errorCode));
586    }
587    if(errorCode!=U_USING_DEFAULT_WARNING || 0!=uprv_strcmp("root", ures_getLocale(ne, &errorCode))) {
588        log_err("ures_open(\"ne\") found something other than \"root\" - %s\n", u_errorName(errorCode));
589    }
590    ures_close(ne);
591
592    errorCode=U_ZERO_ERROR;
593    ne=ures_openDirect("testdata", "ne", &errorCode);
594    if(U_SUCCESS(errorCode)) {
595        log_data_err("ures_openDirect(\"ne\") succeeded unexpectedly\n");
596        ures_close(ne);
597    }
598
599    /* verify that ures_openDirect("te_IN") does not enable fallbacks */
600    errorCode=U_ZERO_ERROR;
601    te_IN=ures_openDirect("testdata", "te_IN", &errorCode);
602    if(U_FAILURE(errorCode)) {
603        log_data_err("ures_open(\"te_IN\") failed: %s\n", u_errorName(errorCode));
604        return;
605    }
606    errorCode=U_ZERO_ERROR;
607    item=ures_getByKey(te_IN, "ShortLanguage", NULL, &errorCode);
608    if(U_SUCCESS(errorCode)) {
609        log_err("te_IN.getByKey(root key) succeeded despite use of ures_openDirect() - %s\n", u_errorName(errorCode));
610        ures_close(item);
611    }
612    ures_close(te_IN);
613}
614
615static int32_t
616parseTable32Key(const char *key) {
617    int32_t number;
618    char c;
619
620    number=0;
621    while((c=*key++)!=0) {
622        number<<=1;
623        if(c=='1') {
624            number|=1;
625        }
626    }
627    return number;
628}
629
630static void
631TestTable32(void) {
632    static const struct {
633        const char *key;
634        int32_t number;
635    } testcases[]={
636        { "ooooooooooooooooo", 0 },
637        { "oooooooooooooooo1", 1 },
638        { "ooooooooooooooo1o", 2 },
639        { "oo11ooo1ooo11111o", 25150 },
640        { "oo11ooo1ooo111111", 25151 },
641        { "o1111111111111111", 65535 },
642        { "1oooooooooooooooo", 65536 },
643        { "1ooooooo11o11ooo1", 65969 },
644        { "1ooooooo11o11oo1o", 65970 },
645        { "1ooooooo111oo1111", 65999 }
646    };
647
648    /* ### TODO UResourceBundle staticItem={ 0 }; - need to know the size */
649    UResourceBundle *res, *item;
650    const UChar *s;
651    const char *key;
652    UErrorCode errorCode;
653    int32_t i, j, number, parsedNumber, length, count;
654
655    errorCode=U_ZERO_ERROR;
656    res=ures_open(loadTestData(&errorCode), "testtable32", &errorCode);
657    if(U_FAILURE(errorCode)) {
658        log_data_err("unable to open testdata/testtable32.res - %s\n", u_errorName(errorCode));
659        return;
660    }
661    if(ures_getType(res)!=URES_TABLE) {
662        log_data_err("testdata/testtable32.res has type %d instead of URES_TABLE\n", ures_getType(res));
663    }
664
665    count=ures_getSize(res);
666    if(count!=66000) {
667        log_err("testdata/testtable32.res should have 66000 entries but has %d\n", count);
668    }
669
670    /* get the items by index */
671    item=NULL;
672    for(i=0; i<count; ++i) {
673        item=ures_getByIndex(res, i, item, &errorCode);
674        if(U_FAILURE(errorCode)) {
675            log_err("unable to get item %d of %d in testdata/testtable32.res - %s\n",
676                    i, count, u_errorName(errorCode));
677            break;
678        }
679
680        key=ures_getKey(item);
681        parsedNumber=parseTable32Key(key);
682
683        switch(ures_getType(item)) {
684        case URES_STRING:
685            s=ures_getString(item, &length, &errorCode);
686            if(U_FAILURE(errorCode) || s==NULL) {
687                log_err("unable to access the string \"%s\" at %d in testdata/testtable32.res - %s\n",
688                        key, i, u_errorName(errorCode));
689                number=-1;
690            } else {
691                j=0;
692                U16_NEXT(s, j, length, number);
693            }
694            break;
695        case URES_INT:
696            number=ures_getInt(item, &errorCode);
697            if(U_FAILURE(errorCode)) {
698                log_err("unable to access the integer \"%s\" at %d in testdata/testtable32.res - %s\n",
699                        key, i, u_errorName(errorCode));
700                number=-1;
701            }
702            break;
703        default:
704            log_err("unexpected resource type %d for \"%s\" at %d in testdata/testtable32.res - %s\n",
705                    ures_getType(item), key, i, u_errorName(errorCode));
706            number=-1;
707            break;
708        }
709
710        if(number>=0 && number!=parsedNumber) {
711            log_err("\"%s\" at %d in testdata/testtable32.res has a string/int value of %d, expected %d\n",
712                    key, i, number, parsedNumber);
713        }
714    }
715
716    /* search for some items by key */
717    for(i=0; i<LENGTHOF(testcases); ++i) {
718        item=ures_getByKey(res, testcases[i].key, item, &errorCode);
719        if(U_FAILURE(errorCode)) {
720            log_err("unable to find the key \"%s\" in testdata/testtable32.res - %s\n",
721                    testcases[i].key, u_errorName(errorCode));
722            continue;
723        }
724
725        switch(ures_getType(item)) {
726        case URES_STRING:
727            s=ures_getString(item, &length, &errorCode);
728            if(U_FAILURE(errorCode) || s==NULL) {
729                log_err("unable to access the string \"%s\" in testdata/testtable32.res - %s\n",
730                        testcases[i].key, u_errorName(errorCode));
731                number=-1;
732            } else {
733                j=0;
734                U16_NEXT(s, j, length, number);
735            }
736            break;
737        case URES_INT:
738            number=ures_getInt(item, &errorCode);
739            if(U_FAILURE(errorCode)) {
740                log_err("unable to access the integer \"%s\" in testdata/testtable32.res - %s\n",
741                        testcases[i].key, u_errorName(errorCode));
742                number=-1;
743            }
744            break;
745        default:
746            log_err("unexpected resource type %d for \"%s\" in testdata/testtable32.res - %s\n",
747                    ures_getType(item), testcases[i].key, u_errorName(errorCode));
748            number=-1;
749            break;
750        }
751
752        if(number>=0 && number!=testcases[i].number) {
753            log_err("\"%s\" in testdata/testtable32.res has a string/int value of %d, expected %d\n",
754                    testcases[i].key, number, testcases[i].number);
755        }
756
757        key=ures_getKey(item);
758        if(0!=uprv_strcmp(key, testcases[i].key)) {
759            log_err("\"%s\" in testdata/testtable32.res claims to have the key \"%s\"\n",
760                    testcases[i].key, key);
761        }
762    }
763
764    ures_close(item);
765    ures_close(res);
766}
767
768static void TestFileStream(void){
769    int32_t c = 0;
770    int32_t c1=0;
771    UErrorCode status = U_ZERO_ERROR;
772    const char* testdatapath = loadTestData(&status);
773    char* fileName = (char*) malloc(uprv_strlen(testdatapath) +10);
774    FileStream* stream = NULL;
775    /* these should not be closed */
776    FileStream* pStdin  = T_FileStream_stdin();
777    FileStream* pStdout = T_FileStream_stdout();
778    FileStream* pStderr = T_FileStream_stderr();
779
780    const char* testline = "This is a test line";
781    int32_t bufLen = (int32_t)strlen(testline)+10;
782    char* buf = (char*) malloc(bufLen);
783    int32_t retLen = 0;
784
785    if(pStdin==NULL){
786        log_err("failed to get T_FileStream_stdin()");
787    }
788    if(pStdout==NULL){
789        log_err("failed to get T_FileStream_stdout()");
790    }
791    if(pStderr==NULL){
792        log_err("failed to get T_FileStream_stderr()");
793    }
794
795    uprv_strcpy(fileName,testdatapath);
796    uprv_strcat(fileName,".dat");
797    stream = T_FileStream_open(fileName, "r");
798    if(stream==NULL){
799        log_data_err("T_FileStream_open failed to open %s\n",fileName);
800    } else {
801      if(!T_FileStream_file_exists(fileName)){
802        log_data_err("T_FileStream_file_exists failed to verify existence of %s \n",fileName);
803      }
804
805      retLen=T_FileStream_read(stream,&c,1);
806      if(retLen==0){
807        log_data_err("T_FileStream_read failed to read from %s \n",fileName);
808      }
809      retLen=0;
810      T_FileStream_rewind(stream);
811      T_FileStream_read(stream,&c1,1);
812      if(c!=c1){
813        log_data_err("T_FileStream_rewind failed to rewind %s \n",fileName);
814      }
815      T_FileStream_rewind(stream);
816      c1 = T_FileStream_peek(stream);
817      if(c!=c1){
818        log_data_err("T_FileStream_peek failed to peekd %s \n",fileName);
819      }
820      c = T_FileStream_getc(stream);
821      T_FileStream_ungetc(c,stream);
822      if(c!= T_FileStream_getc(stream)){
823        log_data_err("T_FileStream_ungetc failed to d %s \n",fileName);
824      }
825
826      if(T_FileStream_size(stream)<=0){
827        log_data_err("T_FileStream_size failed to d %s \n",fileName);
828      }
829      if(T_FileStream_error(stream)){
830        log_data_err("T_FileStream_error shouldn't have an error %s\n",fileName);
831      }
832      if(!T_FileStream_error(NULL)){
833        log_err("T_FileStream_error didn't get an error %s\n",fileName);
834      }
835      T_FileStream_putc(stream, 0x20);
836      if(!T_FileStream_error(stream)){
837        /*
838          Warning
839          writing to a read-only file may not consistently fail on all platforms
840          (e.g. HP-UX, FreeBSD, MacOSX)
841        */
842        log_verbose("T_FileStream_error didn't get an error when writing to a readonly file %s\n",fileName);
843      }
844
845      T_FileStream_close(stream);
846    }
847    /* test writing function */
848    stream=NULL;
849    uprv_strcpy(fileName,testdatapath);
850    uprv_strcat(fileName,".tmp");
851    stream = T_FileStream_open(fileName,"w+");
852
853    if(stream == NULL){
854        log_data_err("Could not open %s for writing\n",fileName);
855    } else {
856      c= '$';
857      T_FileStream_putc(stream,c);
858      T_FileStream_rewind(stream);
859      if(c != T_FileStream_getc(stream)){
860        log_data_err("T_FileStream_putc failed %s\n",fileName);
861      }
862
863      T_FileStream_rewind(stream);
864      T_FileStream_writeLine(stream,testline);
865      T_FileStream_rewind(stream);
866      T_FileStream_readLine(stream,buf,bufLen);
867      if(uprv_strncmp(testline, buf,uprv_strlen(buf))!=0){
868        log_data_err("T_FileStream_writeLine failed %s\n",fileName);
869      }
870
871      T_FileStream_rewind(stream);
872      T_FileStream_write(stream,testline,(int32_t)strlen(testline));
873      T_FileStream_rewind(stream);
874      retLen = T_FileStream_read(stream, buf, bufLen);
875      if(uprv_strncmp(testline, buf,retLen)!=0){
876        log_data_err("T_FileStream_write failed %s\n",fileName);
877      }
878
879      T_FileStream_close(stream);
880    }
881    if(!T_FileStream_remove(fileName)){
882        log_data_err("T_FileStream_remove failed to delete %s\n",fileName);
883    }
884
885
886    free(fileName);
887    free(buf);
888
889}
890
891static void TestGetSize(void) {
892    const struct {
893        const char* key;
894        int32_t size;
895    } test[] = {
896        { "zerotest", 1},
897        { "one", 1},
898        { "importtest", 1},
899        { "integerarray", 1},
900        { "emptyarray", 0},
901        { "emptytable", 0},
902        { "emptystring", 1}, /* empty string is still a string */
903        { "emptyint", 1},
904        { "emptybin", 1},
905        { "testinclude", 1},
906        { "collations", 1}, /* not 2 - there is hidden %%CollationBin */
907    };
908
909    UErrorCode status = U_ZERO_ERROR;
910
911    UResourceBundle *rb = NULL;
912    UResourceBundle *res = NULL;
913    UResourceBundle *helper = NULL;
914    const char* testdatapath = loadTestData(&status);
915    int32_t i = 0, j = 0;
916    int32_t size = 0;
917
918    if(U_FAILURE(status))
919    {
920        log_data_err("Could not load testdata.dat %s\n", u_errorName(status));
921        return;
922    }
923
924    rb = ures_open(testdatapath, "testtypes", &status);
925    if(U_FAILURE(status))
926    {
927        log_err("Could not testtypes resource bundle %s\n", u_errorName(status));
928        return;
929    }
930
931    for(i = 0; i < sizeof(test)/sizeof(test[0]); i++) {
932        res = ures_getByKey(rb, test[i].key, res, &status);
933        if(U_FAILURE(status))
934        {
935            log_err("Couldn't find the key %s. Error: %s\n", test[i].key, u_errorName(status));
936            ures_close(rb);
937            return;
938        }
939        size = ures_getSize(res);
940        if(size != test[i].size) {
941            log_err("Expected size %i, got size %i for key %s\n", test[i].size, size, test[i].key);
942            for(j = 0; j < size; j++) {
943                helper = ures_getByIndex(res, j, helper, &status);
944                log_err("%s\n", ures_getKey(helper));
945            }
946        }
947    }
948    ures_close(helper);
949    ures_close(res);
950    ures_close(rb);
951}
952
953static void TestGetLocaleByType(void) {
954    static const struct {
955        const char *requestedLocale;
956        const char *resourceKey;
957        const char *validLocale;
958        const char *actualLocale;
959    } test[] = {
960        { "te_IN_BLAH", "string_only_in_te_IN", "te_IN", "te_IN" },
961        { "te_IN_BLAH", "string_only_in_te", "te_IN", "te" },
962        { "te_IN_BLAH", "string_only_in_Root", "te_IN", "root" },
963        { "te_IN_BLAH_01234567890_01234567890_01234567890_01234567890_01234567890_01234567890", "array_2d_only_in_Root", "te_IN", "root" },
964        { "te_IN_BLAH@currency=euro", "array_2d_only_in_te_IN", "te_IN", "te_IN" },
965        { "te_IN_BLAH@collation=phonebook;calendar=thai", "array_2d_only_in_te", "te_IN", "te" }
966    };
967
968    UErrorCode status = U_ZERO_ERROR;
969
970    UResourceBundle *rb = NULL;
971    UResourceBundle *res = NULL;
972    const char* testdatapath = loadTestData(&status);
973    int32_t i = 0;
974    const char *locale = NULL;
975
976    if(U_FAILURE(status))
977    {
978        log_data_err("Could not load testdata.dat %s\n", u_errorName(status));
979        return;
980    }
981
982    for(i = 0; i < sizeof(test)/sizeof(test[0]); i++) {
983        rb = ures_open(testdatapath, test[i].requestedLocale, &status);
984        if(U_FAILURE(status))
985        {
986            log_err("Could not open resource bundle %s (error %s)\n", test[i].requestedLocale, u_errorName(status));
987            status = U_ZERO_ERROR;
988            continue;
989        }
990
991        res = ures_getByKey(rb, test[i].resourceKey, res, &status);
992        if(U_FAILURE(status))
993        {
994            log_err("Couldn't find the key %s. Error: %s\n", test[i].resourceKey, u_errorName(status));
995            ures_close(rb);
996            status = U_ZERO_ERROR;
997            continue;
998        }
999
1000        locale = ures_getLocaleByType(res, ULOC_REQUESTED_LOCALE, &status);
1001        if(locale) {
1002            log_err("Requested locale should return NULL\n");
1003        }
1004        locale = ures_getLocaleByType(res, ULOC_VALID_LOCALE, &status);
1005        if(!locale || strcmp(locale, test[i].validLocale) != 0) {
1006            log_err("Expected valid locale to be %s. Got %s\n", test[i].requestedLocale, locale);
1007        }
1008        locale = ures_getLocaleByType(res, ULOC_ACTUAL_LOCALE, &status);
1009        if(!locale || strcmp(locale, test[i].actualLocale) != 0) {
1010            log_err("Expected actual locale to be %s. Got %s\n", test[i].requestedLocale, locale);
1011        }
1012        ures_close(rb);
1013    }
1014    ures_close(res);
1015}
1016
1017