Home | History | Annotate | Download | only in cintltst
      1 /*
      2 *******************************************************************************
      3 *
      4 *   Copyright (C) 2002-2003, International Business Machines
      5 *   Corporation and others.  All Rights Reserved.
      6 *
      7 *******************************************************************************
      8 *   file name:  uenumtst.c
      9 *   encoding:   US-ASCII
     10 *   tab size:   8 (not used)
     11 *   indentation:2
     12 *
     13 *   created on: 2002jul08
     14 *   created by: Vladimir Weinstein
     15 */
     16 
     17 #include "cintltst.h"
     18 #include "uenumimp.h"
     19 #include "cmemory.h"
     20 #include "cstring.h"
     21 #include "unicode/ustring.h"
     22 
     23 static char quikBuf[256];
     24 static char* quikU2C(const UChar* str, int32_t len) {
     25     u_UCharsToChars(str, quikBuf, len);
     26     quikBuf[len] = 0;
     27     return quikBuf;
     28 }
     29 
     30 static const char* test1[] = {
     31     "first",
     32     "second",
     33     "third",
     34     "fourth"
     35 };
     36 
     37 struct chArrayContext {
     38     int32_t currIndex;
     39     int32_t maxIndex;
     40     char *currChar;
     41     UChar *currUChar;
     42     char **array;
     43 };
     44 
     45 typedef struct chArrayContext chArrayContext;
     46 
     47 #define cont ((chArrayContext *)en->context)
     48 
     49 static void U_CALLCONV
     50 chArrayClose(UEnumeration *en) {
     51     if(cont->currUChar != NULL) {
     52         free(cont->currUChar);
     53         cont->currUChar = NULL;
     54     }
     55     free(en);
     56 }
     57 
     58 static int32_t U_CALLCONV
     59 chArrayCount(UEnumeration *en, UErrorCode *status) {
     60     return cont->maxIndex;
     61 }
     62 
     63 static const UChar* U_CALLCONV
     64 chArrayUNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
     65     if(cont->currIndex >= cont->maxIndex) {
     66         return NULL;
     67     }
     68 
     69     if(cont->currUChar == NULL) {
     70         cont->currUChar = (UChar *)malloc(1024*sizeof(UChar));
     71     }
     72 
     73     cont->currChar = (cont->array)[cont->currIndex];
     74     *resultLength = (int32_t)strlen(cont->currChar);
     75     u_charsToUChars(cont->currChar, cont->currUChar, *resultLength);
     76     cont->currIndex++;
     77     return cont->currUChar;
     78 }
     79 
     80 static const char* U_CALLCONV
     81 chArrayNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
     82     if(cont->currIndex >= cont->maxIndex) {
     83         return NULL;
     84     }
     85 
     86     cont->currChar = (cont->array)[cont->currIndex];
     87     *resultLength = (int32_t)strlen(cont->currChar);
     88     cont->currIndex++;
     89     return cont->currChar;
     90 }
     91 
     92 static void U_CALLCONV
     93 chArrayReset(UEnumeration *en, UErrorCode *status) {
     94     cont->currIndex = 0;
     95 }
     96 
     97 chArrayContext myCont = {
     98     0, 0,
     99     NULL, NULL,
    100     NULL
    101 };
    102 
    103 UEnumeration chEnum = {
    104     NULL,
    105     &myCont,
    106     chArrayClose,
    107     chArrayCount,
    108     chArrayUNext,
    109     chArrayNext,
    110     chArrayReset
    111 };
    112 
    113 static const UEnumeration emptyEnumerator = {
    114     NULL,
    115     NULL,
    116     NULL,
    117     NULL,
    118     NULL,
    119     NULL,
    120     NULL,
    121 };
    122 
    123 static const UEnumeration emptyPartialEnumerator = {
    124     NULL,
    125     NULL,
    126     NULL,
    127     NULL,
    128     uenum_unextDefault,
    129     NULL,
    130     NULL,
    131 };
    132 
    133 /********************************************************************/
    134 static const UChar _first[] = {102,105,114,115,116,0};    /* "first"  */
    135 static const UChar _second[]= {115,101,99,111,110,100,0}; /* "second" */
    136 static const UChar _third[] = {116,104,105,114,100,0};    /* "third"  */
    137 static const UChar _fourth[]= {102,111,117,114,116,104,0};/* "fourth" */
    138 
    139 static const UChar* test2[] = {
    140     _first, _second, _third, _fourth
    141 };
    142 
    143 struct uchArrayContext {
    144     int32_t currIndex;
    145     int32_t maxIndex;
    146     UChar *currUChar;
    147     UChar **array;
    148 };
    149 
    150 typedef struct uchArrayContext uchArrayContext;
    151 
    152 #define ucont ((uchArrayContext *)en->context)
    153 
    154 static void U_CALLCONV
    155 uchArrayClose(UEnumeration *en) {
    156     free(en);
    157 }
    158 
    159 static int32_t U_CALLCONV
    160 uchArrayCount(UEnumeration *en, UErrorCode *status) {
    161     return ucont->maxIndex;
    162 }
    163 
    164 static const UChar* U_CALLCONV
    165 uchArrayUNext(UEnumeration *en, int32_t *resultLength, UErrorCode *status) {
    166     if(ucont->currIndex >= ucont->maxIndex) {
    167         return NULL;
    168     }
    169 
    170     ucont->currUChar = (ucont->array)[ucont->currIndex];
    171     *resultLength = u_strlen(ucont->currUChar);
    172     ucont->currIndex++;
    173     return ucont->currUChar;
    174 }
    175 
    176 static void U_CALLCONV
    177 uchArrayReset(UEnumeration *en, UErrorCode *status) {
    178     ucont->currIndex = 0;
    179 }
    180 
    181 uchArrayContext myUCont = {
    182     0, 0,
    183     NULL, NULL
    184 };
    185 
    186 UEnumeration uchEnum = {
    187     NULL,
    188     &myUCont,
    189     uchArrayClose,
    190     uchArrayCount,
    191     uchArrayUNext,
    192     uenum_nextDefault,
    193     uchArrayReset
    194 };
    195 
    196 /********************************************************************/
    197 
    198 static UEnumeration *getchArrayEnum(const char** source, int32_t size) {
    199     UEnumeration *en = (UEnumeration *)malloc(sizeof(UEnumeration));
    200     memcpy(en, &chEnum, sizeof(UEnumeration));
    201     cont->array = (char **)source;
    202     cont->maxIndex = size;
    203     return en;
    204 }
    205 
    206 static void EnumerationTest(void) {
    207     UErrorCode status = U_ZERO_ERROR;
    208     int32_t len = 0;
    209     UEnumeration *en = getchArrayEnum(test1, sizeof(test1)/sizeof(test1[0]));
    210     const char *string = NULL;
    211     const UChar *uString = NULL;
    212     while ((string = uenum_next(en, &len, &status))) {
    213         log_verbose("read \"%s\", length %i\n", string, len);
    214     }
    215     uenum_reset(en, &status);
    216     while ((uString = uenum_unext(en, &len, &status))) {
    217         log_verbose("read \"%s\" (UChar), length %i\n", quikU2C(uString, len), len);
    218     }
    219 
    220     uenum_close(en);
    221 }
    222 
    223 static void EmptyEnumerationTest(void) {
    224     UErrorCode status = U_ZERO_ERROR;
    225     UEnumeration *emptyEnum = uprv_malloc(sizeof(UEnumeration));
    226 
    227     uprv_memcpy(emptyEnum, &emptyEnumerator, sizeof(UEnumeration));
    228     if (uenum_count(emptyEnum, &status) != -1 || status != U_UNSUPPORTED_ERROR) {
    229         log_err("uenum_count failed\n");
    230     }
    231     status = U_ZERO_ERROR;
    232     if (uenum_next(emptyEnum, NULL, &status) != NULL || status != U_UNSUPPORTED_ERROR) {
    233         log_err("uenum_next failed\n");
    234     }
    235     status = U_ZERO_ERROR;
    236     if (uenum_unext(emptyEnum, NULL, &status) != NULL || status != U_UNSUPPORTED_ERROR) {
    237         log_err("uenum_unext failed\n");
    238     }
    239     status = U_ZERO_ERROR;
    240     uenum_reset(emptyEnum, &status);
    241     if (status != U_UNSUPPORTED_ERROR) {
    242         log_err("uenum_reset failed\n");
    243     }
    244     uenum_close(emptyEnum);
    245 
    246     status = U_ZERO_ERROR;
    247     if (uenum_next(NULL, NULL, &status) != NULL || status != U_ZERO_ERROR) {
    248         log_err("uenum_next(NULL) failed\n");
    249     }
    250     status = U_ZERO_ERROR;
    251     if (uenum_unext(NULL, NULL, &status) != NULL || status != U_ZERO_ERROR) {
    252         log_err("uenum_unext(NULL) failed\n");
    253     }
    254     status = U_ZERO_ERROR;
    255     uenum_reset(NULL, &status);
    256     if (status != U_ZERO_ERROR) {
    257         log_err("uenum_reset(NULL) failed\n");
    258     }
    259 
    260     emptyEnum = uprv_malloc(sizeof(UEnumeration));
    261     uprv_memcpy(emptyEnum, &emptyPartialEnumerator, sizeof(UEnumeration));
    262     status = U_ZERO_ERROR;
    263     if (uenum_unext(emptyEnum, NULL, &status) != NULL || status != U_UNSUPPORTED_ERROR) {
    264         log_err("partial uenum_unext failed\n");
    265     }
    266     uenum_close(emptyEnum);
    267 }
    268 
    269 static UEnumeration *getuchArrayEnum(const UChar** source, int32_t size) {
    270     UEnumeration *en = (UEnumeration *)malloc(sizeof(UEnumeration));
    271     memcpy(en, &uchEnum, sizeof(UEnumeration));
    272     ucont->array = (UChar **)source;
    273     ucont->maxIndex = size;
    274     return en;
    275 }
    276 
    277 static void DefaultNextTest(void) {
    278     UErrorCode status = U_ZERO_ERROR;
    279     int32_t len = 0;
    280     UEnumeration *en = getuchArrayEnum(test2, sizeof(test2)/sizeof(test2[0]));
    281     const char *string = NULL;
    282     const UChar *uString = NULL;
    283     while ((uString = uenum_unext(en, &len, &status))) {
    284         log_verbose("read \"%s\" (UChar), length %i\n", quikU2C(uString, len), len);
    285     }
    286     if (U_FAILURE(status)) {
    287         log_err("FAIL: uenum_unext => %s\n", u_errorName(status));
    288     }
    289     uenum_reset(en, &status);
    290     while ((string = uenum_next(en, &len, &status))) {
    291         log_verbose("read \"%s\", length %i\n", string, len);
    292     }
    293     if (U_FAILURE(status)) {
    294         log_err("FAIL: uenum_next => %s\n", u_errorName(status));
    295     }
    296 
    297     uenum_close(en);
    298 }
    299 
    300 void addEnumerationTest(TestNode** root);
    301 
    302 void addEnumerationTest(TestNode** root)
    303 {
    304     addTest(root, &EnumerationTest, "tsutil/uenumtst/EnumerationTest");
    305     addTest(root, &EmptyEnumerationTest, "tsutil/uenumtst/EmptyEnumerationTest");
    306     addTest(root, &DefaultNextTest, "tsutil/uenumtst/DefaultNextTest");
    307 }
    308