• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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];
quikU2C(const UChar * str,int32_t len)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
chArrayClose(UEnumeration * en)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
chArrayCount(UEnumeration * en,UErrorCode * status)59 chArrayCount(UEnumeration *en, UErrorCode *status) {
60     return cont->maxIndex;
61 }
62 
63 static const UChar* U_CALLCONV
chArrayUNext(UEnumeration * en,int32_t * resultLength,UErrorCode * status)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
chArrayNext(UEnumeration * en,int32_t * resultLength,UErrorCode * status)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
chArrayReset(UEnumeration * en,UErrorCode * status)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
uchArrayClose(UEnumeration * en)155 uchArrayClose(UEnumeration *en) {
156     free(en);
157 }
158 
159 static int32_t U_CALLCONV
uchArrayCount(UEnumeration * en,UErrorCode * status)160 uchArrayCount(UEnumeration *en, UErrorCode *status) {
161     return ucont->maxIndex;
162 }
163 
164 static const UChar* U_CALLCONV
uchArrayUNext(UEnumeration * en,int32_t * resultLength,UErrorCode * status)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
uchArrayReset(UEnumeration * en,UErrorCode * status)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 
getchArrayEnum(const char ** source,int32_t size)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 
EnumerationTest(void)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 
EmptyEnumerationTest(void)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 
getuchArrayEnum(const UChar ** source,int32_t size)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 
DefaultNextTest(void)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 
addEnumerationTest(TestNode ** root)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