1 /********************************************************************
3 * Copyright (c) 1997-2003, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
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"
16 #include "unicode/ustream.h"
18 #if U_IOSTREAM_SOURCE >= 199711
21 #elif U_IOSTREAM_SOURCE >= 198506
27 #define LENGTHOF(array) (sizeof(array)/sizeof((array)[0]))
29 void UnicodeStringTest::runIndexedTest( int32_t index
, UBool exec
, const char* &name
, char *par
)
31 if (exec
) logln("TestSuite UnicodeStringTest: ");
33 case 0: name
= "TestBasicManipulation"; if (exec
) TestBasicManipulation(); break;
34 case 1: name
= "TestCompare"; if (exec
) TestCompare(); break;
35 case 2: name
= "TestExtract"; if (exec
) TestExtract(); break;
36 case 3: name
= "TestRemoveReplace"; if (exec
) TestRemoveReplace(); break;
38 name
= "StringCaseTest";
40 logln("StringCaseTest---"); logln("");
45 case 5: name
= "TestSearching"; if (exec
) TestSearching(); break;
46 case 6: name
= "TestSpacePadding"; if (exec
) TestSpacePadding(); break;
47 case 7: name
= "TestPrefixAndSuffix"; if (exec
) TestPrefixAndSuffix(); break;
48 case 8: name
= "TestFindAndReplace"; if (exec
) TestFindAndReplace(); break;
49 case 9: name
= "TestBogus"; if (exec
) TestBogus(); break;
50 case 10: name
= "TestReverse"; if (exec
) TestReverse(); break;
51 case 11: name
= "TestMiscellaneous"; if (exec
) TestMiscellaneous(); break;
52 case 12: name
= "TestStackAllocation"; if (exec
) TestStackAllocation(); break;
53 case 13: name
= "TestUnescape"; if (exec
) TestUnescape(); break;
54 case 14: name
= "TestCountChar32"; if (exec
) TestCountChar32(); break;
56 default: name
= ""; break; //needed to end loop
61 UnicodeStringTest::TestBasicManipulation()
63 UnicodeString
test1("Now is the time for all men to come swiftly to the aid of the party.\n");
64 UnicodeString expectedValue
;
67 c
=(UnicodeString
*)test1
.clone();
68 test1
.insert(24, "good ");
69 expectedValue
= "Now is the time for all good men to come swiftly to the aid of the party.\n";
70 if (test1
!= expectedValue
)
71 errln("insert() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test1
+ "\"");
73 c
->insert(24, "good ");
74 if(*c
!= expectedValue
) {
75 errln("clone()->insert() failed: expected \"" + expectedValue
+ "\"\n,got \"" + *c
+ "\"");
80 expectedValue
= "Now is the time for all good men to come to the aid of the party.\n";
81 if (test1
!= expectedValue
)
82 errln("remove() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test1
+ "\"");
84 test1
.replace(58, 6, "ir country");
85 expectedValue
= "Now is the time for all good men to come to the aid of their country.\n";
86 if (test1
!= expectedValue
)
87 errln("replace() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test1
+ "\"");
90 test1
.extract(0, 15, temp
);
92 UnicodeString
test2(temp
, 15);
94 expectedValue
= "Now is the time";
95 if (test2
!= expectedValue
)
96 errln("extract() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test2
+ "\"");
98 test2
+= " for me to go!\n";
99 expectedValue
= "Now is the time for me to go!\n";
100 if (test2
!= expectedValue
)
101 errln("operator+=() failed: expected \"" + expectedValue
+ "\"\n,got \"" + test2
+ "\"");
103 if (test1
.length() != 70)
104 errln("length() failed: expected 70, got " + test1
.length());
105 if (test2
.length() != 30)
106 errln("length() failed: expected 30, got " + test2
.length());
109 test3
.append((UChar32
)0x20402);
110 if(test3
!= CharsToUnicodeString("\\uD841\\uDC02")){
111 errln((UnicodeString
)"append failed for UChar32, expected \"\\\\ud841\\\\udc02\", got " + prettify(test3
));
113 if(test3
.length() != 2){
114 errln("append or length failed for UChar32, expected 2, got " + test3
.length());
116 test3
.append((UChar32
)0x0074);
117 if(test3
!= CharsToUnicodeString("\\uD841\\uDC02t")){
118 errln((UnicodeString
)"append failed for UChar32, expected \"\\\\uD841\\\\uDC02t\", got " + prettify(test3
));
120 if(test3
.length() != 3){
121 errln((UnicodeString
)"append or length failed for UChar32, expected 2, got " + test3
.length());
124 // test some UChar32 overloads
125 if( test3
.setTo((UChar32
)0x10330).length() != 2 ||
126 test3
.insert(0, (UChar32
)0x20100).length() != 4 ||
127 test3
.replace(2, 2, (UChar32
)0xe0061).length() != 4 ||
128 (test3
= (UChar32
)0x14001).length() != 2
130 errln((UnicodeString
)"simple UChar32 overloads for replace, insert, setTo or = failed");
134 // test moveIndex32()
135 UnicodeString s
=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
138 s
.moveIndex32(2, -1)!=0 ||
139 s
.moveIndex32(2, 1)!=4 ||
140 s
.moveIndex32(2, 2)!=5 ||
141 s
.moveIndex32(5, -2)!=2 ||
142 s
.moveIndex32(0, -1)!=0 ||
143 s
.moveIndex32(6, 1)!=6
145 errln("UnicodeString::moveIndex32() failed");
148 if(s
.getChar32Start(1)!=0 || s
.getChar32Start(2)!=2) {
149 errln("UnicodeString::getChar32Start() failed");
152 if(s
.getChar32Limit(1)!=2 || s
.getChar32Limit(2)!=2) {
153 errln("UnicodeString::getChar32Limit() failed");
158 // test new 2.2 constructors and setTo function that parallel Java's substring function.
159 UnicodeString
src("Hello folks how are you?");
160 UnicodeString
target1("how are you?");
161 if (target1
!= UnicodeString(src
, 12)) {
162 errln("UnicodeString(const UnicodeString&, int32_t) failed");
164 UnicodeString
target2("folks");
165 if (target2
!= UnicodeString(src
, 6, 5)) {
166 errln("UnicodeString(const UnicodeString&, int32_t, int32_t) failed");
168 if (target1
!= target2
.setTo(src
, 12)) {
169 errln("UnicodeString::setTo(const UnicodeString&, int32_t) failed");
175 UnicodeStringTest::TestCompare()
177 UnicodeString
test1("this is a test");
178 UnicodeString
test2("this is a test");
179 UnicodeString
test3("this is a test of the emergency broadcast system");
180 UnicodeString
test4("never say, \"this is a test\"!!");
182 UnicodeString
test5((UChar
)0x5000);
183 UnicodeString
test6((UChar
)0x5100);
185 UChar uniChars
[] = { 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73,
186 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0 };
187 char chars
[] = "this is a test";
189 // test operator== and operator!=
190 if (test1
!= test2
|| test1
== test3
|| test1
== test4
)
191 errln("operator== or operator!= failed");
193 // test operator> and operator<
194 if (test1
> test2
|| test1
< test2
|| !(test1
< test3
) || !(test1
> test4
) ||
197 errln("operator> or operator< failed");
200 // test operator>= and operator<=
201 if (!(test1
>= test2
) || !(test1
<= test2
) || !(test1
<= test3
) || !(test1
>= test4
))
202 errln("operator>= or operator<= failed");
204 // test compare(UnicodeString)
205 if (test1
.compare(test2
) != 0 || test1
.compare(test3
) >= 0 || test1
.compare(test4
) <= 0)
206 errln("compare(UnicodeString) failed");
208 //test compare(offset, length, UnicodeString)
209 if(test1
.compare(0, 14, test2
) != 0 ||
210 test3
.compare(0, 14, test2
) != 0 ||
211 test4
.compare(12, 14, test2
) != 0 ||
212 test3
.compare(0, 18, test1
) <=0 )
213 errln("compare(offset, length, UnicodeString) failes");
215 // test compare(UChar*)
216 if (test2
.compare(uniChars
) != 0 || test3
.compare(uniChars
) <= 0 || test4
.compare(uniChars
) >= 0)
217 errln("compare(UChar*) failed");
219 // test compare(char*)
220 if (test2
.compare(chars
) != 0 || test3
.compare(chars
) <= 0 || test4
.compare(chars
) >= 0)
221 errln("compare(char*) failed");
223 // test compare(UChar*, length)
224 if (test1
.compare(uniChars
, 4) <= 0 || test1
.compare(uniChars
, 4) <= 0)
225 errln("compare(UChar*, length) failed");
227 // test compare(thisOffset, thisLength, that, thatOffset, thatLength)
228 if (test1
.compare(0, 14, test2
, 0, 14) != 0
229 || test1
.compare(0, 14, test3
, 0, 14) != 0
230 || test1
.compare(0, 14, test4
, 12, 14) != 0)
231 errln("1. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
233 if (test1
.compare(10, 4, test2
, 0, 4) >= 0
234 || test1
.compare(10, 4, test3
, 22, 9) <= 0
235 || test1
.compare(10, 4, test4
, 22, 4) != 0)
236 errln("2. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
238 // test compareBetween
239 if (test1
.compareBetween(0, 14, test2
, 0, 14) != 0 || test1
.compareBetween(0, 14, test3
, 0, 14) != 0
240 || test1
.compareBetween(0, 14, test4
, 12, 26) != 0)
241 errln("compareBetween failed");
243 if (test1
.compareBetween(10, 14, test2
, 0, 4) >= 0 || test1
.compareBetween(10, 14, test3
, 22, 31) <= 0
244 || test1
.compareBetween(10, 14, test4
, 22, 26) != 0)
245 errln("compareBetween failed");
247 // test compare() etc. with strings that share a buffer but are not equal
248 test2
=test1
; // share the buffer, length() too large for the stackBuffer
249 test2
.truncate(1); // change only the length, not the buffer
250 if( test1
==test2
|| test1
<=test2
||
251 test1
.compare(test2
)<=0 ||
252 test1
.compareCodePointOrder(test2
)<=0 ||
253 test1
.compareCodePointOrder(0, INT32_MAX
, test2
)<=0 ||
254 test1
.compareCodePointOrder(0, INT32_MAX
, test2
, 0, INT32_MAX
)<=0 ||
255 test1
.compareCodePointOrderBetween(0, INT32_MAX
, test2
, 0, INT32_MAX
)<=0 ||
256 test1
.caseCompare(test2
, U_FOLD_CASE_DEFAULT
)<=0
258 errln("UnicodeStrings that share a buffer but have different lengths compare as equal");
261 /* test compareCodePointOrder() */
263 /* these strings are in ascending order */
264 static const UChar strings
[][4]={
265 { 0x61, 0 }, /* U+0061 */
266 { 0x20ac, 0xd801, 0 }, /* U+20ac U+d801 */
267 { 0x20ac, 0xd800, 0xdc00, 0 }, /* U+20ac U+10000 */
268 { 0xd800, 0 }, /* U+d800 */
269 { 0xd800, 0xff61, 0 }, /* U+d800 U+ff61 */
270 { 0xdfff, 0 }, /* U+dfff */
271 { 0xff61, 0xdfff, 0 }, /* U+ff61 U+dfff */
272 { 0xff61, 0xd800, 0xdc02, 0 }, /* U+ff61 U+10002 */
273 { 0xd800, 0xdc02, 0 }, /* U+10002 */
274 { 0xd84d, 0xdc56, 0 } /* U+23456 */
276 UnicodeString u
[20]; // must be at least as long as strings[]
279 for(i
=0; i
<(int32_t)(sizeof(strings
)/sizeof(strings
[0])); ++i
) {
280 u
[i
]=UnicodeString(TRUE
, strings
[i
], -1);
283 for(i
=0; i
<(int32_t)(sizeof(strings
)/sizeof(strings
[0])-1); ++i
) {
284 if(u
[i
].compareCodePointOrder(u
[i
+1])>=0 || u
[i
].compareCodePointOrder(0, INT32_MAX
, u
[i
+1].getBuffer())>=0) {
285 errln("error: UnicodeString::compareCodePointOrder() fails for string %d and the following one\n", i
);
290 /* test caseCompare() */
293 _mixed
[]= { 0x61, 0x42, 0x131, 0x3a3, 0xdf, 0x130, 0x49, 0xfb03, 0xd93f, 0xdfff, 0 },
294 _otherDefault
[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x69, 0x307, 0x69, 0x46, 0x66, 0x49, 0xd93f, 0xdfff, 0 },
295 _otherExcludeSpecialI
[]={ 0x41, 0x62, 0x131, 0x3c3, 0x53, 0x73, 0x69, 0x131, 0x66, 0x46, 0x69, 0xd93f, 0xdfff, 0 },
296 _different
[]= { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x130, 0x49, 0x46, 0x66, 0x49, 0xd93f, 0xdffd, 0 };
299 mixed(TRUE
, _mixed
, -1),
300 otherDefault(TRUE
, _otherDefault
, -1),
301 otherExcludeSpecialI(TRUE
, _otherExcludeSpecialI
, -1),
302 different(TRUE
, _different
, -1);
306 /* test caseCompare() */
307 result
=mixed
.caseCompare(otherDefault
, U_FOLD_CASE_DEFAULT
);
308 if(result
!=0 || 0!=mixed
.caseCompareBetween(0, INT32_MAX
, otherDefault
, 0, INT32_MAX
, U_FOLD_CASE_DEFAULT
)) {
309 errln("error: mixed.caseCompare(other, default)=%ld instead of 0\n", result
);
311 result
=mixed
.caseCompare(otherExcludeSpecialI
, U_FOLD_CASE_EXCLUDE_SPECIAL_I
);
313 errln("error: mixed.caseCompare(otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=%ld instead of 0\n", result
);
315 result
=mixed
.caseCompare(otherDefault
, U_FOLD_CASE_EXCLUDE_SPECIAL_I
);
316 if(result
==0 || 0==mixed
.caseCompareBetween(0, INT32_MAX
, otherDefault
, 0, INT32_MAX
, U_FOLD_CASE_EXCLUDE_SPECIAL_I
)) {
317 errln("error: mixed.caseCompare(other, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=0 instead of !=0\n");
320 /* test caseCompare() */
321 result
=mixed
.caseCompare(different
, U_FOLD_CASE_DEFAULT
);
323 errln("error: mixed.caseCompare(different, default)=%ld instead of positive\n", result
);
326 /* test caseCompare() - include the folded sharp s (U+00df) with different lengths */
327 result
=mixed
.caseCompare(1, 4, different
, 1, 5, U_FOLD_CASE_DEFAULT
);
328 if(result
!=0 || 0!=mixed
.caseCompareBetween(1, 5, different
, 1, 6, U_FOLD_CASE_DEFAULT
)) {
329 errln("error: mixed.caseCompare(mixed, 1, 4, different, 1, 5, default)=%ld instead of 0\n", result
);
332 /* test caseCompare() - stop in the middle of the sharp s (U+00df) */
333 result
=mixed
.caseCompare(1, 4, different
, 1, 4, U_FOLD_CASE_DEFAULT
);
335 errln("error: mixed.caseCompare(1, 4, different, 1, 4, default)=%ld instead of positive\n", result
);
339 // test that srcLength=-1 is handled in functions that
340 // take input const UChar */int32_t srcLength (j785)
342 static const UChar u
[]={ 0x61, 0x308, 0x62, 0 };
343 UnicodeString s
=UNICODE_STRING("a\\u0308b", 8).unescape();
345 if(s
.compare(u
, -1)!=0 || s
.compare(0, 999, u
, 0, -1)!=0) {
346 errln("error UnicodeString::compare(..., const UChar *, srcLength=-1) does not work");
349 if(s
.compareCodePointOrder(u
, -1)!=0 || s
.compareCodePointOrder(0, 999, u
, 0, -1)!=0) {
350 errln("error UnicodeString::compareCodePointOrder(..., const UChar *, srcLength=-1, ...) does not work");
353 if(s
.caseCompare(u
, -1, U_FOLD_CASE_DEFAULT
)!=0 || s
.caseCompare(0, 999, u
, 0, -1, U_FOLD_CASE_DEFAULT
)!=0) {
354 errln("error UnicodeString::caseCompare(..., const UChar *, srcLength=-1, ...) does not work");
357 if(s
.indexOf(u
, 1, -1, 0, 999)!=1 || s
.indexOf(u
+1, -1, 0, 999)!=1 || s
.indexOf(u
+1, -1, 0)!=1) {
358 errln("error UnicodeString::indexOf(const UChar *, srcLength=-1, ...) does not work");
361 if(s
.lastIndexOf(u
, 1, -1, 0, 999)!=1 || s
.lastIndexOf(u
+1, -1, 0, 999)!=1 || s
.lastIndexOf(u
+1, -1, 0)!=1) {
362 errln("error UnicodeString::lastIndexOf(const UChar *, srcLength=-1, ...) does not work");
365 UnicodeString s2
, s3
;
366 s2
.replace(0, 0, u
+1, -1);
367 s3
.replace(0, 0, u
, 1, -1);
368 if(s
.compare(1, 999, s2
)!=0 || s2
!=s3
) {
369 errln("error UnicodeString::replace(..., const UChar *, srcLength=-1, ...) does not work");
375 UnicodeStringTest::TestExtract()
377 UnicodeString
test1("Now is the time for all good men to come to the aid of their country.", "");
379 UChar test3
[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
380 char test4
[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
382 char test6
[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
384 test1
.extract(11, 12, test2
);
385 test1
.extract(11, 12, test3
);
386 if (test1
.extract(11, 12, test4
) != 12 || test4
[12] != 0) {
387 errln("UnicodeString.extract(char *) failed to return the correct size of destination buffer.");
389 test1
.extractBetween(11, 23, test5
);
390 if (test1
.extract(60, 71, test6
) != 9) {
391 errln("UnicodeString.extract() failed to return the correct size of destination buffer for end of buffer.");
393 if (test1
.extract(11, 12, test6
) != 12) {
394 errln("UnicodeString.extract() failed to return the correct size of destination buffer.");
397 // convert test4 back to Unicode for comparison
398 UnicodeString
test4b(test4
, 12);
400 if (test1
.extract(11, 12, (char *)NULL
) != 12) {
401 errln("UnicodeString.extract(NULL) failed to return the correct size of destination buffer.");
403 if (test1
.extract(11, -1, test6
) != 0) {
404 errln("UnicodeString.extract(-1) failed to stop reading the string.");
407 for (int32_t i
= 0; i
< 12; i
++) {
408 if (test1
.charAt((int32_t)(11 + i
)) != test2
.charAt(i
)) {
409 errln(UnicodeString("extracting into a UnicodeString failed at position ") + i
);
412 if (test1
.charAt((int32_t)(11 + i
)) != test3
[i
]) {
413 errln(UnicodeString("extracting into an array of UChar failed at position ") + i
);
416 if (((char)test1
.charAt((int32_t)(11 + i
))) != test4b
.charAt(i
)) {
417 errln(UnicodeString("extracting into an array of char failed at position ") + i
);
420 if (test1
.charAt((int32_t)(11 + i
)) != test5
.charAt(i
)) {
421 errln(UnicodeString("extracting with extractBetween failed at position ") + i
);
426 // test preflighting and overflows with invariant conversion
427 if (test1
.extract(0, 10, (char *)NULL
, "") != 10) {
428 errln("UnicodeString.extract(0, 10, (char *)NULL, \"\") != 10");
431 test4
[2] = (char)0xff;
432 if (test1
.extract(0, 10, test4
, 2, "") != 10) {
433 errln("UnicodeString.extract(0, 10, test4, 2, \"\") != 10");
435 if (test4
[2] != (char)0xff) {
436 errln("UnicodeString.extract(0, 10, test4, 2, \"\") overwrote test4[2]");
440 // test new, NUL-terminating extract() function
441 UnicodeString
s("terminate", "");
443 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
444 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5
446 UErrorCode errorCode
;
449 errorCode
=U_ZERO_ERROR
;
450 length
=s
.extract((UChar
*)NULL
, 0, errorCode
);
451 if(errorCode
!=U_BUFFER_OVERFLOW_ERROR
|| length
!=s
.length()) {
452 errln("UnicodeString.extract(NULL, 0)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)", length
, s
.length(), u_errorName(errorCode
));
455 errorCode
=U_ZERO_ERROR
;
456 length
=s
.extract(dest
, s
.length()-1, errorCode
);
457 if(errorCode
!=U_BUFFER_OVERFLOW_ERROR
|| length
!=s
.length()) {
458 errln("UnicodeString.extract(dest too short)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)",
459 length
, u_errorName(errorCode
), s
.length());
462 errorCode
=U_ZERO_ERROR
;
463 length
=s
.extract(dest
, s
.length(), errorCode
);
464 if(errorCode
!=U_STRING_NOT_TERMINATED_WARNING
|| length
!=s
.length()) {
465 errln("UnicodeString.extract(dest just right without NUL)==%d (%s) expected %d (U_STRING_NOT_TERMINATED_WARNING)",
466 length
, u_errorName(errorCode
), s
.length());
468 if(dest
[length
-1]!=s
[length
-1] || dest
[length
]!=0xa5) {
469 errln("UnicodeString.extract(dest just right without NUL) did not extract the string correctly");
472 errorCode
=U_ZERO_ERROR
;
473 length
=s
.extract(dest
, s
.length()+1, errorCode
);
474 if(errorCode
!=U_ZERO_ERROR
|| length
!=s
.length()) {
475 errln("UnicodeString.extract(dest large enough)==%d (%s) expected %d (U_ZERO_ERROR)",
476 length
, u_errorName(errorCode
), s
.length());
478 if(dest
[length
-1]!=s
[length
-1] || dest
[length
]!=0 || dest
[length
+1]!=0xa5) {
479 errln("UnicodeString.extract(dest large enough) did not extract the string correctly");
484 // test new UConverter extract() and constructor
485 UnicodeString s
=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
487 static const char expect
[]={
488 (char)0xf0, (char)0xaf, (char)0xa6, (char)0x99,
489 (char)0xf0, (char)0x9d, (char)0x85, (char)0x9f,
490 (char)0xc3, (char)0x84,
491 (char)0xe1, (char)0xbb, (char)0x90
493 UErrorCode errorCode
=U_ZERO_ERROR
;
494 UConverter
*cnv
=ucnv_open("UTF-8", &errorCode
);
497 if(U_SUCCESS(errorCode
)) {
499 if( (length
=s
.extract(NULL
, 0, cnv
, errorCode
))!=13 ||
500 errorCode
!=U_BUFFER_OVERFLOW_ERROR
502 errln("UnicodeString::extract(NULL, UConverter) preflighting failed (length=%ld, %s)",
503 length
, u_errorName(errorCode
));
505 errorCode
=U_ZERO_ERROR
;
506 if( (length
=s
.extract(buffer
, 2, cnv
, errorCode
))!=13 ||
507 errorCode
!=U_BUFFER_OVERFLOW_ERROR
509 errln("UnicodeString::extract(too small, UConverter) preflighting failed (length=%ld, %s)",
510 length
, u_errorName(errorCode
));
514 errorCode
=U_ZERO_ERROR
;
515 if( s
.extract(NULL
, 2, cnv
, errorCode
)==13 || U_SUCCESS(errorCode
)) {
516 errln("UnicodeString::extract(UConverter) succeeded with an illegal destination");
518 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
519 if( s
.extract(NULL
, 0, cnv
, errorCode
)==13 || U_SUCCESS(errorCode
)) {
520 errln("UnicodeString::extract(UConverter) succeeded with a previous error code");
522 errorCode
=U_ZERO_ERROR
;
525 if( (length
=s
.extract(buffer
, sizeof(buffer
), cnv
, errorCode
))!=13 ||
526 uprv_memcmp(buffer
, expect
, 13)!=0 ||
530 errln("UnicodeString::extract(UConverter) conversion failed (length=%ld, %s)",
531 length
, u_errorName(errorCode
));
534 // try the constructor
535 UnicodeString
t(expect
, sizeof(expect
), cnv
, errorCode
);
536 if(U_FAILURE(errorCode
) || s
!=t
) {
537 errln("UnicodeString(UConverter) conversion failed (%s)",
538 u_errorName(errorCode
));
547 UnicodeStringTest::TestRemoveReplace()
549 UnicodeString
test1("The rain in Spain stays mainly on the plain");
550 UnicodeString
test2("eat SPAMburgers!");
551 UChar test3
[] = { 0x53, 0x50, 0x41, 0x4d, 0x4d, 0 };
552 char test4
[] = "SPAM";
553 UnicodeString
& test5
= test1
;
555 test1
.replace(4, 4, test2
, 4, 4);
556 test1
.replace(12, 5, test3
, 4);
558 test1
.replace(17, 4, test3
);
559 test1
.replace(23, 4, test4
);
560 test1
.replaceBetween(37, 42, test2
, 4, 8);
562 if (test1
!= "The SPAM in SPAM SPAMs SPAMly on the SPAM")
563 errln("One of the replace methods failed:\n"
564 " expected \"The SPAM in SPAM SPAMs SPAMly on the SPAM\",\n"
565 " got \"" + test1
+ "\"");
568 test1
.removeBetween(26, 28);
570 if (test1
!= "The SPAM in SPAM SPAM SPAM on the SPAM")
571 errln("One of the remove methods failed:\n"
572 " expected \"The SPAM in SPAM SPAM SPAM on the SPAM\",\n"
573 " got \"" + test1
+ "\"");
575 for (int32_t i
= 0; i
< test1
.length(); i
++) {
576 if (test5
[i
] != 0x53 && test5
[i
] != 0x50 && test5
[i
] != 0x41 && test5
[i
] != 0x4d && test5
[i
] != 0x20) {
577 test1
.setCharAt(i
, 0x78);
581 if (test1
!= "xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM")
582 errln("One of the remove methods failed:\n"
583 " expected \"xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM\",\n"
584 " got \"" + test1
+ "\"");
587 if (test1
.length() != 0)
588 errln("Remove() failed: expected empty string, got \"" + test1
+ "\"");
592 UnicodeStringTest::TestSearching()
594 UnicodeString
test1("test test ttest tetest testesteststt");
595 UnicodeString
test2("test");
596 UChar testChar
= 0x74;
598 UChar32 testChar32
= 0x20402;
601 0xd841, 0xdc02, 0x0071, 0xdc02, 0xd841, 0x0071, 0xd841, 0xdc02,
603 // 8 9 10 11 12 13 14 15
604 0x0071, 0x0072, 0xd841, 0xdc02, 0x0071, 0xd841, 0xdc02, 0x0071,
607 0xdc02, 0xd841, 0x0073, 0x0000
609 UnicodeString
test3(testData
);
610 UnicodeString
test4(testChar32
);
612 uint16_t occurrences
= 0;
613 int32_t startPos
= 0;
615 startPos
!= -1 && startPos
< test1
.length();
616 (startPos
= test1
.indexOf(test2
, startPos
)) != -1 ? (++occurrences
, startPos
+= 4) : 0)
618 if (occurrences
!= 6)
619 errln("indexOf failed: expected to find 6 occurrences, found " + occurrences
);
621 for ( occurrences
= 0, startPos
= 10;
622 startPos
!= -1 && startPos
< test1
.length();
623 (startPos
= test1
.indexOf(test2
, startPos
)) != -1 ? (++occurrences
, startPos
+= 4) : 0)
625 if (occurrences
!= 4)
626 errln("indexOf with starting offset failed: expected to find 4 occurrences, found " + occurrences
);
629 for ( occurrences
= 0, startPos
= 5;
630 startPos
!= -1 && startPos
< test1
.length();
631 (startPos
= test1
.indexOf(test2
, startPos
, endPos
- startPos
)) != -1 ? (++occurrences
, startPos
+= 4) : 0)
633 if (occurrences
!= 4)
634 errln("indexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences
);
636 //using UChar32 string
637 for ( startPos
=0, occurrences
=0;
638 startPos
!= -1 && startPos
< test3
.length();
639 (startPos
= test3
.indexOf(test4
, startPos
)) != -1 ? (++occurrences
, startPos
+= 2) : 0)
641 if (occurrences
!= 4)
642 errln((UnicodeString
)"indexOf failed: expected to find 4 occurrences, found " + occurrences
);
644 for ( startPos
=10, occurrences
=0;
645 startPos
!= -1 && startPos
< test3
.length();
646 (startPos
= test3
.indexOf(test4
, startPos
)) != -1 ? (++occurrences
, startPos
+= 2) : 0)
648 if (occurrences
!= 2)
649 errln("indexOf failed: expected to find 2 occurrences, found " + occurrences
);
652 for ( occurrences
= 0, startPos
= 0;
653 startPos
!= -1 && startPos
< test1
.length();
654 (startPos
= test1
.indexOf(testChar
, startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
656 if (occurrences
!= 16)
657 errln("indexOf with character failed: expected to find 16 occurrences, found " + occurrences
);
659 for ( occurrences
= 0, startPos
= 10;
660 startPos
!= -1 && startPos
< test1
.length();
661 (startPos
= test1
.indexOf(testChar
, startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
663 if (occurrences
!= 12)
664 errln("indexOf with character & start offset failed: expected to find 12 occurrences, found " + occurrences
);
666 for ( occurrences
= 0, startPos
= 5, endPos
= 28;
667 startPos
!= -1 && startPos
< test1
.length();
668 (startPos
= test1
.indexOf(testChar
, startPos
, endPos
- startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
670 if (occurrences
!= 10)
671 errln("indexOf with character & start & end offsets failed: expected to find 10 occurrences, found " + occurrences
);
673 //testing for UChar32
674 UnicodeString subString
;
675 for( occurrences
=0, startPos
=0; startPos
< test3
.length(); startPos
+=1){
676 subString
.append(test3
, startPos
, test3
.length());
677 if(subString
.indexOf(testChar32
) != -1 ){
682 if (occurrences
!= 14)
683 errln((UnicodeString
)"indexOf failed: expected to find 14 occurrences, found " + occurrences
);
685 for ( occurrences
= 0, startPos
= 0;
686 startPos
!= -1 && startPos
< test3
.length();
687 (startPos
= test3
.indexOf(testChar32
, startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
689 if (occurrences
!= 4)
690 errln((UnicodeString
)"indexOf failed: expected to find 4 occurrences, found " + occurrences
);
692 endPos
=test3
.length();
693 for ( occurrences
= 0, startPos
= 5;
694 startPos
!= -1 && startPos
< test3
.length();
695 (startPos
= test3
.indexOf(testChar32
, startPos
, endPos
- startPos
)) != -1 ? (++occurrences
, startPos
+= 1) : 0)
697 if (occurrences
!= 3)
698 errln((UnicodeString
)"indexOf with character & start & end offsets failed: expected to find 2 occurrences, found " + occurrences
);
701 if(test1
.lastIndexOf(test2
)!=29) {
702 errln("test1.lastIndexOf(test2)!=29");
705 if(test1
.lastIndexOf(test2
, 15)!=29 || test1
.lastIndexOf(test2
, 29)!=29 || test1
.lastIndexOf(test2
, 30)!=-1) {
706 errln("test1.lastIndexOf(test2, start) failed");
709 for ( occurrences
= 0, startPos
= 32;
711 (startPos
= test1
.lastIndexOf(test2
, 5, startPos
- 5)) != -1 ? ++occurrences
: 0)
713 if (occurrences
!= 4)
714 errln("lastIndexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences
);
716 for ( occurrences
= 0, startPos
= 32;
718 (startPos
= test1
.lastIndexOf(testChar
, 5, startPos
- 5)) != -1 ? ++occurrences
: 0)
720 if (occurrences
!= 11)
721 errln("lastIndexOf with character & start & end offsets failed: expected to find 11 occurrences, found " + occurrences
);
724 startPos
=test3
.length();
725 for ( occurrences
= 0;
727 (startPos
= test3
.lastIndexOf(testChar32
, 5, startPos
- 5)) != -1 ? ++occurrences
: 0)
729 if (occurrences
!= 3)
730 errln((UnicodeString
)"lastIndexOf with character & start & end offsets failed: expected to find 3 occurrences, found " + occurrences
);
733 for ( occurrences
= 0, endPos
= test3
.length(); endPos
> 0; endPos
-= 1){
735 subString
.append(test3
, 0, endPos
);
736 if(subString
.lastIndexOf(testChar32
) != -1 ){
740 if (occurrences
!= 18)
741 errln((UnicodeString
)"indexOf failed: expected to find 18 occurrences, found " + occurrences
);
744 // test that indexOf(UChar32) and lastIndexOf(UChar32)
745 // do not find surrogate code points when they are part of matched pairs
746 // (= part of supplementary code points)
748 if(test3
.indexOf((UChar32
)0xd841) != 4 || test3
.indexOf((UChar32
)0xdc02) != 3) {
749 errln("error: UnicodeString::indexOf(UChar32 surrogate) finds a partial supplementary code point");
751 if( UnicodeString(test3
, 0, 17).lastIndexOf((UChar
)0xd841, 0) != 4 ||
752 UnicodeString(test3
, 0, 17).lastIndexOf((UChar32
)0xd841, 2) != 4 ||
753 test3
.lastIndexOf((UChar32
)0xd841, 0, 17) != 4 || test3
.lastIndexOf((UChar32
)0xdc02, 0, 17) != 16
755 errln("error: UnicodeString::lastIndexOf(UChar32 surrogate) finds a partial supplementary code point");
760 UnicodeStringTest::TestSpacePadding()
762 UnicodeString
test1("hello");
763 UnicodeString
test2(" there");
764 UnicodeString
test3("Hi! How ya doin'? Beautiful day, isn't it?");
767 UnicodeString expectedValue
;
769 returnVal
= test1
.padLeading(15);
770 expectedValue
= " hello";
771 if (returnVal
== FALSE
|| test1
!= expectedValue
)
772 errln("padLeading() failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
774 returnVal
= test2
.padTrailing(15);
775 expectedValue
= " there ";
776 if (returnVal
== FALSE
|| test2
!= expectedValue
)
777 errln("padTrailing() failed: expected \"" + expectedValue
+ "\", got \"" + test2
+ "\".");
779 expectedValue
= test3
;
780 returnVal
= test3
.padTrailing(15);
781 if (returnVal
== TRUE
|| test3
!= expectedValue
)
782 errln("padTrailing() failed: expected \"" + expectedValue
+ "\", got \"" + test3
+ "\".");
784 expectedValue
= "hello";
785 test4
.setTo(test1
).trim();
787 if (test4
!= expectedValue
|| test1
== expectedValue
|| test4
!= expectedValue
)
788 errln("trim(UnicodeString&) failed");
791 if (test1
!= expectedValue
)
792 errln("trim() failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
795 expectedValue
= "there";
796 if (test2
!= expectedValue
)
797 errln("trim() failed: expected \"" + expectedValue
+ "\", got \"" + test2
+ "\".");
800 expectedValue
= "Hi! How ya doin'? Beautiful day, isn't it?";
801 if (test3
!= expectedValue
)
802 errln("trim() failed: expected \"" + expectedValue
+ "\", got \"" + test3
+ "\".");
804 returnVal
= test1
.truncate(15);
805 expectedValue
= "hello";
806 if (returnVal
== TRUE
|| test1
!= expectedValue
)
807 errln("truncate() failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
809 returnVal
= test2
.truncate(15);
810 expectedValue
= "there";
811 if (returnVal
== TRUE
|| test2
!= expectedValue
)
812 errln("truncate() failed: expected \"" + expectedValue
+ "\", got \"" + test2
+ "\".");
814 returnVal
= test3
.truncate(15);
815 expectedValue
= "Hi! How ya doi";
816 if (returnVal
== FALSE
|| test3
!= expectedValue
)
817 errln("truncate() failed: expected \"" + expectedValue
+ "\", got \"" + test3
+ "\".");
821 UnicodeStringTest::TestPrefixAndSuffix()
823 UnicodeString
test1("Now is the time for all good men to come to the aid of their country.");
824 UnicodeString
test2("Now");
825 UnicodeString
test3("country.");
826 UnicodeString
test4("count");
828 if (!test1
.startsWith(test2
) || !test1
.startsWith(test2
, 0, test2
.length())) {
829 errln("startsWith() failed: \"" + test2
+ "\" should be a prefix of \"" + test1
+ "\".");
832 if (test1
.startsWith(test3
) ||
833 test1
.startsWith(test3
.getBuffer(), test3
.length()) ||
834 test1
.startsWith(test3
.getTerminatedBuffer(), 0, -1)
836 errln("startsWith() failed: \"" + test3
+ "\" shouldn't be a prefix of \"" + test1
+ "\".");
839 if (test1
.endsWith(test2
)) {
840 errln("endsWith() failed: \"" + test2
+ "\" shouldn't be a suffix of \"" + test1
+ "\".");
843 if (!test1
.endsWith(test3
)) {
844 errln("endsWith(test3) failed: \"" + test3
+ "\" should be a suffix of \"" + test1
+ "\".");
846 if (!test1
.endsWith(test3
, 0, INT32_MAX
)) {
847 errln("endsWith(test3, 0, INT32_MAX) failed: \"" + test3
+ "\" should be a suffix of \"" + test1
+ "\".");
850 if(!test1
.endsWith(test3
.getBuffer(), test3
.length())) {
851 errln("endsWith(test3.getBuffer(), test3.length()) failed: \"" + test3
+ "\" should be a suffix of \"" + test1
+ "\".");
853 if(!test1
.endsWith(test3
.getTerminatedBuffer(), 0, -1)) {
854 errln("endsWith(test3.getTerminatedBuffer(), 0, -1) failed: \"" + test3
+ "\" should be a suffix of \"" + test1
+ "\".");
857 if (!test3
.startsWith(test4
)) {
858 errln("endsWith(test4) failed: \"" + test4
+ "\" should be a prefix of \"" + test3
+ "\".");
861 if (test4
.startsWith(test3
)) {
862 errln("startsWith(test3) failed: \"" + test3
+ "\" shouldn't be a prefix of \"" + test4
+ "\".");
867 UnicodeStringTest::TestFindAndReplace()
869 UnicodeString
test1("One potato, two potato, three potato, four\n");
870 UnicodeString
test2("potato");
871 UnicodeString
test3("MISSISSIPPI");
873 UnicodeString expectedValue
;
875 test1
.findAndReplace(test2
, test3
);
876 expectedValue
= "One MISSISSIPPI, two MISSISSIPPI, three MISSISSIPPI, four\n";
877 if (test1
!= expectedValue
)
878 errln("findAndReplace failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
879 test1
.findAndReplace(2, 32, test3
, test2
);
880 expectedValue
= "One potato, two potato, three MISSISSIPPI, four\n";
881 if (test1
!= expectedValue
)
882 errln("findAndReplace failed: expected \"" + expectedValue
+ "\", got \"" + test1
+ "\".");
886 UnicodeStringTest::TestReverse()
888 UnicodeString
test("backwards words say to used I");
897 if (test
!= "I used to say words backwards")
898 errln("reverse() failed: Expected \"I used to say words backwards\",\n got \""
901 test
=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
903 if(test
.char32At(0)!=0x1ed0 || test
.char32At(1)!=0xc4 || test
.char32At(2)!=0x1d15f || test
.char32At(4)!=0x2f999) {
904 errln("reverse() failed with supplementary characters");
909 UnicodeStringTest::TestMiscellaneous()
911 UnicodeString
test1("This is a test");
912 UnicodeString
test2("This is a test");
913 UnicodeString
test3("Me too!");
915 // test getBuffer(minCapacity) and releaseBuffer()
916 test1
=UnicodeString(); // make sure that it starts with its stackBuffer
917 UChar
*p
=test1
.getBuffer(20);
918 if(test1
.getCapacity()<20) {
919 errln("UnicodeString::getBuffer(20).getCapacity()<20");
922 test1
.append((UChar
)7); // must not be able to modify the string here
923 test1
.setCharAt(3, 7);
925 if( test1
.length()!=0 ||
926 test1
.charAt(0)!=0xffff || test1
.charAt(3)!=0xffff ||
927 test1
.getBuffer(10)!=0 || test1
.getBuffer()!=0
929 errln("UnicodeString::getBuffer(minCapacity) allows read or write access to the UnicodeString");
935 test1
.releaseBuffer(3);
936 test1
.append((UChar
)4);
938 if(test1
.length()!=4 || test1
.charAt(0)!=1 || test1
.charAt(1)!=2 || test1
.charAt(2)!=3 || test1
.charAt(3)!=4) {
939 errln("UnicodeString::releaseBuffer(newLength) does not properly reallow access to the UnicodeString");
942 // test releaseBuffer() without getBuffer(minCapacity) - must not have any effect
943 test1
.releaseBuffer(1);
944 if(test1
.length()!=4 || test1
.charAt(0)!=1 || test1
.charAt(1)!=2 || test1
.charAt(2)!=3 || test1
.charAt(3)!=4) {
945 errln("UnicodeString::releaseBuffer(newLength) without getBuffer(minCapacity) changed the UnicodeString");
948 // test getBuffer(const)
949 const UChar
*q
=test1
.getBuffer(), *r
=test1
.getBuffer();
950 if( test1
.length()!=4 ||
951 q
[0]!=1 || q
[1]!=2 || q
[2]!=3 || q
[3]!=4 ||
952 r
[0]!=1 || r
[1]!=2 || r
[2]!=3 || r
[3]!=4
954 errln("UnicodeString::getBuffer(const) does not return a usable buffer pointer");
957 // test releaseBuffer() with a NUL-terminated buffer
958 test1
.getBuffer(20)[2]=0;
959 test1
.releaseBuffer(); // implicit -1
960 if(test1
.length()!=2 || test1
.charAt(0)!=1 || test1
.charAt(1) !=2) {
961 errln("UnicodeString::releaseBuffer(-1) does not properly set the length of the UnicodeString");
964 // test releaseBuffer() with a non-NUL-terminated buffer
965 p
=test1
.getBuffer(256);
966 for(int32_t i
=0; i
<test1
.getCapacity(); ++i
) {
967 p
[i
]=(UChar
)1; // fill the buffer with all non-NUL code units
969 test1
.releaseBuffer(); // implicit -1
970 if(test1
.length()!=test1
.getCapacity() || test1
.charAt(1)!=1 || test1
.charAt(100)!=1 || test1
.charAt(test1
.getCapacity()-1)!=1) {
971 errln("UnicodeString::releaseBuffer(-1 but no NUL) does not properly set the length of the UnicodeString");
974 // test getTerminatedBuffer()
975 test1
=UnicodeString("This is another test.", "");
976 test2
=UnicodeString("This is another test.", "");
977 q
=test1
.getTerminatedBuffer();
978 if(q
[test1
.length()]!=0 || test1
!=test2
|| test2
.compare(q
, -1)!=0) {
979 errln("getTerminatedBuffer()[length]!=0");
982 const UChar u
[]={ 5, 6, 7, 8, 0 };
983 test1
.setTo(FALSE
, u
, 3);
984 q
=test1
.getTerminatedBuffer();
985 if(q
==u
|| q
[0]!=5 || q
[1]!=6 || q
[2]!=7 || q
[3]!=0) {
986 errln("UnicodeString(u[3]).getTerminatedBuffer() returns a bad buffer");
989 test1
.setTo(TRUE
, u
, -1);
990 q
=test1
.getTerminatedBuffer();
991 if(q
!=u
|| test1
.length()!=4 || q
[3]!=8 || q
[4]!=0) {
992 errln("UnicodeString(u[-1]).getTerminatedBuffer() returns a bad buffer");
995 test1
=UNICODE_STRING("la", 2);
996 test1
.append(UNICODE_STRING(" lila", 5).getTerminatedBuffer(), 0, -1);
997 if(test1
!=UNICODE_STRING("la lila", 7)) {
998 errln("UnicodeString::append(const UChar *, start, length) failed");
1001 test1
.insert(3, UNICODE_STRING("dudum ", 6), 0, INT32_MAX
);
1002 if(test1
!=UNICODE_STRING("la dudum lila", 13)) {
1003 errln("UnicodeString::insert(start, const UniStr &, start, length) failed");
1006 static const UChar ucs
[]={ 0x68, 0x6d, 0x20, 0 };
1007 test1
.insert(9, ucs
, -1);
1008 if(test1
!=UNICODE_STRING("la dudum hm lila", 16)) {
1009 errln("UnicodeString::insert(start, const UChar *, length) failed");
1012 test1
.replace(9, 2, (UChar
)0x2b);
1013 if(test1
!=UNICODE_STRING("la dudum + lila", 15)) {
1014 errln("UnicodeString::replace(start, length, UChar) failed");
1017 if(test1
.hasMetaData() || UnicodeString().hasMetaData()) {
1018 errln("UnicodeString::hasMetaData() returns TRUE");
1023 UnicodeStringTest::TestStackAllocation()
1025 UChar testString
[] ={
1026 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x72, 0x61, 0x7a, 0x79, 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0 };
1027 UChar guardWord
= 0x4DED;
1028 UnicodeString
* test
= 0;
1030 test
= new UnicodeString(testString
);
1031 if (*test
!= "This is a crazy test.")
1032 errln("Test string failed to initialize properly.");
1033 if (guardWord
!= 0x04DED)
1034 errln("Test string initialization overwrote guard word!");
1036 test
->insert(8, "only ");
1037 test
->remove(15, 6);
1038 if (*test
!= "This is only a test.")
1039 errln("Manipulation of test string failed to work right.");
1040 if (guardWord
!= 0x4DED)
1041 errln("Manipulation of test string overwrote guard word!");
1043 // we have to deinitialize and release the backing store by calling the destructor
1044 // explicitly, since we can't overload operator delete
1047 UChar workingBuffer
[] = {
1048 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
1049 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20,
1050 0x63, 0x6f, 0x6d, 0x65, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1051 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,
1052 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
1053 UChar guardWord2
= 0x4DED;
1055 test
= new UnicodeString(workingBuffer
, 35, 100);
1056 if (*test
!= "Now is the time for all men to come")
1057 errln("Stack-allocated backing store failed to initialize correctly.");
1058 if (guardWord2
!= 0x4DED)
1059 errln("Stack-allocated backing store overwrote guard word!");
1061 test
->insert(24, "good ");
1062 if (*test
!= "Now is the time for all good men to come")
1063 errln("insert() on stack-allocated UnicodeString didn't work right");
1064 if (guardWord2
!= 0x4DED)
1065 errln("insert() on stack-allocated UnicodeString overwrote guard word!");
1067 if (workingBuffer
[24] != 0x67)
1068 errln("insert() on stack-allocated UnicodeString didn't affect backing store");
1070 *test
+= " to the aid of their country.";
1071 if (*test
!= "Now is the time for all good men to come to the aid of their country.")
1072 errln("Stack-allocated UnicodeString overflow didn't work");
1073 if (guardWord2
!= 0x4DED)
1074 errln("Stack-allocated UnicodeString overflow overwrote guard word!");
1078 errln("Assignment to stack-allocated UnicodeString didn't work");
1079 if (workingBuffer
[0] != 0x4e)
1080 errln("Change to UnicodeString after overflow are still affecting original buffer");
1081 if (guardWord2
!= 0x4DED)
1082 errln("Change to UnicodeString after overflow overwrote guard word!");
1084 // test read-only aliasing with setTo()
1085 workingBuffer
[0] = 0x20ac;
1086 workingBuffer
[1] = 0x125;
1087 workingBuffer
[2] = 0;
1088 test
->setTo(TRUE
, workingBuffer
, 2);
1089 if(test
->length() != 2 || test
->charAt(0) != 0x20ac || test
->charAt(1) != 0x125) {
1090 errln("UnicodeString.setTo(readonly alias) does not alias correctly");
1093 UnicodeString
*c
=(UnicodeString
*)test
->clone();
1095 workingBuffer
[1] = 0x109;
1096 if(test
->charAt(1) != 0x109) {
1097 errln("UnicodeString.setTo(readonly alias) made a copy: did not see change in buffer");
1100 if(c
->length() != 2 || c
->charAt(1) != 0x125) {
1101 errln("clone(alias) did not copy the buffer");
1105 test
->setTo(TRUE
, workingBuffer
, -1);
1106 if(test
->length() != 2 || test
->charAt(0) != 0x20ac || test
->charAt(1) != 0x109) {
1107 errln("UnicodeString.setTo(readonly alias, length -1) does not alias correctly");
1110 test
->setTo(FALSE
, workingBuffer
, -1);
1111 if(!test
->isBogus()) {
1112 errln("UnicodeString.setTo(unterminated readonly alias, length -1) does not result in isBogus()");
1117 test
=new UnicodeString();
1118 UChar buffer
[]={0x0061, 0x0062, 0x20ac, 0x0043, 0x0042, 0x0000};
1119 test
->setTo(buffer
, 4, 10);
1120 if(test
->length() !=4 || test
->charAt(0) != 0x0061 || test
->charAt(1) != 0x0062 ||
1121 test
->charAt(2) != 0x20ac || test
->charAt(3) != 0x0043){
1122 errln((UnicodeString
)"UnicodeString.setTo(UChar*, length, capacity) does not work correctly\n" + prettify(*test
));
1127 // test the UChar32 constructor
1128 UnicodeString
c32Test((UChar32
)0x10ff2a);
1129 if( c32Test
.length() != UTF_CHAR_LENGTH(0x10ff2a) ||
1130 c32Test
.char32At(c32Test
.length() - 1) != 0x10ff2a
1132 errln("The UnicodeString(UChar32) constructor does not work with a 0x10ff2a filler");
1135 // test the (new) capacity constructor
1136 UnicodeString
capTest(5, (UChar32
)0x2a, 5);
1137 if( capTest
.length() != 5 * UTF_CHAR_LENGTH(0x2a) ||
1138 capTest
.char32At(0) != 0x2a ||
1139 capTest
.char32At(4) != 0x2a
1141 errln("The UnicodeString capacity constructor does not work with an ASCII filler");
1144 capTest
= UnicodeString(5, (UChar32
)0x10ff2a, 5);
1145 if( capTest
.length() != 5 * UTF_CHAR_LENGTH(0x10ff2a) ||
1146 capTest
.char32At(0) != 0x10ff2a ||
1147 capTest
.char32At(4) != 0x10ff2a
1149 errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
1152 capTest
= UnicodeString(5, (UChar32
)0, 0);
1153 if(capTest
.length() != 0) {
1154 errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
1159 * Test the unescape() function.
1161 void UnicodeStringTest::TestUnescape(void) {
1162 UnicodeString
IN("abc\\u4567 \\n\\r \\U00101234xyz\\x1\\x{5289}\\x1b");
1163 UnicodeString
OUT("abc");
1164 OUT
.append((UChar
)0x4567);
1166 OUT
.append((UChar
)0xA);
1167 OUT
.append((UChar
)0xD);
1169 OUT
.append((UChar32
)0x00101234);
1171 OUT
.append((UChar32
)1).append((UChar32
)0x5289).append((UChar
)0x1b);
1172 UnicodeString result
= IN
.unescape();
1173 if (result
!= OUT
) {
1174 errln("FAIL: " + prettify(IN
) + ".unescape() -> " +
1175 prettify(result
) + ", expected " +
1179 // test that an empty string is returned in case of an error
1180 if (!UNICODE_STRING("wrong \\u sequence", 17).unescape().isEmpty()) {
1181 errln("FAIL: unescaping of a string with an illegal escape sequence did not return an empty string");
1185 /* test code point counting functions --------------------------------------- */
1187 /* reference implementation of UnicodeString::hasMoreChar32Than() */
1189 _refUnicodeStringHasMoreChar32Than(const UnicodeString
&s
, int32_t start
, int32_t length
, int32_t number
) {
1190 int32_t count
=s
.countChar32(start
, length
);
1191 return count
>number
;
1194 /* compare the real function against the reference */
1196 UnicodeStringTest::_testUnicodeStringHasMoreChar32Than(const UnicodeString
&s
, int32_t start
, int32_t length
, int32_t number
) {
1197 if(s
.hasMoreChar32Than(start
, length
, number
)!=_refUnicodeStringHasMoreChar32Than(s
, start
, length
, number
)) {
1198 errln("hasMoreChar32Than(%d, %d, %d)=%hd is wrong\n",
1199 start
, length
, number
, s
.hasMoreChar32Than(start
, length
, number
));
1204 UnicodeStringTest::TestCountChar32(void) {
1206 UnicodeString s
=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
1208 // test countChar32()
1209 // note that this also calls and tests u_countChar32(length>=0)
1211 s
.countChar32()!=4 ||
1212 s
.countChar32(1)!=4 ||
1213 s
.countChar32(2)!=3 ||
1214 s
.countChar32(2, 3)!=2 ||
1215 s
.countChar32(2, 0)!=0
1217 errln("UnicodeString::countChar32() failed");
1220 // NUL-terminate the string buffer and test u_countChar32(length=-1)
1221 const UChar
*buffer
=s
.getTerminatedBuffer();
1223 u_countChar32(buffer
, -1)!=4 ||
1224 u_countChar32(buffer
+1, -1)!=4 ||
1225 u_countChar32(buffer
+2, -1)!=3 ||
1226 u_countChar32(buffer
+3, -1)!=3 ||
1227 u_countChar32(buffer
+4, -1)!=2 ||
1228 u_countChar32(buffer
+5, -1)!=1 ||
1229 u_countChar32(buffer
+6, -1)!=0
1231 errln("u_countChar32(length=-1) failed");
1234 // test u_countChar32() with bad input
1235 if(u_countChar32(NULL
, 5)!=0 || u_countChar32(buffer
, -2)!=0) {
1236 errln("u_countChar32(bad input) failed (returned non-zero counts)");
1240 /* test data and variables for hasMoreChar32Than() */
1241 static const UChar str
[]={
1242 0x61, 0x62, 0xd800, 0xdc00,
1243 0xd801, 0xdc01, 0x63, 0xd802,
1244 0x64, 0xdc03, 0x65, 0x66,
1245 0xd804, 0xdc04, 0xd805, 0xdc05,
1248 UnicodeString
string(str
, LENGTHOF(str
));
1249 int32_t start
, length
, number
;
1251 /* test hasMoreChar32Than() */
1252 for(length
=string
.length(); length
>=0; --length
) {
1253 for(start
=0; start
<=length
; ++start
) {
1254 for(number
=-1; number
<=((length
-start
)+2); ++number
) {
1255 _testUnicodeStringHasMoreChar32Than(string
, start
, length
-start
, number
);
1260 /* test hasMoreChar32Than() with pinning */
1261 for(start
=-1; start
<=string
.length()+1; ++start
) {
1262 for(number
=-1; number
<=((string
.length()-start
)+2); ++number
) {
1263 _testUnicodeStringHasMoreChar32Than(string
, start
, 0x7fffffff, number
);
1267 /* test hasMoreChar32Than() with a bogus string */
1268 string
.setToBogus();
1269 for(length
=-1; length
<=1; ++length
) {
1270 for(start
=-1; start
<=length
; ++start
) {
1271 for(number
=-1; number
<=((length
-start
)+2); ++number
) {
1272 _testUnicodeStringHasMoreChar32Than(string
, start
, length
-start
, number
);
1279 UnicodeStringTest::TestBogus() {
1280 UnicodeString
test1("This is a test");
1281 UnicodeString
test2("This is a test");
1282 UnicodeString
test3("Me too!");
1284 // test isBogus() and setToBogus()
1285 if (test1
.isBogus() || test2
.isBogus() || test3
.isBogus()) {
1286 errln("A string returned TRUE for isBogus()!");
1289 // NULL pointers are treated like empty strings
1290 // use other illegal arguments to make a bogus string
1291 test3
.setTo(FALSE
, test1
.getBuffer(), -2);
1292 if(!test3
.isBogus()) {
1293 errln("A bogus string returned FALSE for isBogus()!");
1295 if (test1
.hashCode() != test2
.hashCode() || test1
.hashCode() == test3
.hashCode()) {
1296 errln("hashCode() failed");
1298 if(test3
.getBuffer()!=0 || test3
.getBuffer(20)!=0 || test3
.getTerminatedBuffer()!=0) {
1299 errln("bogus.getBuffer()!=0");
1302 // verify that non-assignment modifications fail and do not revive a bogus string
1304 test3
.append((UChar
)0x61);
1305 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1306 errln("bogus.append('a') worked but must not");
1310 test3
.findAndReplace(UnicodeString((UChar
)0x61), test2
);
1311 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1312 errln("bogus.findAndReplace() worked but must not");
1317 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1318 errln("bogus.trim() revived bogus but must not");
1323 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1324 errln("bogus.remove(1) revived bogus but must not");
1328 if(!test3
.setCharAt(0, 0x62).isBogus() || !test3
.isEmpty()) {
1329 errln("bogus.setCharAt(0, 'b') worked but must not");
1333 if(test3
.truncate(1) || !test3
.isBogus() || !test3
.isEmpty()) {
1334 errln("bogus.truncate(1) revived bogus but must not");
1337 // verify that assignments revive a bogus string
1339 if(!test3
.isBogus() || (test3
=test1
).isBogus() || test3
!=test1
) {
1340 errln("bogus.operator=() failed");
1344 if(!test3
.isBogus() || test3
.fastCopyFrom(test1
).isBogus() || test3
!=test1
) {
1345 errln("bogus.fastCopyFrom() failed");
1349 if(!test3
.isBogus() || test3
.setTo(test1
).isBogus() || test3
!=test1
) {
1350 errln("bogus.setTo(UniStr) failed");
1354 if(!test3
.isBogus() || test3
.setTo(test1
, 0).isBogus() || test3
!=test1
) {
1355 errln("bogus.setTo(UniStr, 0) failed");
1359 if(!test3
.isBogus() || test3
.setTo(test1
, 0, 0x7fffffff).isBogus() || test3
!=test1
) {
1360 errln("bogus.setTo(UniStr, 0, len) failed");
1364 if(!test3
.isBogus() || test3
.setTo(test1
.getBuffer(), test1
.length()).isBogus() || test3
!=test1
) {
1365 errln("bogus.setTo(const UChar *, len) failed");
1369 if(!test3
.isBogus() || test3
.setTo((UChar
)0x2028).isBogus() || test3
!=UnicodeString((UChar
)0x2028)) {
1370 errln("bogus.setTo(UChar) failed");
1374 if(!test3
.isBogus() || test3
.setTo((UChar32
)0x1d157).isBogus() || test3
!=UnicodeString((UChar32
)0x1d157)) {
1375 errln("bogus.setTo(UChar32) failed");
1379 if(!test3
.isBogus() || test3
.setTo(FALSE
, test1
.getBuffer(), test1
.length()).isBogus() || test3
!=test1
) {
1380 errln("bogus.setTo(readonly alias) failed");
1383 // writable alias to another string's buffer: very bad idea, just convenient for this test
1385 if(!test3
.isBogus() || test3
.setTo((UChar
*)test1
.getBuffer(), test1
.length(), test1
.getCapacity()).isBogus() || test3
!=test1
) {
1386 errln("bogus.setTo(writable alias) failed");
1389 // verify simple, documented ways to turn a bogus string into an empty one
1391 if(!test3
.isBogus() || (test3
=UnicodeString()).isBogus() || !test3
.isEmpty()) {
1392 errln("bogus.operator=(UnicodeString()) failed");
1396 if(!test3
.isBogus() || test3
.setTo(UnicodeString()).isBogus() || !test3
.isEmpty()) {
1397 errln("bogus.setTo(UnicodeString()) failed");
1401 if(test3
.remove().isBogus() || test3
.getBuffer()==0 || !test3
.isEmpty()) {
1402 errln("bogus.remove() failed");
1406 if(test3
.remove(0, INT32_MAX
).isBogus() || test3
.getBuffer()==0 || !test3
.isEmpty()) {
1407 errln("bogus.remove(0, INT32_MAX) failed");
1411 if(test3
.truncate(0) || test3
.isBogus() || !test3
.isEmpty()) {
1412 errln("bogus.truncate(0) failed");
1416 if(!test3
.isBogus() || test3
.setTo((UChar32
)-1).isBogus() || !test3
.isEmpty()) {
1417 errln("bogus.setTo((UChar32)-1) failed");
1420 static const UChar nul
=0;
1423 if(!test3
.isBogus() || test3
.setTo(&nul
, 0).isBogus() || !test3
.isEmpty()) {
1424 errln("bogus.setTo(&nul, 0) failed");
1428 if(!test3
.isBogus() || test3
.getBuffer()!=0) {
1429 errln("setToBogus() failed to make a string bogus");
1433 if(test1
.isBogus() || !(test1
=test3
).isBogus()) {
1434 errln("normal=bogus failed to make the left string bogus");
1437 // test that NULL primitive input string values are treated like
1438 // empty strings, not errors (bogus)
1439 test2
.setTo((UChar32
)0x10005);
1440 if(test2
.insert(1, NULL
, 1).length()!=2) {
1441 errln("UniStr.insert(...NULL...) should not modify the string but does");
1444 UErrorCode errorCode
=U_ZERO_ERROR
;
1446 test4((const UChar
*)NULL
),
1447 test5(TRUE
, (const UChar
*)NULL
, 1),
1448 test6((UChar
*)NULL
, 5, 5),
1449 test7((const char *)NULL
, 3, NULL
, errorCode
);
1450 if(test4
.isBogus() || test5
.isBogus() || test6
.isBogus() || test7
.isBogus()) {
1451 errln("a constructor set to bogus for a NULL input string, should be empty");
1454 test4
.setTo(NULL
, 3);
1455 test5
.setTo(TRUE
, (const UChar
*)NULL
, 1);
1456 test6
.setTo((UChar
*)NULL
, 5, 5);
1457 if(test4
.isBogus() || test5
.isBogus() || test6
.isBogus()) {
1458 errln("a setTo() set to bogus for a NULL input string, should be empty");
1461 // test that bogus==bogus<any
1462 if(test1
!=test3
|| test1
.compare(test3
)!=0) {
1463 errln("bogus==bogus failed");
1467 if(test1
>=test2
|| !(test2
>test1
) || test1
.compare(test2
)>=0 || !(test2
.compare(test1
)>0)) {
1468 errln("bogus<empty failed");