]> git.saurik.com Git - apple/icu.git/blob - icuSources/test/intltest/ustrtest.cpp
ICU-6.2.22.tar.gz
[apple/icu.git] / icuSources / test / intltest / ustrtest.cpp
1 /********************************************************************
2 * COPYRIGHT:
3 * Copyright (c) 1997-2004, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
6
7 #include "ustrtest.h"
8 #include "unicode/unistr.h"
9 #include "unicode/uchar.h"
10 #include "unicode/ustring.h"
11 #include "unicode/locid.h"
12 #include "unicode/ucnv.h"
13 #include "cmemory.h"
14
15 #if 0
16 #include "unicode/ustream.h"
17
18 #if U_IOSTREAM_SOURCE >= 199711
19 #include <iostream>
20 using namespace std;
21 #elif U_IOSTREAM_SOURCE >= 198506
22 #include <iostream.h>
23 #endif
24
25 #endif
26
27 #define LENGTHOF(array) (int32_t)((sizeof(array)/sizeof((array)[0])))
28
29 UnicodeStringTest::~UnicodeStringTest() {}
30
31 void UnicodeStringTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char *par)
32 {
33 if (exec) logln("TestSuite UnicodeStringTest: ");
34 switch (index) {
35 case 0:
36 name = "StringCaseTest";
37 if (exec) {
38 logln("StringCaseTest---"); logln("");
39 StringCaseTest test;
40 callTest(test, par);
41 }
42 break;
43 case 1: name = "TestBasicManipulation"; if (exec) TestBasicManipulation(); break;
44 case 2: name = "TestCompare"; if (exec) TestCompare(); break;
45 case 3: name = "TestExtract"; if (exec) TestExtract(); break;
46 case 4: name = "TestRemoveReplace"; if (exec) TestRemoveReplace(); break;
47 case 5: name = "TestSearching"; if (exec) TestSearching(); break;
48 case 6: name = "TestSpacePadding"; if (exec) TestSpacePadding(); break;
49 case 7: name = "TestPrefixAndSuffix"; if (exec) TestPrefixAndSuffix(); break;
50 case 8: name = "TestFindAndReplace"; if (exec) TestFindAndReplace(); break;
51 case 9: name = "TestBogus"; if (exec) TestBogus(); break;
52 case 10: name = "TestReverse"; if (exec) TestReverse(); break;
53 case 11: name = "TestMiscellaneous"; if (exec) TestMiscellaneous(); break;
54 case 12: name = "TestStackAllocation"; if (exec) TestStackAllocation(); break;
55 case 13: name = "TestUnescape"; if (exec) TestUnescape(); break;
56 case 14: name = "TestCountChar32"; if (exec) TestCountChar32(); break;
57 case 15: name = "TestStringEnumeration"; if (exec) TestStringEnumeration(); break;
58
59 default: name = ""; break; //needed to end loop
60 }
61 }
62
63 void
64 UnicodeStringTest::TestBasicManipulation()
65 {
66 UnicodeString test1("Now is the time for all men to come swiftly to the aid of the party.\n");
67 UnicodeString expectedValue;
68 UnicodeString *c;
69
70 c=(UnicodeString *)test1.clone();
71 test1.insert(24, "good ");
72 expectedValue = "Now is the time for all good men to come swiftly to the aid of the party.\n";
73 if (test1 != expectedValue)
74 errln("insert() failed: expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
75
76 c->insert(24, "good ");
77 if(*c != expectedValue) {
78 errln("clone()->insert() failed: expected \"" + expectedValue + "\"\n,got \"" + *c + "\"");
79 }
80 delete c;
81
82 test1.remove(41, 8);
83 expectedValue = "Now is the time for all good men to come to the aid of the party.\n";
84 if (test1 != expectedValue)
85 errln("remove() failed: expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
86
87 test1.replace(58, 6, "ir country");
88 expectedValue = "Now is the time for all good men to come to the aid of their country.\n";
89 if (test1 != expectedValue)
90 errln("replace() failed: expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
91
92 UChar temp[80];
93 test1.extract(0, 15, temp);
94
95 UnicodeString test2(temp, 15);
96
97 expectedValue = "Now is the time";
98 if (test2 != expectedValue)
99 errln("extract() failed: expected \"" + expectedValue + "\"\n,got \"" + test2 + "\"");
100
101 test2 += " for me to go!\n";
102 expectedValue = "Now is the time for me to go!\n";
103 if (test2 != expectedValue)
104 errln("operator+=() failed: expected \"" + expectedValue + "\"\n,got \"" + test2 + "\"");
105
106 if (test1.length() != 70)
107 errln("length() failed: expected 70, got " + test1.length());
108 if (test2.length() != 30)
109 errln("length() failed: expected 30, got " + test2.length());
110
111 UnicodeString test3;
112 test3.append((UChar32)0x20402);
113 if(test3 != CharsToUnicodeString("\\uD841\\uDC02")){
114 errln((UnicodeString)"append failed for UChar32, expected \"\\\\ud841\\\\udc02\", got " + prettify(test3));
115 }
116 if(test3.length() != 2){
117 errln("append or length failed for UChar32, expected 2, got " + test3.length());
118 }
119 test3.append((UChar32)0x0074);
120 if(test3 != CharsToUnicodeString("\\uD841\\uDC02t")){
121 errln((UnicodeString)"append failed for UChar32, expected \"\\\\uD841\\\\uDC02t\", got " + prettify(test3));
122 }
123 if(test3.length() != 3){
124 errln((UnicodeString)"append or length failed for UChar32, expected 2, got " + test3.length());
125 }
126
127 // test some UChar32 overloads
128 if( test3.setTo((UChar32)0x10330).length() != 2 ||
129 test3.insert(0, (UChar32)0x20100).length() != 4 ||
130 test3.replace(2, 2, (UChar32)0xe0061).length() != 4 ||
131 (test3 = (UChar32)0x14001).length() != 2
132 ) {
133 errln((UnicodeString)"simple UChar32 overloads for replace, insert, setTo or = failed");
134 }
135
136 {
137 // test moveIndex32()
138 UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
139
140 if(
141 s.moveIndex32(2, -1)!=0 ||
142 s.moveIndex32(2, 1)!=4 ||
143 s.moveIndex32(2, 2)!=5 ||
144 s.moveIndex32(5, -2)!=2 ||
145 s.moveIndex32(0, -1)!=0 ||
146 s.moveIndex32(6, 1)!=6
147 ) {
148 errln("UnicodeString::moveIndex32() failed");
149 }
150
151 if(s.getChar32Start(1)!=0 || s.getChar32Start(2)!=2) {
152 errln("UnicodeString::getChar32Start() failed");
153 }
154
155 if(s.getChar32Limit(1)!=2 || s.getChar32Limit(2)!=2) {
156 errln("UnicodeString::getChar32Limit() failed");
157 }
158 }
159
160 {
161 // test new 2.2 constructors and setTo function that parallel Java's substring function.
162 UnicodeString src("Hello folks how are you?");
163 UnicodeString target1("how are you?");
164 if (target1 != UnicodeString(src, 12)) {
165 errln("UnicodeString(const UnicodeString&, int32_t) failed");
166 }
167 UnicodeString target2("folks");
168 if (target2 != UnicodeString(src, 6, 5)) {
169 errln("UnicodeString(const UnicodeString&, int32_t, int32_t) failed");
170 }
171 if (target1 != target2.setTo(src, 12)) {
172 errln("UnicodeString::setTo(const UnicodeString&, int32_t) failed");
173 }
174 }
175
176 {
177 // op+ is new in ICU 2.8
178 UnicodeString s=UnicodeString("abc", "")+UnicodeString("def", "")+UnicodeString("ghi", "");
179 if(s!=UnicodeString("abcdefghi", "")) {
180 errln("operator+(UniStr, UniStr) failed");
181 }
182 }
183
184 {
185 // tests for Jitterbug 2360
186 // verify that APIs with source pointer + length accept length == -1
187 // mostly test only where modified, only few functions did not already do this
188 if(UnicodeString("abc", -1, "")!=UnicodeString("abc", "")) {
189 errln("UnicodeString(codepageData, dataLength, codepage) does not work with dataLength==-1");
190 }
191
192 UChar buffer[10]={ 0x61, 0x62, 0x20ac, 0xd900, 0xdc05, 0, 0x62, 0xffff, 0xdbff, 0xdfff };
193 UnicodeString s, t(buffer, -1, LENGTHOF(buffer));
194
195 if(s.setTo(buffer, -1, LENGTHOF(buffer)).length()!=u_strlen(buffer)) {
196 errln("UnicodeString.setTo(buffer, length, capacity) does not work with length==-1");
197 }
198 if(t.length()!=u_strlen(buffer)) {
199 errln("UnicodeString(buffer, length, capacity) does not work with length==-1");
200 }
201
202 if(0!=s.caseCompare(buffer, -1, U_FOLD_CASE_DEFAULT)) {
203 errln("UnicodeString.caseCompare(const UChar *, length, options) does not work with length==-1");
204 }
205
206 buffer[u_strlen(buffer)]=0xe4;
207 UnicodeString u(buffer, -1, LENGTHOF(buffer));
208 if(s.setTo(buffer, -1, LENGTHOF(buffer)).length()!=LENGTHOF(buffer)) {
209 errln("UnicodeString.setTo(buffer without NUL, length, capacity) does not work with length==-1");
210 }
211 if(u.length()!=LENGTHOF(buffer)) {
212 errln("UnicodeString(buffer without NUL, length, capacity) does not work with length==-1");
213 }
214
215 static const char cs[]={ 0x61, (char)0xe4, (char)0x85, 0 };
216 UConverter *cnv;
217 UErrorCode errorCode=U_ZERO_ERROR;
218
219 cnv=ucnv_open("ISO-8859-1", &errorCode);
220 UnicodeString v(cs, -1, cnv, errorCode);
221 ucnv_close(cnv);
222 if(v!=UnicodeString("a\\xe4\\x85").unescape()) {
223 errln("UnicodeString(const char *, length, cnv, errorCode) does not work with length==-1");
224 }
225 }
226 }
227
228 void
229 UnicodeStringTest::TestCompare()
230 {
231 UnicodeString test1("this is a test");
232 UnicodeString test2("this is a test");
233 UnicodeString test3("this is a test of the emergency broadcast system");
234 UnicodeString test4("never say, \"this is a test\"!!");
235
236 UnicodeString test5((UChar)0x5000);
237 UnicodeString test6((UChar)0x5100);
238
239 UChar uniChars[] = { 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73,
240 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0 };
241 char chars[] = "this is a test";
242
243 // test operator== and operator!=
244 if (test1 != test2 || test1 == test3 || test1 == test4)
245 errln("operator== or operator!= failed");
246
247 // test operator> and operator<
248 if (test1 > test2 || test1 < test2 || !(test1 < test3) || !(test1 > test4) ||
249 !(test5 < test6)
250 ) {
251 errln("operator> or operator< failed");
252 }
253
254 // test operator>= and operator<=
255 if (!(test1 >= test2) || !(test1 <= test2) || !(test1 <= test3) || !(test1 >= test4))
256 errln("operator>= or operator<= failed");
257
258 // test compare(UnicodeString)
259 if (test1.compare(test2) != 0 || test1.compare(test3) >= 0 || test1.compare(test4) <= 0)
260 errln("compare(UnicodeString) failed");
261
262 //test compare(offset, length, UnicodeString)
263 if(test1.compare(0, 14, test2) != 0 ||
264 test3.compare(0, 14, test2) != 0 ||
265 test4.compare(12, 14, test2) != 0 ||
266 test3.compare(0, 18, test1) <=0 )
267 errln("compare(offset, length, UnicodeString) failes");
268
269 // test compare(UChar*)
270 if (test2.compare(uniChars) != 0 || test3.compare(uniChars) <= 0 || test4.compare(uniChars) >= 0)
271 errln("compare(UChar*) failed");
272
273 // test compare(char*)
274 if (test2.compare(chars) != 0 || test3.compare(chars) <= 0 || test4.compare(chars) >= 0)
275 errln("compare(char*) failed");
276
277 // test compare(UChar*, length)
278 if (test1.compare(uniChars, 4) <= 0 || test1.compare(uniChars, 4) <= 0)
279 errln("compare(UChar*, length) failed");
280
281 // test compare(thisOffset, thisLength, that, thatOffset, thatLength)
282 if (test1.compare(0, 14, test2, 0, 14) != 0
283 || test1.compare(0, 14, test3, 0, 14) != 0
284 || test1.compare(0, 14, test4, 12, 14) != 0)
285 errln("1. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
286
287 if (test1.compare(10, 4, test2, 0, 4) >= 0
288 || test1.compare(10, 4, test3, 22, 9) <= 0
289 || test1.compare(10, 4, test4, 22, 4) != 0)
290 errln("2. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
291
292 // test compareBetween
293 if (test1.compareBetween(0, 14, test2, 0, 14) != 0 || test1.compareBetween(0, 14, test3, 0, 14) != 0
294 || test1.compareBetween(0, 14, test4, 12, 26) != 0)
295 errln("compareBetween failed");
296
297 if (test1.compareBetween(10, 14, test2, 0, 4) >= 0 || test1.compareBetween(10, 14, test3, 22, 31) <= 0
298 || test1.compareBetween(10, 14, test4, 22, 26) != 0)
299 errln("compareBetween failed");
300
301 // test compare() etc. with strings that share a buffer but are not equal
302 test2=test1; // share the buffer, length() too large for the stackBuffer
303 test2.truncate(1); // change only the length, not the buffer
304 if( test1==test2 || test1<=test2 ||
305 test1.compare(test2)<=0 ||
306 test1.compareCodePointOrder(test2)<=0 ||
307 test1.compareCodePointOrder(0, INT32_MAX, test2)<=0 ||
308 test1.compareCodePointOrder(0, INT32_MAX, test2, 0, INT32_MAX)<=0 ||
309 test1.compareCodePointOrderBetween(0, INT32_MAX, test2, 0, INT32_MAX)<=0 ||
310 test1.caseCompare(test2, U_FOLD_CASE_DEFAULT)<=0
311 ) {
312 errln("UnicodeStrings that share a buffer but have different lengths compare as equal");
313 }
314
315 /* test compareCodePointOrder() */
316 {
317 /* these strings are in ascending order */
318 static const UChar strings[][4]={
319 { 0x61, 0 }, /* U+0061 */
320 { 0x20ac, 0xd801, 0 }, /* U+20ac U+d801 */
321 { 0x20ac, 0xd800, 0xdc00, 0 }, /* U+20ac U+10000 */
322 { 0xd800, 0 }, /* U+d800 */
323 { 0xd800, 0xff61, 0 }, /* U+d800 U+ff61 */
324 { 0xdfff, 0 }, /* U+dfff */
325 { 0xff61, 0xdfff, 0 }, /* U+ff61 U+dfff */
326 { 0xff61, 0xd800, 0xdc02, 0 }, /* U+ff61 U+10002 */
327 { 0xd800, 0xdc02, 0 }, /* U+10002 */
328 { 0xd84d, 0xdc56, 0 } /* U+23456 */
329 };
330 UnicodeString u[20]; // must be at least as long as strings[]
331 int32_t i;
332
333 for(i=0; i<(int32_t)(sizeof(strings)/sizeof(strings[0])); ++i) {
334 u[i]=UnicodeString(TRUE, strings[i], -1);
335 }
336
337 for(i=0; i<(int32_t)(sizeof(strings)/sizeof(strings[0])-1); ++i) {
338 if(u[i].compareCodePointOrder(u[i+1])>=0 || u[i].compareCodePointOrder(0, INT32_MAX, u[i+1].getBuffer())>=0) {
339 errln("error: UnicodeString::compareCodePointOrder() fails for string %d and the following one\n", i);
340 }
341 }
342 }
343
344 /* test caseCompare() */
345 {
346 static const UChar
347 _mixed[]= { 0x61, 0x42, 0x131, 0x3a3, 0xdf, 0x130, 0x49, 0xfb03, 0xd93f, 0xdfff, 0 },
348 _otherDefault[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x69, 0x307, 0x69, 0x46, 0x66, 0x49, 0xd93f, 0xdfff, 0 },
349 _otherExcludeSpecialI[]={ 0x41, 0x62, 0x131, 0x3c3, 0x53, 0x73, 0x69, 0x131, 0x66, 0x46, 0x69, 0xd93f, 0xdfff, 0 },
350 _different[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x130, 0x49, 0x46, 0x66, 0x49, 0xd93f, 0xdffd, 0 };
351
352 UnicodeString
353 mixed(TRUE, _mixed, -1),
354 otherDefault(TRUE, _otherDefault, -1),
355 otherExcludeSpecialI(TRUE, _otherExcludeSpecialI, -1),
356 different(TRUE, _different, -1);
357
358 int8_t result;
359
360 /* test caseCompare() */
361 result=mixed.caseCompare(otherDefault, U_FOLD_CASE_DEFAULT);
362 if(result!=0 || 0!=mixed.caseCompareBetween(0, INT32_MAX, otherDefault, 0, INT32_MAX, U_FOLD_CASE_DEFAULT)) {
363 errln("error: mixed.caseCompare(other, default)=%ld instead of 0\n", result);
364 }
365 result=mixed.caseCompare(otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I);
366 if(result!=0) {
367 errln("error: mixed.caseCompare(otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=%ld instead of 0\n", result);
368 }
369 result=mixed.caseCompare(otherDefault, U_FOLD_CASE_EXCLUDE_SPECIAL_I);
370 if(result==0 || 0==mixed.caseCompareBetween(0, INT32_MAX, otherDefault, 0, INT32_MAX, U_FOLD_CASE_EXCLUDE_SPECIAL_I)) {
371 errln("error: mixed.caseCompare(other, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=0 instead of !=0\n");
372 }
373
374 /* test caseCompare() */
375 result=mixed.caseCompare(different, U_FOLD_CASE_DEFAULT);
376 if(result<=0) {
377 errln("error: mixed.caseCompare(different, default)=%ld instead of positive\n", result);
378 }
379
380 /* test caseCompare() - include the folded sharp s (U+00df) with different lengths */
381 result=mixed.caseCompare(1, 4, different, 1, 5, U_FOLD_CASE_DEFAULT);
382 if(result!=0 || 0!=mixed.caseCompareBetween(1, 5, different, 1, 6, U_FOLD_CASE_DEFAULT)) {
383 errln("error: mixed.caseCompare(mixed, 1, 4, different, 1, 5, default)=%ld instead of 0\n", result);
384 }
385
386 /* test caseCompare() - stop in the middle of the sharp s (U+00df) */
387 result=mixed.caseCompare(1, 4, different, 1, 4, U_FOLD_CASE_DEFAULT);
388 if(result<=0) {
389 errln("error: mixed.caseCompare(1, 4, different, 1, 4, default)=%ld instead of positive\n", result);
390 }
391 }
392
393 // test that srcLength=-1 is handled in functions that
394 // take input const UChar */int32_t srcLength (j785)
395 {
396 static const UChar u[]={ 0x61, 0x308, 0x62, 0 };
397 UnicodeString s=UNICODE_STRING("a\\u0308b", 8).unescape();
398
399 if(s.compare(u, -1)!=0 || s.compare(0, 999, u, 0, -1)!=0) {
400 errln("error UnicodeString::compare(..., const UChar *, srcLength=-1) does not work");
401 }
402
403 if(s.compareCodePointOrder(u, -1)!=0 || s.compareCodePointOrder(0, 999, u, 0, -1)!=0) {
404 errln("error UnicodeString::compareCodePointOrder(..., const UChar *, srcLength=-1, ...) does not work");
405 }
406
407 if(s.caseCompare(u, -1, U_FOLD_CASE_DEFAULT)!=0 || s.caseCompare(0, 999, u, 0, -1, U_FOLD_CASE_DEFAULT)!=0) {
408 errln("error UnicodeString::caseCompare(..., const UChar *, srcLength=-1, ...) does not work");
409 }
410
411 if(s.indexOf(u, 1, -1, 0, 999)!=1 || s.indexOf(u+1, -1, 0, 999)!=1 || s.indexOf(u+1, -1, 0)!=1) {
412 errln("error UnicodeString::indexOf(const UChar *, srcLength=-1, ...) does not work");
413 }
414
415 if(s.lastIndexOf(u, 1, -1, 0, 999)!=1 || s.lastIndexOf(u+1, -1, 0, 999)!=1 || s.lastIndexOf(u+1, -1, 0)!=1) {
416 errln("error UnicodeString::lastIndexOf(const UChar *, srcLength=-1, ...) does not work");
417 }
418
419 UnicodeString s2, s3;
420 s2.replace(0, 0, u+1, -1);
421 s3.replace(0, 0, u, 1, -1);
422 if(s.compare(1, 999, s2)!=0 || s2!=s3) {
423 errln("error UnicodeString::replace(..., const UChar *, srcLength=-1, ...) does not work");
424 }
425 }
426 }
427
428 void
429 UnicodeStringTest::TestExtract()
430 {
431 UnicodeString test1("Now is the time for all good men to come to the aid of their country.", "");
432 UnicodeString test2;
433 UChar test3[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
434 char test4[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
435 UnicodeString test5;
436 char test6[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
437
438 test1.extract(11, 12, test2);
439 test1.extract(11, 12, test3);
440 if (test1.extract(11, 12, test4) != 12 || test4[12] != 0) {
441 errln("UnicodeString.extract(char *) failed to return the correct size of destination buffer.");
442 }
443
444 // test proper pinning in extractBetween()
445 test1.extractBetween(-3, 7, test5);
446 if(test5!=UNICODE_STRING("Now is ", 7)) {
447 errln("UnicodeString.extractBetween(-3, 7) did not pin properly.");
448 }
449
450 test1.extractBetween(11, 23, test5);
451 if (test1.extract(60, 71, test6) != 9) {
452 errln("UnicodeString.extract() failed to return the correct size of destination buffer for end of buffer.");
453 }
454 if (test1.extract(11, 12, test6) != 12) {
455 errln("UnicodeString.extract() failed to return the correct size of destination buffer.");
456 }
457
458 // convert test4 back to Unicode for comparison
459 UnicodeString test4b(test4, 12);
460
461 if (test1.extract(11, 12, (char *)NULL) != 12) {
462 errln("UnicodeString.extract(NULL) failed to return the correct size of destination buffer.");
463 }
464 if (test1.extract(11, -1, test6) != 0) {
465 errln("UnicodeString.extract(-1) failed to stop reading the string.");
466 }
467
468 for (int32_t i = 0; i < 12; i++) {
469 if (test1.charAt((int32_t)(11 + i)) != test2.charAt(i)) {
470 errln(UnicodeString("extracting into a UnicodeString failed at position ") + i);
471 break;
472 }
473 if (test1.charAt((int32_t)(11 + i)) != test3[i]) {
474 errln(UnicodeString("extracting into an array of UChar failed at position ") + i);
475 break;
476 }
477 if (((char)test1.charAt((int32_t)(11 + i))) != test4b.charAt(i)) {
478 errln(UnicodeString("extracting into an array of char failed at position ") + i);
479 break;
480 }
481 if (test1.charAt((int32_t)(11 + i)) != test5.charAt(i)) {
482 errln(UnicodeString("extracting with extractBetween failed at position ") + i);
483 break;
484 }
485 }
486
487 // test preflighting and overflows with invariant conversion
488 if (test1.extract(0, 10, (char *)NULL, "") != 10) {
489 errln("UnicodeString.extract(0, 10, (char *)NULL, \"\") != 10");
490 }
491
492 test4[2] = (char)0xff;
493 if (test1.extract(0, 10, test4, 2, "") != 10) {
494 errln("UnicodeString.extract(0, 10, test4, 2, \"\") != 10");
495 }
496 if (test4[2] != (char)0xff) {
497 errln("UnicodeString.extract(0, 10, test4, 2, \"\") overwrote test4[2]");
498 }
499
500 {
501 // test new, NUL-terminating extract() function
502 UnicodeString s("terminate", "");
503 UChar dest[20]={
504 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
505 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5
506 };
507 UErrorCode errorCode;
508 int32_t length;
509
510 errorCode=U_ZERO_ERROR;
511 length=s.extract((UChar *)NULL, 0, errorCode);
512 if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=s.length()) {
513 errln("UnicodeString.extract(NULL, 0)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)", length, s.length(), u_errorName(errorCode));
514 }
515
516 errorCode=U_ZERO_ERROR;
517 length=s.extract(dest, s.length()-1, errorCode);
518 if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=s.length()) {
519 errln("UnicodeString.extract(dest too short)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)",
520 length, u_errorName(errorCode), s.length());
521 }
522
523 errorCode=U_ZERO_ERROR;
524 length=s.extract(dest, s.length(), errorCode);
525 if(errorCode!=U_STRING_NOT_TERMINATED_WARNING || length!=s.length()) {
526 errln("UnicodeString.extract(dest just right without NUL)==%d (%s) expected %d (U_STRING_NOT_TERMINATED_WARNING)",
527 length, u_errorName(errorCode), s.length());
528 }
529 if(dest[length-1]!=s[length-1] || dest[length]!=0xa5) {
530 errln("UnicodeString.extract(dest just right without NUL) did not extract the string correctly");
531 }
532
533 errorCode=U_ZERO_ERROR;
534 length=s.extract(dest, s.length()+1, errorCode);
535 if(errorCode!=U_ZERO_ERROR || length!=s.length()) {
536 errln("UnicodeString.extract(dest large enough)==%d (%s) expected %d (U_ZERO_ERROR)",
537 length, u_errorName(errorCode), s.length());
538 }
539 if(dest[length-1]!=s[length-1] || dest[length]!=0 || dest[length+1]!=0xa5) {
540 errln("UnicodeString.extract(dest large enough) did not extract the string correctly");
541 }
542 }
543
544 {
545 // test new UConverter extract() and constructor
546 UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
547 char buffer[32];
548 static const char expect[]={
549 (char)0xf0, (char)0xaf, (char)0xa6, (char)0x99,
550 (char)0xf0, (char)0x9d, (char)0x85, (char)0x9f,
551 (char)0xc3, (char)0x84,
552 (char)0xe1, (char)0xbb, (char)0x90
553 };
554 UErrorCode errorCode=U_ZERO_ERROR;
555 UConverter *cnv=ucnv_open("UTF-8", &errorCode);
556 int32_t length;
557
558 if(U_SUCCESS(errorCode)) {
559 // test preflighting
560 if( (length=s.extract(NULL, 0, cnv, errorCode))!=13 ||
561 errorCode!=U_BUFFER_OVERFLOW_ERROR
562 ) {
563 errln("UnicodeString::extract(NULL, UConverter) preflighting failed (length=%ld, %s)",
564 length, u_errorName(errorCode));
565 }
566 errorCode=U_ZERO_ERROR;
567 if( (length=s.extract(buffer, 2, cnv, errorCode))!=13 ||
568 errorCode!=U_BUFFER_OVERFLOW_ERROR
569 ) {
570 errln("UnicodeString::extract(too small, UConverter) preflighting failed (length=%ld, %s)",
571 length, u_errorName(errorCode));
572 }
573
574 // try error cases
575 errorCode=U_ZERO_ERROR;
576 if( s.extract(NULL, 2, cnv, errorCode)==13 || U_SUCCESS(errorCode)) {
577 errln("UnicodeString::extract(UConverter) succeeded with an illegal destination");
578 }
579 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
580 if( s.extract(NULL, 0, cnv, errorCode)==13 || U_SUCCESS(errorCode)) {
581 errln("UnicodeString::extract(UConverter) succeeded with a previous error code");
582 }
583 errorCode=U_ZERO_ERROR;
584
585 // extract for real
586 if( (length=s.extract(buffer, sizeof(buffer), cnv, errorCode))!=13 ||
587 uprv_memcmp(buffer, expect, 13)!=0 ||
588 buffer[13]!=0 ||
589 U_FAILURE(errorCode)
590 ) {
591 errln("UnicodeString::extract(UConverter) conversion failed (length=%ld, %s)",
592 length, u_errorName(errorCode));
593 }
594
595 // try the constructor
596 UnicodeString t(expect, sizeof(expect), cnv, errorCode);
597 if(U_FAILURE(errorCode) || s!=t) {
598 errln("UnicodeString(UConverter) conversion failed (%s)",
599 u_errorName(errorCode));
600 }
601
602 ucnv_close(cnv);
603 }
604 }
605 }
606
607 void
608 UnicodeStringTest::TestRemoveReplace()
609 {
610 UnicodeString test1("The rain in Spain stays mainly on the plain");
611 UnicodeString test2("eat SPAMburgers!");
612 UChar test3[] = { 0x53, 0x50, 0x41, 0x4d, 0x4d, 0 };
613 char test4[] = "SPAM";
614 UnicodeString& test5 = test1;
615
616 test1.replace(4, 4, test2, 4, 4);
617 test1.replace(12, 5, test3, 4);
618 test3[4] = 0;
619 test1.replace(17, 4, test3);
620 test1.replace(23, 4, test4);
621 test1.replaceBetween(37, 42, test2, 4, 8);
622
623 if (test1 != "The SPAM in SPAM SPAMs SPAMly on the SPAM")
624 errln("One of the replace methods failed:\n"
625 " expected \"The SPAM in SPAM SPAMs SPAMly on the SPAM\",\n"
626 " got \"" + test1 + "\"");
627
628 test1.remove(21, 1);
629 test1.removeBetween(26, 28);
630
631 if (test1 != "The SPAM in SPAM SPAM SPAM on the SPAM")
632 errln("One of the remove methods failed:\n"
633 " expected \"The SPAM in SPAM SPAM SPAM on the SPAM\",\n"
634 " got \"" + test1 + "\"");
635
636 for (int32_t i = 0; i < test1.length(); i++) {
637 if (test5[i] != 0x53 && test5[i] != 0x50 && test5[i] != 0x41 && test5[i] != 0x4d && test5[i] != 0x20) {
638 test1.setCharAt(i, 0x78);
639 }
640 }
641
642 if (test1 != "xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM")
643 errln("One of the remove methods failed:\n"
644 " expected \"xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM\",\n"
645 " got \"" + test1 + "\"");
646
647 test1.remove();
648 if (test1.length() != 0)
649 errln("Remove() failed: expected empty string, got \"" + test1 + "\"");
650 }
651
652 void
653 UnicodeStringTest::TestSearching()
654 {
655 UnicodeString test1("test test ttest tetest testesteststt");
656 UnicodeString test2("test");
657 UChar testChar = 0x74;
658
659 UChar32 testChar32 = 0x20402;
660 UChar testData[]={
661 // 0 1 2 3 4 5 6 7
662 0xd841, 0xdc02, 0x0071, 0xdc02, 0xd841, 0x0071, 0xd841, 0xdc02,
663
664 // 8 9 10 11 12 13 14 15
665 0x0071, 0x0072, 0xd841, 0xdc02, 0x0071, 0xd841, 0xdc02, 0x0071,
666
667 // 16 17 18 19
668 0xdc02, 0xd841, 0x0073, 0x0000
669 };
670 UnicodeString test3(testData);
671 UnicodeString test4(testChar32);
672
673 uint16_t occurrences = 0;
674 int32_t startPos = 0;
675 for ( ;
676 startPos != -1 && startPos < test1.length();
677 (startPos = test1.indexOf(test2, startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
678 ;
679 if (occurrences != 6)
680 errln("indexOf failed: expected to find 6 occurrences, found " + occurrences);
681
682 for ( occurrences = 0, startPos = 10;
683 startPos != -1 && startPos < test1.length();
684 (startPos = test1.indexOf(test2, startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
685 ;
686 if (occurrences != 4)
687 errln("indexOf with starting offset failed: expected to find 4 occurrences, found " + occurrences);
688
689 int32_t endPos = 28;
690 for ( occurrences = 0, startPos = 5;
691 startPos != -1 && startPos < test1.length();
692 (startPos = test1.indexOf(test2, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
693 ;
694 if (occurrences != 4)
695 errln("indexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences);
696
697 //using UChar32 string
698 for ( startPos=0, occurrences=0;
699 startPos != -1 && startPos < test3.length();
700 (startPos = test3.indexOf(test4, startPos)) != -1 ? (++occurrences, startPos += 2) : 0)
701 ;
702 if (occurrences != 4)
703 errln((UnicodeString)"indexOf failed: expected to find 4 occurrences, found " + occurrences);
704
705 for ( startPos=10, occurrences=0;
706 startPos != -1 && startPos < test3.length();
707 (startPos = test3.indexOf(test4, startPos)) != -1 ? (++occurrences, startPos += 2) : 0)
708 ;
709 if (occurrences != 2)
710 errln("indexOf failed: expected to find 2 occurrences, found " + occurrences);
711 //---
712
713 for ( occurrences = 0, startPos = 0;
714 startPos != -1 && startPos < test1.length();
715 (startPos = test1.indexOf(testChar, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
716 ;
717 if (occurrences != 16)
718 errln("indexOf with character failed: expected to find 16 occurrences, found " + occurrences);
719
720 for ( occurrences = 0, startPos = 10;
721 startPos != -1 && startPos < test1.length();
722 (startPos = test1.indexOf(testChar, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
723 ;
724 if (occurrences != 12)
725 errln("indexOf with character & start offset failed: expected to find 12 occurrences, found " + occurrences);
726
727 for ( occurrences = 0, startPos = 5, endPos = 28;
728 startPos != -1 && startPos < test1.length();
729 (startPos = test1.indexOf(testChar, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
730 ;
731 if (occurrences != 10)
732 errln("indexOf with character & start & end offsets failed: expected to find 10 occurrences, found " + occurrences);
733
734 //testing for UChar32
735 UnicodeString subString;
736 for( occurrences =0, startPos=0; startPos < test3.length(); startPos +=1){
737 subString.append(test3, startPos, test3.length());
738 if(subString.indexOf(testChar32) != -1 ){
739 ++occurrences;
740 }
741 subString.remove();
742 }
743 if (occurrences != 14)
744 errln((UnicodeString)"indexOf failed: expected to find 14 occurrences, found " + occurrences);
745
746 for ( occurrences = 0, startPos = 0;
747 startPos != -1 && startPos < test3.length();
748 (startPos = test3.indexOf(testChar32, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
749 ;
750 if (occurrences != 4)
751 errln((UnicodeString)"indexOf failed: expected to find 4 occurrences, found " + occurrences);
752
753 endPos=test3.length();
754 for ( occurrences = 0, startPos = 5;
755 startPos != -1 && startPos < test3.length();
756 (startPos = test3.indexOf(testChar32, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
757 ;
758 if (occurrences != 3)
759 errln((UnicodeString)"indexOf with character & start & end offsets failed: expected to find 2 occurrences, found " + occurrences);
760 //---
761
762 if(test1.lastIndexOf(test2)!=29) {
763 errln("test1.lastIndexOf(test2)!=29");
764 }
765
766 if(test1.lastIndexOf(test2, 15)!=29 || test1.lastIndexOf(test2, 29)!=29 || test1.lastIndexOf(test2, 30)!=-1) {
767 errln("test1.lastIndexOf(test2, start) failed");
768 }
769
770 for ( occurrences = 0, startPos = 32;
771 startPos != -1;
772 (startPos = test1.lastIndexOf(test2, 5, startPos - 5)) != -1 ? ++occurrences : 0)
773 ;
774 if (occurrences != 4)
775 errln("lastIndexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences);
776
777 for ( occurrences = 0, startPos = 32;
778 startPos != -1;
779 (startPos = test1.lastIndexOf(testChar, 5, startPos - 5)) != -1 ? ++occurrences : 0)
780 ;
781 if (occurrences != 11)
782 errln("lastIndexOf with character & start & end offsets failed: expected to find 11 occurrences, found " + occurrences);
783
784 //testing UChar32
785 startPos=test3.length();
786 for ( occurrences = 0;
787 startPos != -1;
788 (startPos = test3.lastIndexOf(testChar32, 5, startPos - 5)) != -1 ? ++occurrences : 0)
789 ;
790 if (occurrences != 3)
791 errln((UnicodeString)"lastIndexOf with character & start & end offsets failed: expected to find 3 occurrences, found " + occurrences);
792
793
794 for ( occurrences = 0, endPos = test3.length(); endPos > 0; endPos -= 1){
795 subString.remove();
796 subString.append(test3, 0, endPos);
797 if(subString.lastIndexOf(testChar32) != -1 ){
798 ++occurrences;
799 }
800 }
801 if (occurrences != 18)
802 errln((UnicodeString)"indexOf failed: expected to find 18 occurrences, found " + occurrences);
803 //---
804
805 // test that indexOf(UChar32) and lastIndexOf(UChar32)
806 // do not find surrogate code points when they are part of matched pairs
807 // (= part of supplementary code points)
808 // Jitterbug 1542
809 if(test3.indexOf((UChar32)0xd841) != 4 || test3.indexOf((UChar32)0xdc02) != 3) {
810 errln("error: UnicodeString::indexOf(UChar32 surrogate) finds a partial supplementary code point");
811 }
812 if( UnicodeString(test3, 0, 17).lastIndexOf((UChar)0xd841, 0) != 4 ||
813 UnicodeString(test3, 0, 17).lastIndexOf((UChar32)0xd841, 2) != 4 ||
814 test3.lastIndexOf((UChar32)0xd841, 0, 17) != 4 || test3.lastIndexOf((UChar32)0xdc02, 0, 17) != 16
815 ) {
816 errln("error: UnicodeString::lastIndexOf(UChar32 surrogate) finds a partial supplementary code point");
817 }
818 }
819
820 void
821 UnicodeStringTest::TestSpacePadding()
822 {
823 UnicodeString test1("hello");
824 UnicodeString test2(" there");
825 UnicodeString test3("Hi! How ya doin'? Beautiful day, isn't it?");
826 UnicodeString test4;
827 UBool returnVal;
828 UnicodeString expectedValue;
829
830 returnVal = test1.padLeading(15);
831 expectedValue = " hello";
832 if (returnVal == FALSE || test1 != expectedValue)
833 errln("padLeading() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
834
835 returnVal = test2.padTrailing(15);
836 expectedValue = " there ";
837 if (returnVal == FALSE || test2 != expectedValue)
838 errln("padTrailing() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
839
840 expectedValue = test3;
841 returnVal = test3.padTrailing(15);
842 if (returnVal == TRUE || test3 != expectedValue)
843 errln("padTrailing() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
844
845 expectedValue = "hello";
846 test4.setTo(test1).trim();
847
848 if (test4 != expectedValue || test1 == expectedValue || test4 != expectedValue)
849 errln("trim(UnicodeString&) failed");
850
851 test1.trim();
852 if (test1 != expectedValue)
853 errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
854
855 test2.trim();
856 expectedValue = "there";
857 if (test2 != expectedValue)
858 errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
859
860 test3.trim();
861 expectedValue = "Hi! How ya doin'? Beautiful day, isn't it?";
862 if (test3 != expectedValue)
863 errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
864
865 returnVal = test1.truncate(15);
866 expectedValue = "hello";
867 if (returnVal == TRUE || test1 != expectedValue)
868 errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
869
870 returnVal = test2.truncate(15);
871 expectedValue = "there";
872 if (returnVal == TRUE || test2 != expectedValue)
873 errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
874
875 returnVal = test3.truncate(15);
876 expectedValue = "Hi! How ya doi";
877 if (returnVal == FALSE || test3 != expectedValue)
878 errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
879 }
880
881 void
882 UnicodeStringTest::TestPrefixAndSuffix()
883 {
884 UnicodeString test1("Now is the time for all good men to come to the aid of their country.");
885 UnicodeString test2("Now");
886 UnicodeString test3("country.");
887 UnicodeString test4("count");
888
889 if (!test1.startsWith(test2) || !test1.startsWith(test2, 0, test2.length())) {
890 errln("startsWith() failed: \"" + test2 + "\" should be a prefix of \"" + test1 + "\".");
891 }
892
893 if (test1.startsWith(test3) ||
894 test1.startsWith(test3.getBuffer(), test3.length()) ||
895 test1.startsWith(test3.getTerminatedBuffer(), 0, -1)
896 ) {
897 errln("startsWith() failed: \"" + test3 + "\" shouldn't be a prefix of \"" + test1 + "\".");
898 }
899
900 if (test1.endsWith(test2)) {
901 errln("endsWith() failed: \"" + test2 + "\" shouldn't be a suffix of \"" + test1 + "\".");
902 }
903
904 if (!test1.endsWith(test3)) {
905 errln("endsWith(test3) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
906 }
907 if (!test1.endsWith(test3, 0, INT32_MAX)) {
908 errln("endsWith(test3, 0, INT32_MAX) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
909 }
910
911 if(!test1.endsWith(test3.getBuffer(), test3.length())) {
912 errln("endsWith(test3.getBuffer(), test3.length()) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
913 }
914 if(!test1.endsWith(test3.getTerminatedBuffer(), 0, -1)) {
915 errln("endsWith(test3.getTerminatedBuffer(), 0, -1) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
916 }
917
918 if (!test3.startsWith(test4)) {
919 errln("endsWith(test4) failed: \"" + test4 + "\" should be a prefix of \"" + test3 + "\".");
920 }
921
922 if (test4.startsWith(test3)) {
923 errln("startsWith(test3) failed: \"" + test3 + "\" shouldn't be a prefix of \"" + test4 + "\".");
924 }
925 }
926
927 void
928 UnicodeStringTest::TestFindAndReplace()
929 {
930 UnicodeString test1("One potato, two potato, three potato, four\n");
931 UnicodeString test2("potato");
932 UnicodeString test3("MISSISSIPPI");
933
934 UnicodeString expectedValue;
935
936 test1.findAndReplace(test2, test3);
937 expectedValue = "One MISSISSIPPI, two MISSISSIPPI, three MISSISSIPPI, four\n";
938 if (test1 != expectedValue)
939 errln("findAndReplace failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
940 test1.findAndReplace(2, 32, test3, test2);
941 expectedValue = "One potato, two potato, three MISSISSIPPI, four\n";
942 if (test1 != expectedValue)
943 errln("findAndReplace failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
944 }
945
946 void
947 UnicodeStringTest::TestReverse()
948 {
949 UnicodeString test("backwards words say to used I");
950
951 test.reverse();
952 test.reverse(2, 4);
953 test.reverse(7, 2);
954 test.reverse(10, 3);
955 test.reverse(14, 5);
956 test.reverse(20, 9);
957
958 if (test != "I used to say words backwards")
959 errln("reverse() failed: Expected \"I used to say words backwards\",\n got \""
960 + test + "\"");
961
962 test=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
963 test.reverse();
964 if(test.char32At(0)!=0x1ed0 || test.char32At(1)!=0xc4 || test.char32At(2)!=0x1d15f || test.char32At(4)!=0x2f999) {
965 errln("reverse() failed with supplementary characters");
966 }
967 }
968
969 void
970 UnicodeStringTest::TestMiscellaneous()
971 {
972 UnicodeString test1("This is a test");
973 UnicodeString test2("This is a test");
974 UnicodeString test3("Me too!");
975
976 // test getBuffer(minCapacity) and releaseBuffer()
977 test1=UnicodeString(); // make sure that it starts with its stackBuffer
978 UChar *p=test1.getBuffer(20);
979 if(test1.getCapacity()<20) {
980 errln("UnicodeString::getBuffer(20).getCapacity()<20");
981 }
982
983 test1.append((UChar)7); // must not be able to modify the string here
984 test1.setCharAt(3, 7);
985 test1.reverse();
986 if( test1.length()!=0 ||
987 test1.charAt(0)!=0xffff || test1.charAt(3)!=0xffff ||
988 test1.getBuffer(10)!=0 || test1.getBuffer()!=0
989 ) {
990 errln("UnicodeString::getBuffer(minCapacity) allows read or write access to the UnicodeString");
991 }
992
993 p[0]=1;
994 p[1]=2;
995 p[2]=3;
996 test1.releaseBuffer(3);
997 test1.append((UChar)4);
998
999 if(test1.length()!=4 || test1.charAt(0)!=1 || test1.charAt(1)!=2 || test1.charAt(2)!=3 || test1.charAt(3)!=4) {
1000 errln("UnicodeString::releaseBuffer(newLength) does not properly reallow access to the UnicodeString");
1001 }
1002
1003 // test releaseBuffer() without getBuffer(minCapacity) - must not have any effect
1004 test1.releaseBuffer(1);
1005 if(test1.length()!=4 || test1.charAt(0)!=1 || test1.charAt(1)!=2 || test1.charAt(2)!=3 || test1.charAt(3)!=4) {
1006 errln("UnicodeString::releaseBuffer(newLength) without getBuffer(minCapacity) changed the UnicodeString");
1007 }
1008
1009 // test getBuffer(const)
1010 const UChar *q=test1.getBuffer(), *r=test1.getBuffer();
1011 if( test1.length()!=4 ||
1012 q[0]!=1 || q[1]!=2 || q[2]!=3 || q[3]!=4 ||
1013 r[0]!=1 || r[1]!=2 || r[2]!=3 || r[3]!=4
1014 ) {
1015 errln("UnicodeString::getBuffer(const) does not return a usable buffer pointer");
1016 }
1017
1018 // test releaseBuffer() with a NUL-terminated buffer
1019 test1.getBuffer(20)[2]=0;
1020 test1.releaseBuffer(); // implicit -1
1021 if(test1.length()!=2 || test1.charAt(0)!=1 || test1.charAt(1) !=2) {
1022 errln("UnicodeString::releaseBuffer(-1) does not properly set the length of the UnicodeString");
1023 }
1024
1025 // test releaseBuffer() with a non-NUL-terminated buffer
1026 p=test1.getBuffer(256);
1027 for(int32_t i=0; i<test1.getCapacity(); ++i) {
1028 p[i]=(UChar)1; // fill the buffer with all non-NUL code units
1029 }
1030 test1.releaseBuffer(); // implicit -1
1031 if(test1.length()!=test1.getCapacity() || test1.charAt(1)!=1 || test1.charAt(100)!=1 || test1.charAt(test1.getCapacity()-1)!=1) {
1032 errln("UnicodeString::releaseBuffer(-1 but no NUL) does not properly set the length of the UnicodeString");
1033 }
1034
1035 // test getTerminatedBuffer()
1036 test1=UnicodeString("This is another test.", "");
1037 test2=UnicodeString("This is another test.", "");
1038 q=test1.getTerminatedBuffer();
1039 if(q[test1.length()]!=0 || test1!=test2 || test2.compare(q, -1)!=0) {
1040 errln("getTerminatedBuffer()[length]!=0");
1041 }
1042
1043 const UChar u[]={ 5, 6, 7, 8, 0 };
1044 test1.setTo(FALSE, u, 3);
1045 q=test1.getTerminatedBuffer();
1046 if(q==u || q[0]!=5 || q[1]!=6 || q[2]!=7 || q[3]!=0) {
1047 errln("UnicodeString(u[3]).getTerminatedBuffer() returns a bad buffer");
1048 }
1049
1050 test1.setTo(TRUE, u, -1);
1051 q=test1.getTerminatedBuffer();
1052 if(q!=u || test1.length()!=4 || q[3]!=8 || q[4]!=0) {
1053 errln("UnicodeString(u[-1]).getTerminatedBuffer() returns a bad buffer");
1054 }
1055
1056 test1=UNICODE_STRING("la", 2);
1057 test1.append(UNICODE_STRING(" lila", 5).getTerminatedBuffer(), 0, -1);
1058 if(test1!=UNICODE_STRING("la lila", 7)) {
1059 errln("UnicodeString::append(const UChar *, start, length) failed");
1060 }
1061
1062 test1.insert(3, UNICODE_STRING("dudum ", 6), 0, INT32_MAX);
1063 if(test1!=UNICODE_STRING("la dudum lila", 13)) {
1064 errln("UnicodeString::insert(start, const UniStr &, start, length) failed");
1065 }
1066
1067 static const UChar ucs[]={ 0x68, 0x6d, 0x20, 0 };
1068 test1.insert(9, ucs, -1);
1069 if(test1!=UNICODE_STRING("la dudum hm lila", 16)) {
1070 errln("UnicodeString::insert(start, const UChar *, length) failed");
1071 }
1072
1073 test1.replace(9, 2, (UChar)0x2b);
1074 if(test1!=UNICODE_STRING("la dudum + lila", 15)) {
1075 errln("UnicodeString::replace(start, length, UChar) failed");
1076 }
1077
1078 if(test1.hasMetaData() || UnicodeString().hasMetaData()) {
1079 errln("UnicodeString::hasMetaData() returns TRUE");
1080 }
1081 }
1082
1083 void
1084 UnicodeStringTest::TestStackAllocation()
1085 {
1086 UChar testString[] ={
1087 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x72, 0x61, 0x7a, 0x79, 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0 };
1088 UChar guardWord = 0x4DED;
1089 UnicodeString* test = 0;
1090
1091 test = new UnicodeString(testString);
1092 if (*test != "This is a crazy test.")
1093 errln("Test string failed to initialize properly.");
1094 if (guardWord != 0x04DED)
1095 errln("Test string initialization overwrote guard word!");
1096
1097 test->insert(8, "only ");
1098 test->remove(15, 6);
1099 if (*test != "This is only a test.")
1100 errln("Manipulation of test string failed to work right.");
1101 if (guardWord != 0x4DED)
1102 errln("Manipulation of test string overwrote guard word!");
1103
1104 // we have to deinitialize and release the backing store by calling the destructor
1105 // explicitly, since we can't overload operator delete
1106 delete test;
1107
1108 UChar workingBuffer[] = {
1109 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
1110 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20,
1111 0x63, 0x6f, 0x6d, 0x65, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1113 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1114 UChar guardWord2 = 0x4DED;
1115
1116 test = new UnicodeString(workingBuffer, 35, 100);
1117 if (*test != "Now is the time for all men to come")
1118 errln("Stack-allocated backing store failed to initialize correctly.");
1119 if (guardWord2 != 0x4DED)
1120 errln("Stack-allocated backing store overwrote guard word!");
1121
1122 test->insert(24, "good ");
1123 if (*test != "Now is the time for all good men to come")
1124 errln("insert() on stack-allocated UnicodeString didn't work right");
1125 if (guardWord2 != 0x4DED)
1126 errln("insert() on stack-allocated UnicodeString overwrote guard word!");
1127
1128 if (workingBuffer[24] != 0x67)
1129 errln("insert() on stack-allocated UnicodeString didn't affect backing store");
1130
1131 *test += " to the aid of their country.";
1132 if (*test != "Now is the time for all good men to come to the aid of their country.")
1133 errln("Stack-allocated UnicodeString overflow didn't work");
1134 if (guardWord2 != 0x4DED)
1135 errln("Stack-allocated UnicodeString overflow overwrote guard word!");
1136
1137 *test = "ha!";
1138 if (*test != "ha!")
1139 errln("Assignment to stack-allocated UnicodeString didn't work");
1140 if (workingBuffer[0] != 0x4e)
1141 errln("Change to UnicodeString after overflow are still affecting original buffer");
1142 if (guardWord2 != 0x4DED)
1143 errln("Change to UnicodeString after overflow overwrote guard word!");
1144
1145 // test read-only aliasing with setTo()
1146 workingBuffer[0] = 0x20ac;
1147 workingBuffer[1] = 0x125;
1148 workingBuffer[2] = 0;
1149 test->setTo(TRUE, workingBuffer, 2);
1150 if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x125) {
1151 errln("UnicodeString.setTo(readonly alias) does not alias correctly");
1152 }
1153
1154 UnicodeString *c=(UnicodeString *)test->clone();
1155
1156 workingBuffer[1] = 0x109;
1157 if(test->charAt(1) != 0x109) {
1158 errln("UnicodeString.setTo(readonly alias) made a copy: did not see change in buffer");
1159 }
1160
1161 if(c->length() != 2 || c->charAt(1) != 0x125) {
1162 errln("clone(alias) did not copy the buffer");
1163 }
1164 delete c;
1165
1166 test->setTo(TRUE, workingBuffer, -1);
1167 if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x109) {
1168 errln("UnicodeString.setTo(readonly alias, length -1) does not alias correctly");
1169 }
1170
1171 test->setTo(FALSE, workingBuffer, -1);
1172 if(!test->isBogus()) {
1173 errln("UnicodeString.setTo(unterminated readonly alias, length -1) does not result in isBogus()");
1174 }
1175
1176 delete test;
1177
1178 test=new UnicodeString();
1179 UChar buffer[]={0x0061, 0x0062, 0x20ac, 0x0043, 0x0042, 0x0000};
1180 test->setTo(buffer, 4, 10);
1181 if(test->length() !=4 || test->charAt(0) != 0x0061 || test->charAt(1) != 0x0062 ||
1182 test->charAt(2) != 0x20ac || test->charAt(3) != 0x0043){
1183 errln((UnicodeString)"UnicodeString.setTo(UChar*, length, capacity) does not work correctly\n" + prettify(*test));
1184 }
1185 delete test;
1186
1187
1188 // test the UChar32 constructor
1189 UnicodeString c32Test((UChar32)0x10ff2a);
1190 if( c32Test.length() != UTF_CHAR_LENGTH(0x10ff2a) ||
1191 c32Test.char32At(c32Test.length() - 1) != 0x10ff2a
1192 ) {
1193 errln("The UnicodeString(UChar32) constructor does not work with a 0x10ff2a filler");
1194 }
1195
1196 // test the (new) capacity constructor
1197 UnicodeString capTest(5, (UChar32)0x2a, 5);
1198 if( capTest.length() != 5 * UTF_CHAR_LENGTH(0x2a) ||
1199 capTest.char32At(0) != 0x2a ||
1200 capTest.char32At(4) != 0x2a
1201 ) {
1202 errln("The UnicodeString capacity constructor does not work with an ASCII filler");
1203 }
1204
1205 capTest = UnicodeString(5, (UChar32)0x10ff2a, 5);
1206 if( capTest.length() != 5 * UTF_CHAR_LENGTH(0x10ff2a) ||
1207 capTest.char32At(0) != 0x10ff2a ||
1208 capTest.char32At(4) != 0x10ff2a
1209 ) {
1210 errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
1211 }
1212
1213 capTest = UnicodeString(5, (UChar32)0, 0);
1214 if(capTest.length() != 0) {
1215 errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
1216 }
1217 }
1218
1219 /**
1220 * Test the unescape() function.
1221 */
1222 void UnicodeStringTest::TestUnescape(void) {
1223 UnicodeString IN("abc\\u4567 \\n\\r \\U00101234xyz\\x1\\x{5289}\\x1b");
1224 UnicodeString OUT("abc");
1225 OUT.append((UChar)0x4567);
1226 OUT.append(" ");
1227 OUT.append((UChar)0xA);
1228 OUT.append((UChar)0xD);
1229 OUT.append(" ");
1230 OUT.append((UChar32)0x00101234);
1231 OUT.append("xyz");
1232 OUT.append((UChar32)1).append((UChar32)0x5289).append((UChar)0x1b);
1233 UnicodeString result = IN.unescape();
1234 if (result != OUT) {
1235 errln("FAIL: " + prettify(IN) + ".unescape() -> " +
1236 prettify(result) + ", expected " +
1237 prettify(OUT));
1238 }
1239
1240 // test that an empty string is returned in case of an error
1241 if (!UNICODE_STRING("wrong \\u sequence", 17).unescape().isEmpty()) {
1242 errln("FAIL: unescaping of a string with an illegal escape sequence did not return an empty string");
1243 }
1244 }
1245
1246 /* test code point counting functions --------------------------------------- */
1247
1248 /* reference implementation of UnicodeString::hasMoreChar32Than() */
1249 static int32_t
1250 _refUnicodeStringHasMoreChar32Than(const UnicodeString &s, int32_t start, int32_t length, int32_t number) {
1251 int32_t count=s.countChar32(start, length);
1252 return count>number;
1253 }
1254
1255 /* compare the real function against the reference */
1256 void
1257 UnicodeStringTest::_testUnicodeStringHasMoreChar32Than(const UnicodeString &s, int32_t start, int32_t length, int32_t number) {
1258 if(s.hasMoreChar32Than(start, length, number)!=_refUnicodeStringHasMoreChar32Than(s, start, length, number)) {
1259 errln("hasMoreChar32Than(%d, %d, %d)=%hd is wrong\n",
1260 start, length, number, s.hasMoreChar32Than(start, length, number));
1261 }
1262 }
1263
1264 void
1265 UnicodeStringTest::TestCountChar32(void) {
1266 {
1267 UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
1268
1269 // test countChar32()
1270 // note that this also calls and tests u_countChar32(length>=0)
1271 if(
1272 s.countChar32()!=4 ||
1273 s.countChar32(1)!=4 ||
1274 s.countChar32(2)!=3 ||
1275 s.countChar32(2, 3)!=2 ||
1276 s.countChar32(2, 0)!=0
1277 ) {
1278 errln("UnicodeString::countChar32() failed");
1279 }
1280
1281 // NUL-terminate the string buffer and test u_countChar32(length=-1)
1282 const UChar *buffer=s.getTerminatedBuffer();
1283 if(
1284 u_countChar32(buffer, -1)!=4 ||
1285 u_countChar32(buffer+1, -1)!=4 ||
1286 u_countChar32(buffer+2, -1)!=3 ||
1287 u_countChar32(buffer+3, -1)!=3 ||
1288 u_countChar32(buffer+4, -1)!=2 ||
1289 u_countChar32(buffer+5, -1)!=1 ||
1290 u_countChar32(buffer+6, -1)!=0
1291 ) {
1292 errln("u_countChar32(length=-1) failed");
1293 }
1294
1295 // test u_countChar32() with bad input
1296 if(u_countChar32(NULL, 5)!=0 || u_countChar32(buffer, -2)!=0) {
1297 errln("u_countChar32(bad input) failed (returned non-zero counts)");
1298 }
1299 }
1300
1301 /* test data and variables for hasMoreChar32Than() */
1302 static const UChar str[]={
1303 0x61, 0x62, 0xd800, 0xdc00,
1304 0xd801, 0xdc01, 0x63, 0xd802,
1305 0x64, 0xdc03, 0x65, 0x66,
1306 0xd804, 0xdc04, 0xd805, 0xdc05,
1307 0x67
1308 };
1309 UnicodeString string(str, LENGTHOF(str));
1310 int32_t start, length, number;
1311
1312 /* test hasMoreChar32Than() */
1313 for(length=string.length(); length>=0; --length) {
1314 for(start=0; start<=length; ++start) {
1315 for(number=-1; number<=((length-start)+2); ++number) {
1316 _testUnicodeStringHasMoreChar32Than(string, start, length-start, number);
1317 }
1318 }
1319 }
1320
1321 /* test hasMoreChar32Than() with pinning */
1322 for(start=-1; start<=string.length()+1; ++start) {
1323 for(number=-1; number<=((string.length()-start)+2); ++number) {
1324 _testUnicodeStringHasMoreChar32Than(string, start, 0x7fffffff, number);
1325 }
1326 }
1327
1328 /* test hasMoreChar32Than() with a bogus string */
1329 string.setToBogus();
1330 for(length=-1; length<=1; ++length) {
1331 for(start=-1; start<=length; ++start) {
1332 for(number=-1; number<=((length-start)+2); ++number) {
1333 _testUnicodeStringHasMoreChar32Than(string, start, length-start, number);
1334 }
1335 }
1336 }
1337 }
1338
1339 void
1340 UnicodeStringTest::TestBogus() {
1341 UnicodeString test1("This is a test");
1342 UnicodeString test2("This is a test");
1343 UnicodeString test3("Me too!");
1344
1345 // test isBogus() and setToBogus()
1346 if (test1.isBogus() || test2.isBogus() || test3.isBogus()) {
1347 errln("A string returned TRUE for isBogus()!");
1348 }
1349
1350 // NULL pointers are treated like empty strings
1351 // use other illegal arguments to make a bogus string
1352 test3.setTo(FALSE, test1.getBuffer(), -2);
1353 if(!test3.isBogus()) {
1354 errln("A bogus string returned FALSE for isBogus()!");
1355 }
1356 if (test1.hashCode() != test2.hashCode() || test1.hashCode() == test3.hashCode()) {
1357 errln("hashCode() failed");
1358 }
1359 if(test3.getBuffer()!=0 || test3.getBuffer(20)!=0 || test3.getTerminatedBuffer()!=0) {
1360 errln("bogus.getBuffer()!=0");
1361 }
1362
1363 // verify that non-assignment modifications fail and do not revive a bogus string
1364 test3.setToBogus();
1365 test3.append((UChar)0x61);
1366 if(!test3.isBogus() || test3.getBuffer()!=0) {
1367 errln("bogus.append('a') worked but must not");
1368 }
1369
1370 test3.setToBogus();
1371 test3.findAndReplace(UnicodeString((UChar)0x61), test2);
1372 if(!test3.isBogus() || test3.getBuffer()!=0) {
1373 errln("bogus.findAndReplace() worked but must not");
1374 }
1375
1376 test3.setToBogus();
1377 test3.trim();
1378 if(!test3.isBogus() || test3.getBuffer()!=0) {
1379 errln("bogus.trim() revived bogus but must not");
1380 }
1381
1382 test3.setToBogus();
1383 test3.remove(1);
1384 if(!test3.isBogus() || test3.getBuffer()!=0) {
1385 errln("bogus.remove(1) revived bogus but must not");
1386 }
1387
1388 test3.setToBogus();
1389 if(!test3.setCharAt(0, 0x62).isBogus() || !test3.isEmpty()) {
1390 errln("bogus.setCharAt(0, 'b') worked but must not");
1391 }
1392
1393 test3.setToBogus();
1394 if(test3.truncate(1) || !test3.isBogus() || !test3.isEmpty()) {
1395 errln("bogus.truncate(1) revived bogus but must not");
1396 }
1397
1398 // verify that assignments revive a bogus string
1399 test3.setToBogus();
1400 if(!test3.isBogus() || (test3=test1).isBogus() || test3!=test1) {
1401 errln("bogus.operator=() failed");
1402 }
1403
1404 test3.setToBogus();
1405 if(!test3.isBogus() || test3.fastCopyFrom(test1).isBogus() || test3!=test1) {
1406 errln("bogus.fastCopyFrom() failed");
1407 }
1408
1409 test3.setToBogus();
1410 if(!test3.isBogus() || test3.setTo(test1).isBogus() || test3!=test1) {
1411 errln("bogus.setTo(UniStr) failed");
1412 }
1413
1414 test3.setToBogus();
1415 if(!test3.isBogus() || test3.setTo(test1, 0).isBogus() || test3!=test1) {
1416 errln("bogus.setTo(UniStr, 0) failed");
1417 }
1418
1419 test3.setToBogus();
1420 if(!test3.isBogus() || test3.setTo(test1, 0, 0x7fffffff).isBogus() || test3!=test1) {
1421 errln("bogus.setTo(UniStr, 0, len) failed");
1422 }
1423
1424 test3.setToBogus();
1425 if(!test3.isBogus() || test3.setTo(test1.getBuffer(), test1.length()).isBogus() || test3!=test1) {
1426 errln("bogus.setTo(const UChar *, len) failed");
1427 }
1428
1429 test3.setToBogus();
1430 if(!test3.isBogus() || test3.setTo((UChar)0x2028).isBogus() || test3!=UnicodeString((UChar)0x2028)) {
1431 errln("bogus.setTo(UChar) failed");
1432 }
1433
1434 test3.setToBogus();
1435 if(!test3.isBogus() || test3.setTo((UChar32)0x1d157).isBogus() || test3!=UnicodeString((UChar32)0x1d157)) {
1436 errln("bogus.setTo(UChar32) failed");
1437 }
1438
1439 test3.setToBogus();
1440 if(!test3.isBogus() || test3.setTo(FALSE, test1.getBuffer(), test1.length()).isBogus() || test3!=test1) {
1441 errln("bogus.setTo(readonly alias) failed");
1442 }
1443
1444 // writable alias to another string's buffer: very bad idea, just convenient for this test
1445 test3.setToBogus();
1446 if(!test3.isBogus() || test3.setTo((UChar *)test1.getBuffer(), test1.length(), test1.getCapacity()).isBogus() || test3!=test1) {
1447 errln("bogus.setTo(writable alias) failed");
1448 }
1449
1450 // verify simple, documented ways to turn a bogus string into an empty one
1451 test3.setToBogus();
1452 if(!test3.isBogus() || (test3=UnicodeString()).isBogus() || !test3.isEmpty()) {
1453 errln("bogus.operator=(UnicodeString()) failed");
1454 }
1455
1456 test3.setToBogus();
1457 if(!test3.isBogus() || test3.setTo(UnicodeString()).isBogus() || !test3.isEmpty()) {
1458 errln("bogus.setTo(UnicodeString()) failed");
1459 }
1460
1461 test3.setToBogus();
1462 if(test3.remove().isBogus() || test3.getBuffer()==0 || !test3.isEmpty()) {
1463 errln("bogus.remove() failed");
1464 }
1465
1466 test3.setToBogus();
1467 if(test3.remove(0, INT32_MAX).isBogus() || test3.getBuffer()==0 || !test3.isEmpty()) {
1468 errln("bogus.remove(0, INT32_MAX) failed");
1469 }
1470
1471 test3.setToBogus();
1472 if(test3.truncate(0) || test3.isBogus() || !test3.isEmpty()) {
1473 errln("bogus.truncate(0) failed");
1474 }
1475
1476 test3.setToBogus();
1477 if(!test3.isBogus() || test3.setTo((UChar32)-1).isBogus() || !test3.isEmpty()) {
1478 errln("bogus.setTo((UChar32)-1) failed");
1479 }
1480
1481 static const UChar nul=0;
1482
1483 test3.setToBogus();
1484 if(!test3.isBogus() || test3.setTo(&nul, 0).isBogus() || !test3.isEmpty()) {
1485 errln("bogus.setTo(&nul, 0) failed");
1486 }
1487
1488 test3.setToBogus();
1489 if(!test3.isBogus() || test3.getBuffer()!=0) {
1490 errln("setToBogus() failed to make a string bogus");
1491 }
1492
1493 test3.setToBogus();
1494 if(test1.isBogus() || !(test1=test3).isBogus()) {
1495 errln("normal=bogus failed to make the left string bogus");
1496 }
1497
1498 // test that NULL primitive input string values are treated like
1499 // empty strings, not errors (bogus)
1500 test2.setTo((UChar32)0x10005);
1501 if(test2.insert(1, NULL, 1).length()!=2) {
1502 errln("UniStr.insert(...NULL...) should not modify the string but does");
1503 }
1504
1505 UErrorCode errorCode=U_ZERO_ERROR;
1506 UnicodeString
1507 test4((const UChar *)NULL),
1508 test5(TRUE, (const UChar *)NULL, 1),
1509 test6((UChar *)NULL, 5, 5),
1510 test7((const char *)NULL, 3, NULL, errorCode);
1511 if(test4.isBogus() || test5.isBogus() || test6.isBogus() || test7.isBogus()) {
1512 errln("a constructor set to bogus for a NULL input string, should be empty");
1513 }
1514
1515 test4.setTo(NULL, 3);
1516 test5.setTo(TRUE, (const UChar *)NULL, 1);
1517 test6.setTo((UChar *)NULL, 5, 5);
1518 if(test4.isBogus() || test5.isBogus() || test6.isBogus()) {
1519 errln("a setTo() set to bogus for a NULL input string, should be empty");
1520 }
1521
1522 // test that bogus==bogus<any
1523 if(test1!=test3 || test1.compare(test3)!=0) {
1524 errln("bogus==bogus failed");
1525 }
1526
1527 test2.remove();
1528 if(test1>=test2 || !(test2>test1) || test1.compare(test2)>=0 || !(test2.compare(test1)>0)) {
1529 errln("bogus<empty failed");
1530 }
1531 }
1532
1533 // StringEnumeration ------------------------------------------------------- ***
1534 // most of StringEnumeration is tested elsewhere
1535 // this test improves code coverage
1536
1537 static const char *const
1538 testEnumStrings[]={
1539 "a",
1540 "b",
1541 "c",
1542 "this is a long string which helps us test some buffer limits",
1543 "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
1544 };
1545
1546 class TestEnumeration : public StringEnumeration {
1547 public:
1548 TestEnumeration() : i(0) {}
1549
1550 virtual int32_t count(UErrorCode& /*status*/) const {
1551 return LENGTHOF(testEnumStrings);
1552 }
1553
1554 virtual const UnicodeString *snext(UErrorCode &status) {
1555 if(U_SUCCESS(status) && i<LENGTHOF(testEnumStrings)) {
1556 unistr=UnicodeString(testEnumStrings[i++], "");
1557 return &unistr;
1558 }
1559
1560 return NULL;
1561 }
1562
1563 virtual void reset(UErrorCode& /*status*/) {
1564 i=0;
1565 }
1566
1567 static inline UClassID getStaticClassID() {
1568 return (UClassID)&fgClassID;
1569 }
1570 virtual UClassID getDynamicClassID() const {
1571 return getStaticClassID();
1572 }
1573
1574 private:
1575 static const char fgClassID;
1576
1577 int32_t i, length;
1578 };
1579
1580 const char TestEnumeration::fgClassID=0;
1581
1582 void
1583 UnicodeStringTest::TestStringEnumeration() {
1584 UnicodeString s;
1585 TestEnumeration ten;
1586 int32_t i, length;
1587 UErrorCode status;
1588
1589 const UChar *pu;
1590 const char *pc;
1591
1592 // test the next() default implementation and ensureCharsCapacity()
1593 for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
1594 status=U_ZERO_ERROR;
1595 pc=ten.next(&length, status);
1596 s=UnicodeString(testEnumStrings[i], "");
1597 if(U_FAILURE(status) || pc==NULL || length!=s.length() || UnicodeString(pc, length, "")!=s) {
1598 errln("StringEnumeration.next(%d) failed", i);
1599 }
1600 }
1601 status=U_ZERO_ERROR;
1602 if(ten.next(&length, status)!=NULL) {
1603 errln("StringEnumeration.next(done)!=NULL");
1604 }
1605
1606 // test the unext() default implementation
1607 ten.reset(status);
1608 for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
1609 status=U_ZERO_ERROR;
1610 pu=ten.unext(&length, status);
1611 s=UnicodeString(testEnumStrings[i], "");
1612 if(U_FAILURE(status) || pu==NULL || length!=s.length() || UnicodeString(TRUE, pu, length)!=s) {
1613 errln("StringEnumeration.unext(%d) failed", i);
1614 }
1615 }
1616 status=U_ZERO_ERROR;
1617 if(ten.unext(&length, status)!=NULL) {
1618 errln("StringEnumeration.unext(done)!=NULL");
1619 }
1620
1621 // test that the default clone() implementation works, and returns NULL
1622 if(ten.clone()!=NULL) {
1623 errln("StringEnumeration.clone()!=NULL");
1624 }
1625 }