1/********************************************************************
2 * Copyright (c) 1997-2009, International Business Machines
3 * Corporation and others. All Rights Reserved.
4 ********************************************************************/
5
6#include "unicode/utypes.h"
7
8#include "cstring.h"
9#include "unicode/unistr.h"
10#include "unicode/resbund.h"
11#include "restsnew.h"
12
13#include <stdlib.h>
14#include <time.h>
15#include <string.h>
16#include <limits.h>
17
18//***************************************************************************************
19
20static const UChar kErrorUChars[] = { 0x45, 0x52, 0x52, 0x4f, 0x52, 0 };
21static const int32_t kErrorLength = 5;
22static const int32_t kERROR_COUNT = -1234567;
23
24//***************************************************************************************
25
26enum E_Where
27{
28    e_Root,
29    e_te,
30    e_te_IN,
31    e_Where_count
32};
33
34//***************************************************************************************
35
36#define CONFIRM_EQ(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of " + (expected)); }
37#define CONFIRM_GE(actual,expected) if ((actual)>=(expected)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x >= " + (expected)); }
38#define CONFIRM_NE(actual,expected) if ((expected)!=(actual)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (actual) + (UnicodeString)" instead of x != " + (expected)); }
39
40#define CONFIRM_UErrorCode(actual,expected) if ((expected)==(actual)) { record_pass(); } else { record_fail(); errln(action + (UnicodeString)" returned " + (UnicodeString)u_errorName(actual) + (UnicodeString)" instead of " + (UnicodeString)u_errorName(expected)); }
41
42//***************************************************************************************
43
44/**
45 * Convert an integer, positive or negative, to a character string radix 10.
46 */
47static char*
48itoa(int32_t i, char* buf)
49{
50    char* result = buf;
51
52    // Handle negative
53    if (i < 0)
54    {
55        *buf++ = '-';
56        i = -i;
57    }
58
59    // Output digits in reverse order
60    char* p = buf;
61    do
62    {
63        *p++ = (char)('0' + (i % 10));
64        i /= 10;
65    }
66    while (i);
67    *p-- = 0;
68
69    // Reverse the string
70    while (buf < p)
71    {
72        char c = *buf;
73        *buf++ = *p;
74        *p-- = c;
75    }
76
77    return result;
78}
79
80
81
82//***************************************************************************************
83
84// Array of our test objects
85
86static struct
87{
88    const char* name;
89    Locale *locale;
90    UErrorCode expected_constructor_status;
91    E_Where where;
92    UBool like[e_Where_count];
93    UBool inherits[e_Where_count];
94}
95param[] =
96{
97    // "te" means test
98    // "IN" means inherits
99    // "NE" or "ne" means "does not exist"
100
101    { "root",       0,   U_ZERO_ERROR,             e_Root,      { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } },
102    { "te",         0,   U_ZERO_ERROR,             e_te,        { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE  } },
103    { "te_IN",      0,   U_ZERO_ERROR,             e_te_IN,     { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE   } },
104    { "te_NE",      0,   U_USING_FALLBACK_WARNING, e_te,        { FALSE, TRUE, FALSE }, { TRUE, TRUE, FALSE  } },
105    { "te_IN_NE",   0,   U_USING_FALLBACK_WARNING, e_te_IN,     { FALSE, FALSE, TRUE }, { TRUE, TRUE, TRUE   } },
106    { "ne",         0,   U_USING_DEFAULT_WARNING,  e_Root,      { TRUE, FALSE, FALSE }, { TRUE, FALSE, FALSE } }
107};
108
109static int32_t bundles_count = sizeof(param) / sizeof(param[0]);
110
111//***************************************************************************************
112
113/**
114 * Return a random unsigned long l where 0N <= l <= ULONG_MAX.
115 */
116
117static uint32_t
118randul()
119{
120    static UBool initialized = FALSE;
121    if (!initialized)
122    {
123        srand((unsigned)time(NULL));
124        initialized = TRUE;
125    }
126    // Assume rand has at least 12 bits of precision
127    uint32_t l = 0;
128    for (uint32_t i=0; i<sizeof(l); ++i)
129        ((char*)&l)[i] = (char)((rand() & 0x0FF0) >> 4);
130    return l;
131}
132
133/**
134 * Return a random double x where 0.0 <= x < 1.0.
135 */
136static double
137randd()
138{
139    return (double)(randul() / ULONG_MAX);
140}
141
142/**
143 * Return a random integer i where 0 <= i < n.
144 */
145static int32_t randi(int32_t n)
146{
147    return (int32_t)(randd() * n);
148}
149
150//***************************************************************************************
151
152/*
153 Don't use more than one of these at a time because of the Locale names
154*/
155NewResourceBundleTest::NewResourceBundleTest()
156: pass(0),
157  fail(0)
158{
159    if (param[5].locale == NULL) {
160        param[0].locale = new Locale("root");
161        param[1].locale = new Locale("te");
162        param[2].locale = new Locale("te", "IN");
163        param[3].locale = new Locale("te", "NE");
164        param[4].locale = new Locale("te", "IN", "NE");
165        param[5].locale = new Locale("ne");
166    }
167}
168
169NewResourceBundleTest::~NewResourceBundleTest()
170{
171    if (param[5].locale) {
172        int idx;
173        for (idx = 0; idx < (int)(sizeof(param)/sizeof(param[0])); idx++) {
174            delete param[idx].locale;
175            param[idx].locale = NULL;
176        }
177    }
178}
179
180void NewResourceBundleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char* /*par*/ )
181{
182    if (exec) logln("TestSuite ResourceBundleTest: ");
183    switch (index) {
184    case 0: name = "TestResourceBundles"; if (exec) TestResourceBundles(); break;
185    case 1: name = "TestConstruction"; if (exec) TestConstruction(); break;
186    case 2: name = "TestIteration"; if (exec) TestIteration(); break;
187    case 3: name = "TestOtherAPI";  if(exec) TestOtherAPI(); break;
188    case 4: name = "TestNewTypes";  if(exec) TestNewTypes(); break;
189    case 5: name = "TestGetByFallback";  if(exec) TestGetByFallback(); break;
190        default: name = ""; break; //needed to end loop
191    }
192}
193
194//***************************************************************************************
195
196void
197NewResourceBundleTest::TestResourceBundles()
198{
199    UErrorCode status = U_ZERO_ERROR;
200    loadTestData(status);
201    if(U_FAILURE(status))
202    {
203        dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(status)));
204        return;
205    }
206
207    /* Make sure that users using te_IN for the default locale don't get test failures. */
208    Locale originalDefault;
209    if (Locale::getDefault() == Locale("te_IN")) {
210        Locale::setDefault(Locale("en_US"), status);
211    }
212
213    testTag("only_in_Root", TRUE, FALSE, FALSE);
214    testTag("only_in_te", FALSE, TRUE, FALSE);
215    testTag("only_in_te_IN", FALSE, FALSE, TRUE);
216    testTag("in_Root_te", TRUE, TRUE, FALSE);
217    testTag("in_Root_te_te_IN", TRUE, TRUE, TRUE);
218    testTag("in_Root_te_IN", TRUE, FALSE, TRUE);
219    testTag("in_te_te_IN", FALSE, TRUE, TRUE);
220    testTag("nonexistent", FALSE, FALSE, FALSE);
221    logln("Passed: %d\nFailed: %d", pass, fail);
222
223    /* Restore the default locale for the other tests. */
224    Locale::setDefault(originalDefault, status);
225}
226
227void
228NewResourceBundleTest::TestConstruction()
229{
230    UErrorCode   err = U_ZERO_ERROR;
231    Locale       locale("te", "IN");
232
233    const char* testdatapath;
234    testdatapath=loadTestData(err);
235    if(U_FAILURE(err))
236    {
237        dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(err)));
238        return;
239    }
240
241    /* Make sure that users using te_IN for the default locale don't get test failures. */
242    Locale originalDefault;
243    if (Locale::getDefault() == Locale("te_IN")) {
244        Locale::setDefault(Locale("en_US"), err);
245    }
246
247    ResourceBundle  test1((UnicodeString)testdatapath, err);
248    ResourceBundle  test2(testdatapath, locale, err);
249
250    UnicodeString   result1;
251    UnicodeString   result2;
252
253    result1 = test1.getStringEx("string_in_Root_te_te_IN", err);
254    result2 = test2.getStringEx("string_in_Root_te_te_IN", err);
255    if (U_FAILURE(err)) {
256        errln("Something threw an error in TestConstruction()");
257        return;
258    }
259
260    logln("for string_in_Root_te_te_IN, root.txt had " + result1);
261    logln("for string_in_Root_te_te_IN, te_IN.txt had " + result2);
262
263    if (result1 != "ROOT" || result2 != "TE_IN") {
264        errln("Construction test failed; run verbose for more information");
265    }
266
267    const char* version1;
268    const char* version2;
269
270    version1 = test1.getVersionNumber();
271    version2 = test2.getVersionNumber();
272
273    char *versionID1 = new char[1 + strlen(U_ICU_VERSION) + strlen(version1)]; // + 1 for zero byte
274    char *versionID2 = new char[1 + strlen(U_ICU_VERSION) + strlen(version2)]; // + 1 for zero byte
275
276    strcpy(versionID1, "44.0");  // hardcoded, please change if the default.txt file or ResourceBundle::kVersionSeparater is changed.
277
278    strcpy(versionID2, "55.0");  // hardcoded, please change if the te_IN.txt file or ResourceBundle::kVersionSeparater is changed.
279
280    logln(UnicodeString("getVersionNumber on default.txt returned ") + version1 + UnicodeString(" Expect: " ) + versionID1);
281    logln(UnicodeString("getVersionNumber on te_IN.txt returned ") + version2 + UnicodeString(" Expect: " ) + versionID2);
282
283    if (strcmp(version1, versionID1) != 0) {
284        errln("getVersionNumber(version1) failed. %s != %s", version1, versionID1);
285    }
286    if (strcmp(version2, versionID2) != 0) {
287        errln("getVersionNumber(version2) failed. %s != %s", version2, versionID2);
288    }
289    delete[] versionID1;
290    delete[] versionID2;
291
292    /* Restore the default locale for the other tests. */
293    Locale::setDefault(originalDefault, err);
294}
295
296void
297NewResourceBundleTest::TestIteration()
298{
299    UErrorCode   err = U_ZERO_ERROR;
300    const char* testdatapath;
301    const char* data[]={
302        "string_in_Root_te_te_IN",   "1",
303        "array_in_Root_te_te_IN",    "5",
304        "array_2d_in_Root_te_te_IN", "4",
305    };
306
307    Locale       *locale=new Locale("te_IN");
308
309    testdatapath=loadTestData(err);
310    if(U_FAILURE(err))
311    {
312        dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(err)));
313        return;
314    }
315
316    ResourceBundle  test1(testdatapath, *locale, err);
317    if(U_FAILURE(err)){
318        errln("Construction failed");
319    }
320    uint32_t i;
321    int32_t count, row=0, col=0;
322    char buf[5];
323    UnicodeString expected;
324    UnicodeString element("TE_IN");
325    UnicodeString action;
326
327
328    for(i=0; i<sizeof(data)/sizeof(data[0]); i=i+2){
329        action = "te_IN";
330        action +=".get(";
331        action += data[i];
332        action +=", err)";
333        err=U_ZERO_ERROR;
334        ResourceBundle bundle = test1.get(data[i], err);
335        if(!U_FAILURE(err)){
336            action = "te_IN";
337            action +=".getKey()";
338
339            CONFIRM_EQ((UnicodeString)bundle.getKey(), (UnicodeString)data[i]);
340
341            count=0;
342            row=0;
343            while(bundle.hasNext()){
344                action = data[i];
345                action +=".getNextString(err)";
346                row=count;
347                UnicodeString got=bundle.getNextString(err);
348                if(U_SUCCESS(err)){
349                    expected=element;
350                    if(bundle.getSize() > 1){
351                        CONFIRM_EQ(bundle.getType(), URES_ARRAY);
352                        expected+=itoa(row, buf);
353                        ResourceBundle rowbundle=bundle.get(row, err);
354                        if(!U_FAILURE(err) && rowbundle.getSize()>1){
355                            col=0;
356                            while(rowbundle.hasNext()){
357                                expected=element;
358                                got=rowbundle.getNextString(err);
359                                if(!U_FAILURE(err)){
360                                    expected+=itoa(row, buf);
361                                    expected+=itoa(col, buf);
362                                    col++;
363                                    CONFIRM_EQ(got, expected);
364                                }
365                            }
366                            CONFIRM_EQ(col, rowbundle.getSize());
367                        }
368                    }
369                    else{
370                        CONFIRM_EQ(bundle.getType(), (int32_t)URES_STRING);
371                    }
372                }
373                CONFIRM_EQ(got, expected);
374                count++;
375            }
376            action = data[i];
377            action +=".getSize()";
378            CONFIRM_EQ(bundle.getSize(), count);
379            CONFIRM_EQ(count, atoi(data[i+1]));
380            //after reaching the end
381            err=U_ZERO_ERROR;
382            ResourceBundle errbundle=bundle.getNext(err);
383            action = "After reaching the end of the Iterator:-  ";
384            action +=data[i];
385            action +=".getNext()";
386            CONFIRM_NE(err, (int32_t)U_ZERO_ERROR);
387            CONFIRM_EQ(u_errorName(err), u_errorName(U_INDEX_OUTOFBOUNDS_ERROR));
388            //reset the iterator
389            err = U_ZERO_ERROR;
390            bundle.resetIterator();
391         /*  The following code is causing a crash
392         ****CRASH******
393         */
394
395            bundle.getNext(err);
396            if(U_FAILURE(err)){
397                errln("ERROR: getNext()  throw an error");
398            }
399        }
400    }
401    delete locale;
402}
403
404// TODO: add operator== and != to ResourceBundle
405static UBool
406equalRB(ResourceBundle &a, ResourceBundle &b) {
407    UResType type;
408    UErrorCode status;
409
410    type=a.getType();
411    status=U_ZERO_ERROR;
412    return
413        type==b.getType() &&
414        a.getLocale()==b.getLocale() &&
415        0==strcmp(a.getName(), b.getName()) &&
416        type==URES_STRING ?
417            a.getString(status)==b.getString(status) :
418            type==URES_INT ?
419                a.getInt(status)==b.getInt(status) :
420                TRUE;
421}
422
423void
424NewResourceBundleTest::TestOtherAPI(){
425    UErrorCode   err = U_ZERO_ERROR;
426    const char* testdatapath=loadTestData(err);
427    UnicodeString tDataPathUS = UnicodeString(testdatapath, "");
428
429    if(U_FAILURE(err))
430    {
431        dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(err)));
432        return;
433    }
434
435    /* Make sure that users using te_IN for the default locale don't get test failures. */
436    Locale originalDefault;
437    if (Locale::getDefault() == Locale("te_IN")) {
438        Locale::setDefault(Locale("en_US"), err);
439    }
440
441    Locale       *locale=new Locale("te_IN");
442
443    ResourceBundle test0(tDataPathUS, *locale, err);
444    if(U_FAILURE(err)){
445        errln("Construction failed");
446        return;
447    }
448
449    ResourceBundle  test1(testdatapath, *locale, err);
450    if(U_FAILURE(err)){
451        errln("Construction failed");
452        return;
453    }
454
455    logln("Testing getLocale()\n");
456    if(strcmp(test1.getLocale().getName(), locale->getName()) !=0 ){
457        errln("FAIL: ResourceBundle::getLocale() failed\n");
458    }
459
460    delete locale;
461
462    logln("Testing ResourceBundle(UErrorCode)\n");
463    ResourceBundle defaultresource(err);
464    ResourceBundle explicitdefaultresource(NULL, Locale::getDefault(), err);
465    if(U_FAILURE(err)){
466        errcheckln(err, "Construction of default resourcebundle failed - %s", u_errorName(err));
467        return;
468    }
469    // You can't compare the default locale to the resolved locale in the
470    // resource bundle due to aliasing, keywords in the default locale
471    // or the chance that the machine running these tests is using a locale
472    // that isn't available in ICU.
473    if(strcmp(defaultresource.getLocale().getName(), explicitdefaultresource.getLocale().getName()) != 0){
474        errln("Construction of default resourcebundle didn't take the defaultlocale. Expected %s Got %s err=%s\n",
475            explicitdefaultresource.getLocale().getName(), defaultresource.getLocale().getName(), u_errorName(err));
476    }
477
478
479    ResourceBundle copyRes(defaultresource);
480    if(strcmp(copyRes.getName(), defaultresource.getName() ) !=0  ||
481        strcmp(test1.getName(), defaultresource.getName() ) ==0 ||
482        strcmp(copyRes.getLocale().getName(), defaultresource.getLocale().getName() ) !=0  ||
483        strcmp(test1.getLocale().getName(), defaultresource.getLocale().getName() ) ==0 )
484    {
485        errln("copy construction failed\n");
486    }
487
488    ResourceBundle defaultSub = defaultresource.get((int32_t)0, err);
489    ResourceBundle defSubCopy(defaultSub);
490    if(strcmp(defSubCopy.getName(), defaultSub.getName() ) !=0  ||
491        strcmp(defSubCopy.getLocale().getName(), defaultSub.getLocale().getName() ) !=0  ){
492        errln("copy construction for subresource failed\n");
493    }
494
495    ResourceBundle *p;
496
497    p = defaultresource.clone();
498    if(p == &defaultresource || !equalRB(*p, defaultresource)) {
499        errln("ResourceBundle.clone() failed");
500    }
501    delete p;
502
503    p = defaultSub.clone();
504    if(p == &defaultSub || !equalRB(*p, defaultSub)) {
505        errln("2nd ResourceBundle.clone() failed");
506    }
507    delete p;
508
509    UVersionInfo ver;
510    copyRes.getVersion(ver);
511
512    logln("Version returned: [%d.%d.%d.%d]\n", ver[0], ver[1], ver[2], ver[3]);
513
514    logln("Testing C like UnicodeString APIs\n");
515
516    UResourceBundle *testCAPI = NULL, *bundle = NULL, *rowbundle = NULL, *temp = NULL;
517    err = U_ZERO_ERROR;
518    const char* data[]={
519        "string_in_Root_te_te_IN",   "1",
520        "array_in_Root_te_te_IN",    "5",
521        "array_2d_in_Root_te_te_IN", "4",
522    };
523
524
525    testCAPI = ures_open(testdatapath, "te_IN", &err);
526
527    if(U_SUCCESS(err)) {
528        // Do the testing
529        // first iteration
530
531        uint32_t i;
532        int32_t count, row=0, col=0;
533        char buf[5];
534        UnicodeString expected;
535        UnicodeString element("TE_IN");
536        UnicodeString action;
537
538
539        for(i=0; i<sizeof(data)/sizeof(data[0]); i=i+2){
540            action = "te_IN";
541            action +=".get(";
542            action += data[i];
543            action +=", err)";
544            err=U_ZERO_ERROR;
545            bundle = ures_getByKey(testCAPI, data[i], bundle, &err);
546            if(!U_FAILURE(err)){
547                const char* key = NULL;
548                action = "te_IN";
549                action +=".getKey()";
550
551                CONFIRM_EQ((UnicodeString)ures_getKey(bundle), (UnicodeString)data[i]);
552
553                count=0;
554                row=0;
555                while(ures_hasNext(bundle)){
556                    action = data[i];
557                    action +=".getNextString(err)";
558                    row=count;
559                    UnicodeString got=ures_getNextUnicodeString(bundle, &key, &err);
560                    if(U_SUCCESS(err)){
561                        expected=element;
562                        if(ures_getSize(bundle) > 1){
563                            CONFIRM_EQ(ures_getType(bundle), URES_ARRAY);
564                            expected+=itoa(row, buf);
565                            rowbundle=ures_getByIndex(bundle, row, rowbundle, &err);
566                            if(!U_FAILURE(err) && ures_getSize(rowbundle)>1){
567                                col=0;
568                                while(ures_hasNext(rowbundle)){
569                                    expected=element;
570                                    got=ures_getNextUnicodeString(rowbundle, &key, &err);
571                                    temp = ures_getByIndex(rowbundle, col, temp, &err);
572                                    UnicodeString bla = ures_getUnicodeString(temp, &err);
573                                    UnicodeString bla2 = ures_getUnicodeStringByIndex(rowbundle, col, &err);
574                                    if(!U_FAILURE(err)){
575                                        expected+=itoa(row, buf);
576                                        expected+=itoa(col, buf);
577                                        col++;
578                                        CONFIRM_EQ(got, expected);
579                                        CONFIRM_EQ(bla, expected);
580                                        CONFIRM_EQ(bla2, expected);
581                                    }
582                                }
583                                CONFIRM_EQ(col, ures_getSize(rowbundle));
584                            }
585                        }
586                        else{
587                            CONFIRM_EQ(ures_getType(bundle), (int32_t)URES_STRING);
588                        }
589                    }
590                    CONFIRM_EQ(got, expected);
591                    count++;
592                }
593            }
594        }
595        ures_close(temp);
596        ures_close(rowbundle);
597        ures_close(bundle);
598        ures_close(testCAPI);
599    } else {
600        errln("failed to open a resource bundle\n");
601    }
602
603    /* Restore the default locale for the other tests. */
604    Locale::setDefault(originalDefault, err);
605}
606
607
608
609
610//***************************************************************************************
611
612UBool
613NewResourceBundleTest::testTag(const char* frag,
614                            UBool in_Root,
615                            UBool in_te,
616                            UBool in_te_IN)
617{
618    int32_t failOrig = fail;
619
620    // Make array from input params
621
622    UBool is_in[] = { in_Root, in_te, in_te_IN };
623
624    const char* NAME[] = { "ROOT", "TE", "TE_IN" };
625
626    // Now try to load the desired items
627
628    char tag[100];
629    UnicodeString action;
630
631    int32_t i,j,row,col, actual_bundle;
632    int32_t index;
633    const char* testdatapath;
634
635    UErrorCode status = U_ZERO_ERROR;
636    testdatapath=loadTestData(status);
637    if(U_FAILURE(status))
638    {
639        dataerrln("Could not load testdata.dat %s " + UnicodeString(u_errorName(status)));
640        return FALSE;
641    }
642
643    for (i=0; i<bundles_count; ++i)
644    {
645        action = "Constructor for ";
646        action += param[i].name;
647
648        status = U_ZERO_ERROR;
649        ResourceBundle theBundle( testdatapath, *param[i].locale, status);
650        //ResourceBundle theBundle( "c:\\icu\\icu\\source\\test\\testdata\\testdata", *param[i].locale, status);
651        CONFIRM_UErrorCode(status,param[i].expected_constructor_status);
652
653        if(i == 5)
654          actual_bundle = 0; /* ne -> default */
655        else if(i == 3)
656          actual_bundle = 1; /* te_NE -> te */
657        else if(i == 4)
658          actual_bundle = 2; /* te_IN_NE -> te_IN */
659        else
660          actual_bundle = i;
661
662
663        UErrorCode expected_resource_status = U_MISSING_RESOURCE_ERROR;
664        for (j=e_te_IN; j>=e_Root; --j)
665        {
666            if (is_in[j] && param[i].inherits[j])
667              {
668                if(j == actual_bundle) /* it's in the same bundle OR it's a nonexistent=default bundle (5) */
669                  expected_resource_status = U_ZERO_ERROR;
670                else if(j == 0)
671                  expected_resource_status = U_USING_DEFAULT_WARNING;
672                else
673                  expected_resource_status = U_USING_FALLBACK_WARNING;
674
675                break;
676            }
677        }
678
679        UErrorCode expected_status;
680
681        UnicodeString base;
682        for (j=param[i].where; j>=0; --j)
683        {
684            if (is_in[j])
685            {
686                base = NAME[j];
687                break;
688            }
689        }
690
691        //--------------------------------------------------------------------------
692        // string
693
694        uprv_strcpy(tag, "string_");
695        uprv_strcat(tag, frag);
696
697        action = param[i].name;
698        action += ".getStringEx(";
699        action += tag;
700        action += ")";
701
702
703        status = U_ZERO_ERROR;
704        UnicodeString string = theBundle.getStringEx(tag, status);
705        if(U_FAILURE(status)) {
706            string.setTo(TRUE, kErrorUChars, kErrorLength);
707        }
708
709        CONFIRM_UErrorCode(status, expected_resource_status);
710
711        UnicodeString expected_string(kErrorUChars);
712        if (U_SUCCESS(status)) {
713            expected_string = base;
714        }
715
716        CONFIRM_EQ(string, expected_string);
717
718        //--------------------------------------------------------------------------
719        // array   ResourceBundle using the key
720
721        uprv_strcpy(tag, "array_");
722        uprv_strcat(tag, frag);
723
724        action = param[i].name;
725        action += ".get(";
726        action += tag;
727        action += ")";
728
729        int32_t count = kERROR_COUNT;
730        status = U_ZERO_ERROR;
731        ResourceBundle array = theBundle.get(tag, status);
732        CONFIRM_UErrorCode(status,expected_resource_status);
733
734
735        if (U_SUCCESS(status))
736        {
737            //confirm the resource type is an array
738            UResType bundleType=array.getType();
739            CONFIRM_EQ(bundleType, URES_ARRAY);
740
741            count=array.getSize();
742            CONFIRM_GE(count,1);
743
744            for (j=0; j<count; ++j)
745            {
746                char buf[32];
747                expected_string = base;
748                expected_string += itoa(j,buf);
749                CONFIRM_EQ(array.getNextString(status),expected_string);
750            }
751
752        }
753        else
754        {
755            CONFIRM_EQ(count,kERROR_COUNT);
756            //       CONFIRM_EQ((int32_t)(unsigned long)array,(int32_t)0);
757            count = 0;
758        }
759
760        //--------------------------------------------------------------------------
761        // arrayItem ResourceBundle using the index
762
763
764        for (j=0; j<100; ++j)
765        {
766            index = count ? (randi(count * 3) - count) : (randi(200) - 100);
767            status = U_ZERO_ERROR;
768            string = kErrorUChars;
769            ResourceBundle array = theBundle.get(tag, status);
770            if(!U_FAILURE(status)){
771                UnicodeString t = array.getStringEx(index, status);
772                if(!U_FAILURE(status)) {
773                   string=t;
774                }
775            }
776
777            expected_status = (index >= 0 && index < count) ? expected_resource_status : U_MISSING_RESOURCE_ERROR;
778            CONFIRM_UErrorCode(status,expected_status);
779
780            if (U_SUCCESS(status)){
781                char buf[32];
782                expected_string = base;
783                expected_string += itoa(index,buf);
784            } else {
785                expected_string = kErrorUChars;
786            }
787               CONFIRM_EQ(string,expected_string);
788
789        }
790
791        //--------------------------------------------------------------------------
792        // 2dArray
793
794        uprv_strcpy(tag, "array_2d_");
795        uprv_strcat(tag, frag);
796
797        action = param[i].name;
798        action += ".get(";
799        action += tag;
800        action += ")";
801
802
803        int32_t row_count = kERROR_COUNT, column_count = kERROR_COUNT;
804        status = U_ZERO_ERROR;
805        ResourceBundle array2d=theBundle.get(tag, status);
806
807        //const UnicodeString** array2d = theBundle.get2dArray(tag, row_count, column_count, status);
808        CONFIRM_UErrorCode(status,expected_resource_status);
809
810        if (U_SUCCESS(status))
811        {
812            //confirm the resource type is an 2darray
813            UResType bundleType=array2d.getType();
814            CONFIRM_EQ(bundleType, URES_ARRAY);
815
816            row_count=array2d.getSize();
817            CONFIRM_GE(row_count,1);
818
819            for(row=0; row<row_count; ++row){
820                ResourceBundle tablerow=array2d.get(row, status);
821                CONFIRM_UErrorCode(status, expected_resource_status);
822                if(U_SUCCESS(status)){
823                    //confirm the resourcetype of each table row is an array
824                    UResType rowType=tablerow.getType();
825                    CONFIRM_EQ(rowType, URES_ARRAY);
826
827                    column_count=tablerow.getSize();
828                    CONFIRM_GE(column_count,1);
829
830                    for (col=0; j<column_count; ++j) {
831                           char buf[32];
832                           expected_string = base;
833                           expected_string += itoa(row,buf);
834                           expected_string += itoa(col,buf);
835                           CONFIRM_EQ(tablerow.getNextString(status),expected_string);
836                    }
837                }
838            }
839        }else{
840            CONFIRM_EQ(row_count,kERROR_COUNT);
841            CONFIRM_EQ(column_count,kERROR_COUNT);
842             row_count=column_count=0;
843        }
844
845
846
847
848       //--------------------------------------------------------------------------
849       // 2dArrayItem
850       for (j=0; j<200; ++j)
851       {
852           row = row_count ? (randi(row_count * 3) - row_count) : (randi(200) - 100);
853           col = column_count ? (randi(column_count * 3) - column_count) : (randi(200) - 100);
854           status = U_ZERO_ERROR;
855           string = kErrorUChars;
856           ResourceBundle array2d=theBundle.get(tag, status);
857           if(U_SUCCESS(status)){
858                ResourceBundle tablerow=array2d.get(row, status);
859                if(U_SUCCESS(status)) {
860                    UnicodeString t=tablerow.getStringEx(col, status);
861                    if(U_SUCCESS(status)){
862                       string=t;
863                    }
864                }
865           }
866           expected_status = (row >= 0 && row < row_count && col >= 0 && col < column_count) ?
867                                  expected_resource_status: U_MISSING_RESOURCE_ERROR;
868           CONFIRM_UErrorCode(status,expected_status);
869
870           if (U_SUCCESS(status)){
871               char buf[32];
872               expected_string = base;
873               expected_string += itoa(row,buf);
874               expected_string += itoa(col,buf);
875           } else {
876               expected_string = kErrorUChars;
877           }
878               CONFIRM_EQ(string,expected_string);
879
880        }
881
882        //--------------------------------------------------------------------------
883        // taggedArray
884
885        uprv_strcpy(tag, "tagged_array_");
886        uprv_strcat(tag, frag);
887
888        action = param[i].name;
889        action += ".get(";
890        action += tag;
891        action += ")";
892
893        int32_t         tag_count;
894        status = U_ZERO_ERROR;
895
896        ResourceBundle tags=theBundle.get(tag, status);
897        CONFIRM_UErrorCode(status, expected_resource_status);
898
899        if (U_SUCCESS(status)) {
900            UResType bundleType=tags.getType();
901            CONFIRM_EQ(bundleType, URES_TABLE);
902
903            tag_count=tags.getSize();
904            CONFIRM_GE((int32_t)tag_count, (int32_t)0);
905
906            for(index=0; index <tag_count; index++){
907                ResourceBundle tagelement=tags.get(index, status);
908                UnicodeString key=tagelement.getKey();
909                UnicodeString value=tagelement.getNextString(status);
910                logln("tag = " + key + ", value = " + value );
911                if(key.startsWith("tag") && value.startsWith(base)){
912                    record_pass();
913                }else{
914                    record_fail();
915                }
916
917            }
918
919            for(index=0; index <tag_count; index++){
920                ResourceBundle tagelement=tags.get(index, status);
921                const char *tkey=NULL;
922                UnicodeString value=tagelement.getNextString(&tkey, status);
923                UnicodeString key(tkey);
924                logln("tag = " + key + ", value = " + value );
925                if(value.startsWith(base)){
926                    record_pass();
927                }else{
928                    record_fail();
929                }
930            }
931
932        }else{
933            tag_count=0;
934        }
935
936
937
938
939        //--------------------------------------------------------------------------
940        // taggedArrayItem
941
942        action = param[i].name;
943        action += ".get(";
944        action += tag;
945        action += ")";
946
947        count = 0;
948        for (index=-20; index<20; ++index)
949        {
950            char buf[32];
951            status = U_ZERO_ERROR;
952            string = kErrorUChars;
953            char item_tag[8];
954            uprv_strcpy(item_tag, "tag");
955            uprv_strcat(item_tag, itoa(index,buf));
956            ResourceBundle tags=theBundle.get(tag, status);
957            if(U_SUCCESS(status)){
958                ResourceBundle tagelement=tags.get(item_tag, status);
959                if(!U_FAILURE(status)){
960                    UResType elementType=tagelement.getType();
961                    CONFIRM_EQ(elementType, (int32_t)URES_STRING);
962                    const char* key=tagelement.getKey();
963                    CONFIRM_EQ((UnicodeString)key, (UnicodeString)item_tag);
964                    UnicodeString t=tagelement.getString(status);
965                    if(!U_FAILURE(status)){
966                        string=t;
967                    }
968                }
969                if (index < 0) {
970                    CONFIRM_UErrorCode(status,U_MISSING_RESOURCE_ERROR);
971                }
972                else{
973                   if (status != U_MISSING_RESOURCE_ERROR) {
974                       count++;
975                       expected_string = base;
976                       expected_string += buf;
977                       CONFIRM_EQ(string,expected_string);
978                   }
979                }
980            }
981
982        }
983        CONFIRM_EQ(count, tag_count);
984
985    }
986    return (UBool)(failOrig == fail);
987}
988
989void
990NewResourceBundleTest::record_pass()
991{
992  ++pass;
993}
994void
995NewResourceBundleTest::record_fail()
996{
997  err();
998  ++fail;
999}
1000
1001
1002void
1003NewResourceBundleTest::TestNewTypes() {
1004    char action[256];
1005    const char* testdatapath;
1006    UErrorCode status = U_ZERO_ERROR;
1007    uint8_t *binResult = NULL;
1008    int32_t len = 0;
1009    int32_t i = 0;
1010    int32_t intResult = 0;
1011    uint32_t uintResult = 0;
1012    UChar expected[] = { 'a','b','c','\0','d','e','f' };
1013    const char* expect ="tab:\t cr:\r ff:\f newline:\n backslash:\\\\ quote=\\\' doubleQuote=\\\" singlequoutes=''";
1014    UChar uExpect[200];
1015
1016    testdatapath=loadTestData(status);
1017
1018    if(U_FAILURE(status))
1019    {
1020        dataerrln("Could not load testdata.dat %s \n",u_errorName(status));
1021        return;
1022    }
1023
1024    ResourceBundle theBundle(testdatapath, "testtypes", status);
1025    ResourceBundle bundle(testdatapath, Locale("te_IN"),status);
1026
1027    UnicodeString emptyStr = theBundle.getStringEx("emptystring", status);
1028    if(!emptyStr.length()==0) {
1029      logln("Empty string returned invalid value\n");
1030    }
1031
1032    CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1033
1034    /* This test reads the string "abc\u0000def" from the bundle   */
1035    /* if everything is working correctly, the size of this string */
1036    /* should be 7. Everything else is a wrong answer, esp. 3 and 6*/
1037
1038    strcpy(action, "getting and testing of string with embeded zero");
1039    ResourceBundle res = theBundle.get("zerotest", status);
1040    CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1041    CONFIRM_EQ(res.getType(), URES_STRING);
1042    UnicodeString zeroString=res.getString(status);
1043    len = zeroString.length();
1044    if(U_SUCCESS(status)){
1045        CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1046        CONFIRM_EQ(len, 7);
1047        CONFIRM_NE(len, 3);
1048    }
1049    for(i=0;i<len;i++){
1050        if(zeroString[i]!= expected[i]){
1051            logln("Output didnot match Expected: \\u%4X Got: \\u%4X", expected[i], zeroString[i]);
1052        }
1053    }
1054
1055    strcpy(action, "getting and testing of binary type");
1056    res = theBundle.get("binarytest", status);
1057    CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1058    CONFIRM_EQ(res.getType(), URES_BINARY);
1059    binResult=(uint8_t*)res.getBinary(len, status);
1060    if(U_SUCCESS(status)){
1061        CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1062        CONFIRM_EQ(len, 15);
1063        for(i = 0; i<15; i++) {
1064            CONFIRM_EQ(binResult[i], i);
1065        }
1066    }
1067
1068    strcpy(action, "getting and testing of imported binary type");
1069    res = theBundle.get("importtest",status);
1070    CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1071    CONFIRM_EQ(res.getType(), URES_BINARY);
1072    binResult=(uint8_t*)res.getBinary(len, status);
1073    if(U_SUCCESS(status)){
1074        CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1075        CONFIRM_EQ(len, 15);
1076        for(i = 0; i<15; i++) {
1077            CONFIRM_EQ(binResult[i], i);
1078        }
1079    }
1080
1081    strcpy(action, "getting and testing of integer types");
1082    res = theBundle.get("one",  status);
1083    CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1084    CONFIRM_EQ(res.getType(), URES_INT);
1085    intResult=res.getInt(status);
1086    uintResult = res.getUInt(status);
1087    if(U_SUCCESS(status)){
1088        CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1089        CONFIRM_EQ(uintResult, (uint32_t)intResult);
1090        CONFIRM_EQ(intResult, 1);
1091    }
1092
1093    strcpy(action, "getting minusone");
1094    res = theBundle.get((const char*)"minusone", status);
1095    CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1096    CONFIRM_EQ(res.getType(), URES_INT);
1097    intResult=res.getInt(status);
1098    uintResult = res.getUInt(status);
1099    if(U_SUCCESS(status)){
1100        CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1101        CONFIRM_EQ(uintResult, 0x0FFFFFFF); /* a 28 bit integer */
1102        CONFIRM_EQ(intResult, -1);
1103        CONFIRM_NE(uintResult, (uint32_t)intResult);
1104    }
1105
1106    strcpy(action, "getting plusone");
1107    res = theBundle.get("plusone",status);
1108    CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1109    CONFIRM_EQ(res.getType(), URES_INT);
1110    intResult=res.getInt(status);
1111    uintResult = res.getUInt(status);
1112    if(U_SUCCESS(status)){
1113        CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1114        CONFIRM_EQ(uintResult, (uint32_t)intResult);
1115        CONFIRM_EQ(intResult, 1);
1116    }
1117
1118    res = theBundle.get("onehundredtwentythree",status);
1119    CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1120    CONFIRM_EQ(res.getType(), URES_INT);
1121    intResult=res.getInt(status);
1122    if(U_SUCCESS(status)){
1123        CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1124        CONFIRM_EQ(intResult, 123);
1125    }
1126
1127    /* this tests if escapes are preserved or not */
1128    {
1129        UnicodeString str = theBundle.getStringEx("testescape",status);
1130        CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1131        if(U_SUCCESS(status)){
1132            u_charsToUChars(expect,uExpect,(int32_t)uprv_strlen(expect)+1);
1133            if(str.compare(uExpect)!=0){
1134                errln("Did not get the expected string for testescape expected. Expected : "
1135                    +UnicodeString(uExpect )+ " Got: " + str);
1136            }
1137        }
1138    }
1139    /* test for jitterbug#1435 */
1140    {
1141        UnicodeString str = theBundle.getStringEx("test_underscores",status);
1142        expect ="test message ....";
1143        CONFIRM_UErrorCode(status, U_ZERO_ERROR);
1144        u_charsToUChars(expect,uExpect,(int32_t)uprv_strlen(expect)+1);
1145        if(str.compare(uExpect)!=0){
1146            errln("Did not get the expected string for test_underscores.\n");
1147        }
1148    }
1149
1150
1151}
1152
1153void
1154NewResourceBundleTest::TestGetByFallback() {
1155    UErrorCode status = U_ZERO_ERROR;
1156
1157    ResourceBundle heRes(NULL, "he", status);
1158
1159    heRes.getWithFallback("calendar", status).getWithFallback("islamic-civil", status).getWithFallback("DateTime", status);
1160    if(U_SUCCESS(status)) {
1161        errln("he locale's Islamic-civil DateTime resource exists. How did it get here?\n");
1162    }
1163    status = U_ZERO_ERROR;
1164
1165    heRes.getWithFallback("calendar", status).getWithFallback("islamic-civil", status).getWithFallback("eras", status);
1166    if(U_FAILURE(status)) {
1167        dataerrln("Didn't get Islamic Eras. I know they are there! - %s", u_errorName(status));
1168    }
1169    status = U_ZERO_ERROR;
1170
1171    ResourceBundle rootRes(NULL, "root", status);
1172    rootRes.getWithFallback("calendar", status).getWithFallback("islamic-civil", status).getWithFallback("DateTime", status);
1173    if(U_SUCCESS(status)) {
1174        errln("Root's Islamic-civil's DateTime resource exists. How did it get here?\n");
1175    }
1176    status = U_ZERO_ERROR;
1177
1178}
1179//eof
1180
1181