Home | History | Annotate | Download | only in intltest
      1 /********************************************************************
      2  * COPYRIGHT:
      3  * Copyright (c) 1997-2013, International Business Machines Corporation and
      4  * others. All Rights Reserved.
      5  ********************************************************************/
      6 
      7 #include "ustrtest.h"
      8 #include "unicode/appendable.h"
      9 #include "unicode/std_string.h"
     10 #include "unicode/unistr.h"
     11 #include "unicode/uchar.h"
     12 #include "unicode/ustring.h"
     13 #include "unicode/locid.h"
     14 #include "unicode/ucnv.h"
     15 #include "unicode/uenum.h"
     16 #include "unicode/utf16.h"
     17 #include "cmemory.h"
     18 #include "charstr.h"
     19 
     20 #if 0
     21 #include "unicode/ustream.h"
     22 
     23 #include <iostream>
     24 using namespace std;
     25 
     26 #endif
     27 
     28 #define LENGTHOF(array) (int32_t)((sizeof(array)/sizeof((array)[0])))
     29 
     30 UnicodeStringTest::~UnicodeStringTest() {}
     31 
     32 void UnicodeStringTest::runIndexedTest( int32_t index, UBool exec, const char* &name, char *par)
     33 {
     34     if (exec) logln("TestSuite UnicodeStringTest: ");
     35     switch (index) {
     36         case 0:
     37             name = "StringCaseTest";
     38             if (exec) {
     39                 logln("StringCaseTest---"); logln("");
     40                 StringCaseTest test;
     41                 callTest(test, par);
     42             }
     43             break;
     44         case 1: name = "TestBasicManipulation"; if (exec) TestBasicManipulation(); break;
     45         case 2: name = "TestCompare"; if (exec) TestCompare(); break;
     46         case 3: name = "TestExtract"; if (exec) TestExtract(); break;
     47         case 4: name = "TestRemoveReplace"; if (exec) TestRemoveReplace(); break;
     48         case 5: name = "TestSearching"; if (exec) TestSearching(); break;
     49         case 6: name = "TestSpacePadding"; if (exec) TestSpacePadding(); break;
     50         case 7: name = "TestPrefixAndSuffix"; if (exec) TestPrefixAndSuffix(); break;
     51         case 8: name = "TestFindAndReplace"; if (exec) TestFindAndReplace(); break;
     52         case 9: name = "TestBogus"; if (exec) TestBogus(); break;
     53         case 10: name = "TestReverse"; if (exec) TestReverse(); break;
     54         case 11: name = "TestMiscellaneous"; if (exec) TestMiscellaneous(); break;
     55         case 12: name = "TestStackAllocation"; if (exec) TestStackAllocation(); break;
     56         case 13: name = "TestUnescape"; if (exec) TestUnescape(); break;
     57         case 14: name = "TestCountChar32"; if (exec) TestCountChar32(); break;
     58         case 15: name = "TestStringEnumeration"; if (exec) TestStringEnumeration(); break;
     59         case 16: name = "TestNameSpace"; if (exec) TestNameSpace(); break;
     60         case 17: name = "TestUTF32"; if (exec) TestUTF32(); break;
     61         case 18: name = "TestUTF8"; if (exec) TestUTF8(); break;
     62         case 19: name = "TestReadOnlyAlias"; if (exec) TestReadOnlyAlias(); break;
     63         case 20: name = "TestAppendable"; if (exec) TestAppendable(); break;
     64         case 21: name = "TestUnicodeStringImplementsAppendable"; if (exec) TestUnicodeStringImplementsAppendable(); break;
     65         case 22: name = "TestSizeofUnicodeString"; if (exec) TestSizeofUnicodeString(); break;
     66         case 23: name = "TestStartsWithAndEndsWithNulTerminated"; if (exec) TestStartsWithAndEndsWithNulTerminated(); break;
     67 
     68         default: name = ""; break; //needed to end loop
     69     }
     70 }
     71 
     72 void
     73 UnicodeStringTest::TestBasicManipulation()
     74 {
     75     UnicodeString   test1("Now is the time for all men to come swiftly to the aid of the party.\n");
     76     UnicodeString   expectedValue;
     77     UnicodeString   *c;
     78 
     79     c=(UnicodeString *)test1.clone();
     80     test1.insert(24, "good ");
     81     expectedValue = "Now is the time for all good men to come swiftly to the aid of the party.\n";
     82     if (test1 != expectedValue)
     83         errln("insert() failed:  expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
     84 
     85     c->insert(24, "good ");
     86     if(*c != expectedValue) {
     87         errln("clone()->insert() failed:  expected \"" + expectedValue + "\"\n,got \"" + *c + "\"");
     88     }
     89     delete c;
     90 
     91     test1.remove(41, 8);
     92     expectedValue = "Now is the time for all good men to come to the aid of the party.\n";
     93     if (test1 != expectedValue)
     94         errln("remove() failed:  expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
     95 
     96     test1.replace(58, 6, "ir country");
     97     expectedValue = "Now is the time for all good men to come to the aid of their country.\n";
     98     if (test1 != expectedValue)
     99         errln("replace() failed:  expected \"" + expectedValue + "\"\n,got \"" + test1 + "\"");
    100 
    101     UChar     temp[80];
    102     test1.extract(0, 15, temp);
    103 
    104     UnicodeString       test2(temp, 15);
    105 
    106     expectedValue = "Now is the time";
    107     if (test2 != expectedValue)
    108         errln("extract() failed:  expected \"" + expectedValue + "\"\n,got \"" + test2 + "\"");
    109 
    110     test2 += " for me to go!\n";
    111     expectedValue = "Now is the time for me to go!\n";
    112     if (test2 != expectedValue)
    113         errln("operator+=() failed:  expected \"" + expectedValue + "\"\n,got \"" + test2 + "\"");
    114 
    115     if (test1.length() != 70)
    116         errln(UnicodeString("length() failed: expected 70, got ") + test1.length());
    117     if (test2.length() != 30)
    118         errln(UnicodeString("length() failed: expected 30, got ") + test2.length());
    119 
    120     UnicodeString test3;
    121     test3.append((UChar32)0x20402);
    122     if(test3 != CharsToUnicodeString("\\uD841\\uDC02")){
    123         errln((UnicodeString)"append failed for UChar32, expected \"\\\\ud841\\\\udc02\", got " + prettify(test3));
    124     }
    125     if(test3.length() != 2){
    126         errln(UnicodeString("append or length failed for UChar32, expected 2, got ") + test3.length());
    127     }
    128     test3.append((UChar32)0x0074);
    129     if(test3 != CharsToUnicodeString("\\uD841\\uDC02t")){
    130         errln((UnicodeString)"append failed for UChar32, expected \"\\\\uD841\\\\uDC02t\", got " + prettify(test3));
    131     }
    132     if(test3.length() != 3){
    133         errln((UnicodeString)"append or length failed for UChar32, expected 2, got " + test3.length());
    134     }
    135 
    136     // test some UChar32 overloads
    137     if( test3.setTo((UChar32)0x10330).length() != 2 ||
    138         test3.insert(0, (UChar32)0x20100).length() != 4 ||
    139         test3.replace(2, 2, (UChar32)0xe0061).length() != 4 ||
    140         (test3 = (UChar32)0x14001).length() != 2
    141     ) {
    142         errln((UnicodeString)"simple UChar32 overloads for replace, insert, setTo or = failed");
    143     }
    144 
    145     {
    146         // test moveIndex32()
    147         UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
    148 
    149         if(
    150             s.moveIndex32(2, -1)!=0 ||
    151             s.moveIndex32(2, 1)!=4 ||
    152             s.moveIndex32(2, 2)!=5 ||
    153             s.moveIndex32(5, -2)!=2 ||
    154             s.moveIndex32(0, -1)!=0 ||
    155             s.moveIndex32(6, 1)!=6
    156         ) {
    157             errln("UnicodeString::moveIndex32() failed");
    158         }
    159 
    160         if(s.getChar32Start(1)!=0 || s.getChar32Start(2)!=2) {
    161             errln("UnicodeString::getChar32Start() failed");
    162         }
    163 
    164         if(s.getChar32Limit(1)!=2 || s.getChar32Limit(2)!=2) {
    165             errln("UnicodeString::getChar32Limit() failed");
    166         }
    167     }
    168 
    169     {
    170         // test new 2.2 constructors and setTo function that parallel Java's substring function.
    171         UnicodeString src("Hello folks how are you?");
    172         UnicodeString target1("how are you?");
    173         if (target1 != UnicodeString(src, 12)) {
    174             errln("UnicodeString(const UnicodeString&, int32_t) failed");
    175         }
    176         UnicodeString target2("folks");
    177         if (target2 != UnicodeString(src, 6, 5)) {
    178             errln("UnicodeString(const UnicodeString&, int32_t, int32_t) failed");
    179         }
    180         if (target1 != target2.setTo(src, 12)) {
    181             errln("UnicodeString::setTo(const UnicodeString&, int32_t) failed");
    182         }
    183     }
    184 
    185     {
    186         // op+ is new in ICU 2.8
    187         UnicodeString s=UnicodeString("abc", "")+UnicodeString("def", "")+UnicodeString("ghi", "");
    188         if(s!=UnicodeString("abcdefghi", "")) {
    189             errln("operator+(UniStr, UniStr) failed");
    190         }
    191     }
    192 
    193     {
    194         // tests for Jitterbug 2360
    195         // verify that APIs with source pointer + length accept length == -1
    196         // mostly test only where modified, only few functions did not already do this
    197         if(UnicodeString("abc", -1, "")!=UnicodeString("abc", "")) {
    198             errln("UnicodeString(codepageData, dataLength, codepage) does not work with dataLength==-1");
    199         }
    200 
    201         UChar buffer[10]={ 0x61, 0x62, 0x20ac, 0xd900, 0xdc05, 0,   0x62, 0xffff, 0xdbff, 0xdfff };
    202         UnicodeString s, t(buffer, -1, LENGTHOF(buffer));
    203 
    204         if(s.setTo(buffer, -1, LENGTHOF(buffer)).length()!=u_strlen(buffer)) {
    205             errln("UnicodeString.setTo(buffer, length, capacity) does not work with length==-1");
    206         }
    207         if(t.length()!=u_strlen(buffer)) {
    208             errln("UnicodeString(buffer, length, capacity) does not work with length==-1");
    209         }
    210 
    211         if(0!=s.caseCompare(buffer, -1, U_FOLD_CASE_DEFAULT)) {
    212             errln("UnicodeString.caseCompare(const UChar *, length, options) does not work with length==-1");
    213         }
    214         if(0!=s.caseCompare(0, s.length(), buffer, U_FOLD_CASE_DEFAULT)) {
    215             errln("UnicodeString.caseCompare(start, _length, const UChar *, options) does not work");
    216         }
    217 
    218         buffer[u_strlen(buffer)]=0xe4;
    219         UnicodeString u(buffer, -1, LENGTHOF(buffer));
    220         if(s.setTo(buffer, -1, LENGTHOF(buffer)).length()!=LENGTHOF(buffer)) {
    221             errln("UnicodeString.setTo(buffer without NUL, length, capacity) does not work with length==-1");
    222         }
    223         if(u.length()!=LENGTHOF(buffer)) {
    224             errln("UnicodeString(buffer without NUL, length, capacity) does not work with length==-1");
    225         }
    226 
    227         static const char cs[]={ 0x61, (char)0xe4, (char)0x85, 0 };
    228         UConverter *cnv;
    229         UErrorCode errorCode=U_ZERO_ERROR;
    230 
    231         cnv=ucnv_open("ISO-8859-1", &errorCode);
    232         UnicodeString v(cs, -1, cnv, errorCode);
    233         ucnv_close(cnv);
    234         if(v!=CharsToUnicodeString("a\\xe4\\x85")) {
    235             errln("UnicodeString(const char *, length, cnv, errorCode) does not work with length==-1");
    236         }
    237     }
    238 
    239 #if U_CHARSET_IS_UTF8
    240     {
    241         // Test the hardcoded-UTF-8 UnicodeString optimizations.
    242         static const uint8_t utf8[]={ 0x61, 0xC3, 0xA4, 0xC3, 0x9F, 0xE4, 0xB8, 0x80, 0 };
    243         static const UChar utf16[]={ 0x61, 0xE4, 0xDF, 0x4E00 };
    244         UnicodeString from8a = UnicodeString((const char *)utf8);
    245         UnicodeString from8b = UnicodeString((const char *)utf8, (int32_t)sizeof(utf8)-1);
    246         UnicodeString from16(FALSE, utf16, LENGTHOF(utf16));
    247         if(from8a != from16 || from8b != from16) {
    248             errln("UnicodeString(const char * U_CHARSET_IS_UTF8) failed");
    249         }
    250         char buffer[16];
    251         int32_t length8=from16.extract(0, 0x7fffffff, buffer, (uint32_t)sizeof(buffer));
    252         if(length8!=((int32_t)sizeof(utf8)-1) || 0!=uprv_memcmp(buffer, utf8, sizeof(utf8))) {
    253             errln("UnicodeString::extract(char * U_CHARSET_IS_UTF8) failed");
    254         }
    255         length8=from16.extract(1, 2, buffer, (uint32_t)sizeof(buffer));
    256         if(length8!=4 || buffer[length8]!=0 || 0!=uprv_memcmp(buffer, utf8+1, length8)) {
    257             errln("UnicodeString::extract(substring to char * U_CHARSET_IS_UTF8) failed");
    258         }
    259     }
    260 #endif
    261 }
    262 
    263 void
    264 UnicodeStringTest::TestCompare()
    265 {
    266     UnicodeString   test1("this is a test");
    267     UnicodeString   test2("this is a test");
    268     UnicodeString   test3("this is a test of the emergency broadcast system");
    269     UnicodeString   test4("never say, \"this is a test\"!!");
    270 
    271     UnicodeString   test5((UChar)0x5000);
    272     UnicodeString   test6((UChar)0x5100);
    273 
    274     UChar         uniChars[] = { 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73,
    275                  0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0 };
    276     char            chars[] = "this is a test";
    277 
    278     // test operator== and operator!=
    279     if (test1 != test2 || test1 == test3 || test1 == test4)
    280         errln("operator== or operator!= failed");
    281 
    282     // test operator> and operator<
    283     if (test1 > test2 || test1 < test2 || !(test1 < test3) || !(test1 > test4) ||
    284         !(test5 < test6)
    285     ) {
    286         errln("operator> or operator< failed");
    287     }
    288 
    289     // test operator>= and operator<=
    290     if (!(test1 >= test2) || !(test1 <= test2) || !(test1 <= test3) || !(test1 >= test4))
    291         errln("operator>= or operator<= failed");
    292 
    293     // test compare(UnicodeString)
    294     if (test1.compare(test2) != 0 || test1.compare(test3) >= 0 || test1.compare(test4) <= 0)
    295         errln("compare(UnicodeString) failed");
    296 
    297     //test compare(offset, length, UnicodeString)
    298     if(test1.compare(0, 14, test2) != 0 ||
    299         test3.compare(0, 14, test2) != 0 ||
    300         test4.compare(12, 14, test2) != 0 ||
    301         test3.compare(0, 18, test1) <=0  )
    302         errln("compare(offset, length, UnicodeString) failes");
    303 
    304     // test compare(UChar*)
    305     if (test2.compare(uniChars) != 0 || test3.compare(uniChars) <= 0 || test4.compare(uniChars) >= 0)
    306         errln("compare(UChar*) failed");
    307 
    308     // test compare(char*)
    309     if (test2.compare(chars) != 0 || test3.compare(chars) <= 0 || test4.compare(chars) >= 0)
    310         errln("compare(char*) failed");
    311 
    312     // test compare(UChar*, length)
    313     if (test1.compare(uniChars, 4) <= 0 || test1.compare(uniChars, 4) <= 0)
    314         errln("compare(UChar*, length) failed");
    315 
    316     // test compare(thisOffset, thisLength, that, thatOffset, thatLength)
    317     if (test1.compare(0, 14, test2, 0, 14) != 0
    318     || test1.compare(0, 14, test3, 0, 14) != 0
    319     || test1.compare(0, 14, test4, 12, 14) != 0)
    320         errln("1. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
    321 
    322     if (test1.compare(10, 4, test2, 0, 4) >= 0
    323     || test1.compare(10, 4, test3, 22, 9) <= 0
    324     || test1.compare(10, 4, test4, 22, 4) != 0)
    325         errln("2. compare(thisOffset, thisLength, that, thatOffset, thatLength) failed");
    326 
    327     // test compareBetween
    328     if (test1.compareBetween(0, 14, test2, 0, 14) != 0 || test1.compareBetween(0, 14, test3, 0, 14) != 0
    329                     || test1.compareBetween(0, 14, test4, 12, 26) != 0)
    330         errln("compareBetween failed");
    331 
    332     if (test1.compareBetween(10, 14, test2, 0, 4) >= 0 || test1.compareBetween(10, 14, test3, 22, 31) <= 0
    333                     || test1.compareBetween(10, 14, test4, 22, 26) != 0)
    334         errln("compareBetween failed");
    335 
    336     // test compare() etc. with strings that share a buffer but are not equal
    337     test2=test1; // share the buffer, length() too large for the stackBuffer
    338     test2.truncate(1); // change only the length, not the buffer
    339     if( test1==test2 || test1<=test2 ||
    340         test1.compare(test2)<=0 ||
    341         test1.compareCodePointOrder(test2)<=0 ||
    342         test1.compareCodePointOrder(0, INT32_MAX, test2)<=0 ||
    343         test1.compareCodePointOrder(0, INT32_MAX, test2, 0, INT32_MAX)<=0 ||
    344         test1.compareCodePointOrderBetween(0, INT32_MAX, test2, 0, INT32_MAX)<=0 ||
    345         test1.caseCompare(test2, U_FOLD_CASE_DEFAULT)<=0
    346     ) {
    347         errln("UnicodeStrings that share a buffer but have different lengths compare as equal");
    348     }
    349 
    350     /* test compareCodePointOrder() */
    351     {
    352         /* these strings are in ascending order */
    353         static const UChar strings[][4]={
    354             { 0x61, 0 },                    /* U+0061 */
    355             { 0x20ac, 0xd801, 0 },          /* U+20ac U+d801 */
    356             { 0x20ac, 0xd800, 0xdc00, 0 },  /* U+20ac U+10000 */
    357             { 0xd800, 0 },                  /* U+d800 */
    358             { 0xd800, 0xff61, 0 },          /* U+d800 U+ff61 */
    359             { 0xdfff, 0 },                  /* U+dfff */
    360             { 0xff61, 0xdfff, 0 },          /* U+ff61 U+dfff */
    361             { 0xff61, 0xd800, 0xdc02, 0 },  /* U+ff61 U+10002 */
    362             { 0xd800, 0xdc02, 0 },          /* U+10002 */
    363             { 0xd84d, 0xdc56, 0 }           /* U+23456 */
    364         };
    365         UnicodeString u[20]; // must be at least as long as strings[]
    366         int32_t i;
    367 
    368         for(i=0; i<(int32_t)(sizeof(strings)/sizeof(strings[0])); ++i) {
    369             u[i]=UnicodeString(TRUE, strings[i], -1);
    370         }
    371 
    372         for(i=0; i<(int32_t)(sizeof(strings)/sizeof(strings[0])-1); ++i) {
    373             if(u[i].compareCodePointOrder(u[i+1])>=0 || u[i].compareCodePointOrder(0, INT32_MAX, u[i+1].getBuffer())>=0) {
    374                 errln("error: UnicodeString::compareCodePointOrder() fails for string %d and the following one\n", i);
    375             }
    376         }
    377     }
    378 
    379     /* test caseCompare() */
    380     {
    381         static const UChar
    382         _mixed[]=               { 0x61, 0x42, 0x131, 0x3a3, 0xdf,       0x130,       0x49,  0xfb03,           0xd93f, 0xdfff, 0 },
    383         _otherDefault[]=        { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x69, 0x307, 0x69,  0x46, 0x66, 0x49, 0xd93f, 0xdfff, 0 },
    384         _otherExcludeSpecialI[]={ 0x41, 0x62, 0x131, 0x3c3, 0x53, 0x73, 0x69,        0x131, 0x66, 0x46, 0x69, 0xd93f, 0xdfff, 0 },
    385         _different[]=           { 0x41, 0x62, 0x131, 0x3c3, 0x73, 0x53, 0x130,       0x49,  0x46, 0x66, 0x49, 0xd93f, 0xdffd, 0 };
    386 
    387         UnicodeString
    388             mixed(TRUE, _mixed, -1),
    389             otherDefault(TRUE, _otherDefault, -1),
    390             otherExcludeSpecialI(TRUE, _otherExcludeSpecialI, -1),
    391             different(TRUE, _different, -1);
    392 
    393         int8_t result;
    394 
    395         /* test caseCompare() */
    396         result=mixed.caseCompare(otherDefault, U_FOLD_CASE_DEFAULT);
    397         if(result!=0 || 0!=mixed.caseCompareBetween(0, INT32_MAX, otherDefault, 0, INT32_MAX, U_FOLD_CASE_DEFAULT)) {
    398             errln("error: mixed.caseCompare(other, default)=%ld instead of 0\n", result);
    399         }
    400         result=mixed.caseCompare(otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I);
    401         if(result!=0) {
    402             errln("error: mixed.caseCompare(otherExcludeSpecialI, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=%ld instead of 0\n", result);
    403         }
    404         result=mixed.caseCompare(otherDefault, U_FOLD_CASE_EXCLUDE_SPECIAL_I);
    405         if(result==0 || 0==mixed.caseCompareBetween(0, INT32_MAX, otherDefault, 0, INT32_MAX, U_FOLD_CASE_EXCLUDE_SPECIAL_I)) {
    406             errln("error: mixed.caseCompare(other, U_FOLD_CASE_EXCLUDE_SPECIAL_I)=0 instead of !=0\n");
    407         }
    408 
    409         /* test caseCompare() */
    410         result=mixed.caseCompare(different, U_FOLD_CASE_DEFAULT);
    411         if(result<=0) {
    412             errln("error: mixed.caseCompare(different, default)=%ld instead of positive\n", result);
    413         }
    414 
    415         /* test caseCompare() - include the folded sharp s (U+00df) with different lengths */
    416         result=mixed.caseCompare(1, 4, different, 1, 5, U_FOLD_CASE_DEFAULT);
    417         if(result!=0 || 0!=mixed.caseCompareBetween(1, 5, different, 1, 6, U_FOLD_CASE_DEFAULT)) {
    418             errln("error: mixed.caseCompare(mixed, 1, 4, different, 1, 5, default)=%ld instead of 0\n", result);
    419         }
    420 
    421         /* test caseCompare() - stop in the middle of the sharp s (U+00df) */
    422         result=mixed.caseCompare(1, 4, different, 1, 4, U_FOLD_CASE_DEFAULT);
    423         if(result<=0) {
    424             errln("error: mixed.caseCompare(1, 4, different, 1, 4, default)=%ld instead of positive\n", result);
    425         }
    426     }
    427 
    428     // test that srcLength=-1 is handled in functions that
    429     // take input const UChar */int32_t srcLength (j785)
    430     {
    431         static const UChar u[]={ 0x61, 0x308, 0x62, 0 };
    432         UnicodeString s=UNICODE_STRING("a\\u0308b", 8).unescape();
    433 
    434         if(s.compare(u, -1)!=0 || s.compare(0, 999, u, 0, -1)!=0) {
    435             errln("error UnicodeString::compare(..., const UChar *, srcLength=-1) does not work");
    436         }
    437 
    438         if(s.compareCodePointOrder(u, -1)!=0 || s.compareCodePointOrder(0, 999, u, 0, -1)!=0) {
    439             errln("error UnicodeString::compareCodePointOrder(..., const UChar *, srcLength=-1, ...) does not work");
    440         }
    441 
    442         if(s.caseCompare(u, -1, U_FOLD_CASE_DEFAULT)!=0 || s.caseCompare(0, 999, u, 0, -1, U_FOLD_CASE_DEFAULT)!=0) {
    443             errln("error UnicodeString::caseCompare(..., const UChar *, srcLength=-1, ...) does not work");
    444         }
    445 
    446         if(s.indexOf(u, 1, -1, 0, 999)!=1 || s.indexOf(u+1, -1, 0, 999)!=1 || s.indexOf(u+1, -1, 0)!=1) {
    447             errln("error UnicodeString::indexOf(const UChar *, srcLength=-1, ...) does not work");
    448         }
    449 
    450         if(s.lastIndexOf(u, 1, -1, 0, 999)!=1 || s.lastIndexOf(u+1, -1, 0, 999)!=1 || s.lastIndexOf(u+1, -1, 0)!=1) {
    451             errln("error UnicodeString::lastIndexOf(const UChar *, srcLength=-1, ...) does not work");
    452         }
    453 
    454         UnicodeString s2, s3;
    455         s2.replace(0, 0, u+1, -1);
    456         s3.replace(0, 0, u, 1, -1);
    457         if(s.compare(1, 999, s2)!=0 || s2!=s3) {
    458             errln("error UnicodeString::replace(..., const UChar *, srcLength=-1, ...) does not work");
    459         }
    460     }
    461 }
    462 
    463 void
    464 UnicodeStringTest::TestExtract()
    465 {
    466     UnicodeString  test1("Now is the time for all good men to come to the aid of their country.", "");
    467     UnicodeString  test2;
    468     UChar          test3[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
    469     char           test4[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
    470     UnicodeString  test5;
    471     char           test6[13] = {1, 2, 3, 4, 5, 6, 7, 8, 8, 10, 11, 12, 13};
    472 
    473     test1.extract(11, 12, test2);
    474     test1.extract(11, 12, test3);
    475     if (test1.extract(11, 12, test4) != 12 || test4[12] != 0) {
    476         errln("UnicodeString.extract(char *) failed to return the correct size of destination buffer.");
    477     }
    478 
    479     // test proper pinning in extractBetween()
    480     test1.extractBetween(-3, 7, test5);
    481     if(test5!=UNICODE_STRING("Now is ", 7)) {
    482         errln("UnicodeString.extractBetween(-3, 7) did not pin properly.");
    483     }
    484 
    485     test1.extractBetween(11, 23, test5);
    486     if (test1.extract(60, 71, test6) != 9) {
    487         errln("UnicodeString.extract() failed to return the correct size of destination buffer for end of buffer.");
    488     }
    489     if (test1.extract(11, 12, test6) != 12) {
    490         errln("UnicodeString.extract() failed to return the correct size of destination buffer.");
    491     }
    492 
    493     // convert test4 back to Unicode for comparison
    494     UnicodeString test4b(test4, 12);
    495 
    496     if (test1.extract(11, 12, (char *)NULL) != 12) {
    497         errln("UnicodeString.extract(NULL) failed to return the correct size of destination buffer.");
    498     }
    499     if (test1.extract(11, -1, test6) != 0) {
    500         errln("UnicodeString.extract(-1) failed to stop reading the string.");
    501     }
    502 
    503     for (int32_t i = 0; i < 12; i++) {
    504         if (test1.charAt((int32_t)(11 + i)) != test2.charAt(i)) {
    505             errln(UnicodeString("extracting into a UnicodeString failed at position ") + i);
    506             break;
    507         }
    508         if (test1.charAt((int32_t)(11 + i)) != test3[i]) {
    509             errln(UnicodeString("extracting into an array of UChar failed at position ") + i);
    510             break;
    511         }
    512         if (((char)test1.charAt((int32_t)(11 + i))) != test4b.charAt(i)) {
    513             errln(UnicodeString("extracting into an array of char failed at position ") + i);
    514             break;
    515         }
    516         if (test1.charAt((int32_t)(11 + i)) != test5.charAt(i)) {
    517             errln(UnicodeString("extracting with extractBetween failed at position ") + i);
    518             break;
    519         }
    520     }
    521 
    522     // test preflighting and overflows with invariant conversion
    523     if (test1.extract(0, 10, (char *)NULL, "") != 10) {
    524         errln("UnicodeString.extract(0, 10, (char *)NULL, \"\") != 10");
    525     }
    526 
    527     test4[2] = (char)0xff;
    528     if (test1.extract(0, 10, test4, 2, "") != 10) {
    529         errln("UnicodeString.extract(0, 10, test4, 2, \"\") != 10");
    530     }
    531     if (test4[2] != (char)0xff) {
    532         errln("UnicodeString.extract(0, 10, test4, 2, \"\") overwrote test4[2]");
    533     }
    534 
    535     {
    536         // test new, NUL-terminating extract() function
    537         UnicodeString s("terminate", "");
    538         UChar dest[20]={
    539             0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
    540             0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5
    541         };
    542         UErrorCode errorCode;
    543         int32_t length;
    544 
    545         errorCode=U_ZERO_ERROR;
    546         length=s.extract((UChar *)NULL, 0, errorCode);
    547         if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=s.length()) {
    548             errln("UnicodeString.extract(NULL, 0)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)", length, s.length(), u_errorName(errorCode));
    549         }
    550 
    551         errorCode=U_ZERO_ERROR;
    552         length=s.extract(dest, s.length()-1, errorCode);
    553         if(errorCode!=U_BUFFER_OVERFLOW_ERROR || length!=s.length()) {
    554             errln("UnicodeString.extract(dest too short)==%d (%s) expected %d (U_BUFFER_OVERFLOW_ERROR)",
    555                 length, u_errorName(errorCode), s.length());
    556         }
    557 
    558         errorCode=U_ZERO_ERROR;
    559         length=s.extract(dest, s.length(), errorCode);
    560         if(errorCode!=U_STRING_NOT_TERMINATED_WARNING || length!=s.length()) {
    561             errln("UnicodeString.extract(dest just right without NUL)==%d (%s) expected %d (U_STRING_NOT_TERMINATED_WARNING)",
    562                 length, u_errorName(errorCode), s.length());
    563         }
    564         if(dest[length-1]!=s[length-1] || dest[length]!=0xa5) {
    565             errln("UnicodeString.extract(dest just right without NUL) did not extract the string correctly");
    566         }
    567 
    568         errorCode=U_ZERO_ERROR;
    569         length=s.extract(dest, s.length()+1, errorCode);
    570         if(errorCode!=U_ZERO_ERROR || length!=s.length()) {
    571             errln("UnicodeString.extract(dest large enough)==%d (%s) expected %d (U_ZERO_ERROR)",
    572                 length, u_errorName(errorCode), s.length());
    573         }
    574         if(dest[length-1]!=s[length-1] || dest[length]!=0 || dest[length+1]!=0xa5) {
    575             errln("UnicodeString.extract(dest large enough) did not extract the string correctly");
    576         }
    577     }
    578 
    579     {
    580         // test new UConverter extract() and constructor
    581         UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
    582         char buffer[32];
    583         static const char expect[]={
    584             (char)0xf0, (char)0xaf, (char)0xa6, (char)0x99,
    585             (char)0xf0, (char)0x9d, (char)0x85, (char)0x9f,
    586             (char)0xc3, (char)0x84,
    587             (char)0xe1, (char)0xbb, (char)0x90
    588         };
    589         UErrorCode errorCode=U_ZERO_ERROR;
    590         UConverter *cnv=ucnv_open("UTF-8", &errorCode);
    591         int32_t length;
    592 
    593         if(U_SUCCESS(errorCode)) {
    594             // test preflighting
    595             if( (length=s.extract(NULL, 0, cnv, errorCode))!=13 ||
    596                 errorCode!=U_BUFFER_OVERFLOW_ERROR
    597             ) {
    598                 errln("UnicodeString::extract(NULL, UConverter) preflighting failed (length=%ld, %s)",
    599                       length, u_errorName(errorCode));
    600             }
    601             errorCode=U_ZERO_ERROR;
    602             if( (length=s.extract(buffer, 2, cnv, errorCode))!=13 ||
    603                 errorCode!=U_BUFFER_OVERFLOW_ERROR
    604             ) {
    605                 errln("UnicodeString::extract(too small, UConverter) preflighting failed (length=%ld, %s)",
    606                       length, u_errorName(errorCode));
    607             }
    608 
    609             // try error cases
    610             errorCode=U_ZERO_ERROR;
    611             if( s.extract(NULL, 2, cnv, errorCode)==13 || U_SUCCESS(errorCode)) {
    612                 errln("UnicodeString::extract(UConverter) succeeded with an illegal destination");
    613             }
    614             errorCode=U_ILLEGAL_ARGUMENT_ERROR;
    615             if( s.extract(NULL, 0, cnv, errorCode)==13 || U_SUCCESS(errorCode)) {
    616                 errln("UnicodeString::extract(UConverter) succeeded with a previous error code");
    617             }
    618             errorCode=U_ZERO_ERROR;
    619 
    620             // extract for real
    621             if( (length=s.extract(buffer, sizeof(buffer), cnv, errorCode))!=13 ||
    622                 uprv_memcmp(buffer, expect, 13)!=0 ||
    623                 buffer[13]!=0 ||
    624                 U_FAILURE(errorCode)
    625             ) {
    626                 errln("UnicodeString::extract(UConverter) conversion failed (length=%ld, %s)",
    627                       length, u_errorName(errorCode));
    628             }
    629             // Test again with just the converter name.
    630             if( (length=s.extract(0, s.length(), buffer, sizeof(buffer), "UTF-8"))!=13 ||
    631                 uprv_memcmp(buffer, expect, 13)!=0 ||
    632                 buffer[13]!=0 ||
    633                 U_FAILURE(errorCode)
    634             ) {
    635                 errln("UnicodeString::extract(\"UTF-8\") conversion failed (length=%ld, %s)",
    636                       length, u_errorName(errorCode));
    637             }
    638 
    639             // try the constructor
    640             UnicodeString t(expect, sizeof(expect), cnv, errorCode);
    641             if(U_FAILURE(errorCode) || s!=t) {
    642                 errln("UnicodeString(UConverter) conversion failed (%s)",
    643                       u_errorName(errorCode));
    644             }
    645 
    646             ucnv_close(cnv);
    647         }
    648     }
    649 }
    650 
    651 void
    652 UnicodeStringTest::TestRemoveReplace()
    653 {
    654     UnicodeString   test1("The rain in Spain stays mainly on the plain");
    655     UnicodeString   test2("eat SPAMburgers!");
    656     UChar         test3[] = { 0x53, 0x50, 0x41, 0x4d, 0x4d, 0 };
    657     char            test4[] = "SPAM";
    658     UnicodeString&  test5 = test1;
    659 
    660     test1.replace(4, 4, test2, 4, 4);
    661     test1.replace(12, 5, test3, 4);
    662     test3[4] = 0;
    663     test1.replace(17, 4, test3);
    664     test1.replace(23, 4, test4);
    665     test1.replaceBetween(37, 42, test2, 4, 8);
    666 
    667     if (test1 != "The SPAM in SPAM SPAMs SPAMly on the SPAM")
    668         errln("One of the replace methods failed:\n"
    669               "  expected \"The SPAM in SPAM SPAMs SPAMly on the SPAM\",\n"
    670               "  got \"" + test1 + "\"");
    671 
    672     test1.remove(21, 1);
    673     test1.removeBetween(26, 28);
    674 
    675     if (test1 != "The SPAM in SPAM SPAM SPAM on the SPAM")
    676         errln("One of the remove methods failed:\n"
    677               "  expected \"The SPAM in SPAM SPAM SPAM on the SPAM\",\n"
    678               "  got \"" + test1 + "\"");
    679 
    680     for (int32_t i = 0; i < test1.length(); i++) {
    681         if (test5[i] != 0x53 && test5[i] != 0x50 && test5[i] != 0x41 && test5[i] != 0x4d && test5[i] != 0x20) {
    682             test1.setCharAt(i, 0x78);
    683         }
    684     }
    685 
    686     if (test1 != "xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM")
    687         errln("One of the remove methods failed:\n"
    688               "  expected \"xxx SPAM xx SPAM SPAM SPAM xx xxx SPAM\",\n"
    689               "  got \"" + test1 + "\"");
    690 
    691     test1.remove();
    692     if (test1.length() != 0)
    693         errln("Remove() failed: expected empty string, got \"" + test1 + "\"");
    694 }
    695 
    696 void
    697 UnicodeStringTest::TestSearching()
    698 {
    699     UnicodeString test1("test test ttest tetest testesteststt");
    700     UnicodeString test2("test");
    701     UChar testChar = 0x74;
    702 
    703     UChar32 testChar32 = 0x20402;
    704     UChar testData[]={
    705         //   0       1       2       3       4       5       6       7
    706         0xd841, 0xdc02, 0x0071, 0xdc02, 0xd841, 0x0071, 0xd841, 0xdc02,
    707 
    708         //   8       9      10      11      12      13      14      15
    709         0x0071, 0x0072, 0xd841, 0xdc02, 0x0071, 0xd841, 0xdc02, 0x0071,
    710 
    711         //  16      17      18      19
    712         0xdc02, 0xd841, 0x0073, 0x0000
    713     };
    714     UnicodeString test3(testData);
    715     UnicodeString test4(testChar32);
    716 
    717     uint16_t occurrences = 0;
    718     int32_t startPos = 0;
    719     for ( ;
    720           startPos != -1 && startPos < test1.length();
    721           (startPos = test1.indexOf(test2, startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
    722         ;
    723     if (occurrences != 6)
    724         errln(UnicodeString("indexOf failed: expected to find 6 occurrences, found ") + occurrences);
    725 
    726     for ( occurrences = 0, startPos = 10;
    727           startPos != -1 && startPos < test1.length();
    728           (startPos = test1.indexOf(test2, startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
    729         ;
    730     if (occurrences != 4)
    731         errln(UnicodeString("indexOf with starting offset failed: "
    732                             "expected to find 4 occurrences, found ") + occurrences);
    733 
    734     int32_t endPos = 28;
    735     for ( occurrences = 0, startPos = 5;
    736           startPos != -1 && startPos < test1.length();
    737           (startPos = test1.indexOf(test2, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
    738         ;
    739     if (occurrences != 4)
    740         errln(UnicodeString("indexOf with starting and ending offsets failed: "
    741                             "expected to find 4 occurrences, found ") + occurrences);
    742 
    743     //using UChar32 string
    744     for ( startPos=0, occurrences=0;
    745           startPos != -1 && startPos < test3.length();
    746           (startPos = test3.indexOf(test4, startPos)) != -1 ? (++occurrences, startPos += 2) : 0)
    747         ;
    748     if (occurrences != 4)
    749         errln((UnicodeString)"indexOf failed: expected to find 4 occurrences, found " + occurrences);
    750 
    751     for ( startPos=10, occurrences=0;
    752           startPos != -1 && startPos < test3.length();
    753           (startPos = test3.indexOf(test4, startPos)) != -1 ? (++occurrences, startPos += 2) : 0)
    754         ;
    755     if (occurrences != 2)
    756         errln(UnicodeString("indexOf failed: expected to find 2 occurrences, found ") + occurrences);
    757     //---
    758 
    759     for ( occurrences = 0, startPos = 0;
    760           startPos != -1 && startPos < test1.length();
    761           (startPos = test1.indexOf(testChar, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    762         ;
    763     if (occurrences != 16)
    764         errln(UnicodeString("indexOf with character failed: "
    765                             "expected to find 16 occurrences, found ") + occurrences);
    766 
    767     for ( occurrences = 0, startPos = 10;
    768           startPos != -1 && startPos < test1.length();
    769           (startPos = test1.indexOf(testChar, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    770         ;
    771     if (occurrences != 12)
    772         errln(UnicodeString("indexOf with character & start offset failed: "
    773                             "expected to find 12 occurrences, found ") + occurrences);
    774 
    775     for ( occurrences = 0, startPos = 5, endPos = 28;
    776           startPos != -1 && startPos < test1.length();
    777           (startPos = test1.indexOf(testChar, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    778         ;
    779     if (occurrences != 10)
    780         errln(UnicodeString("indexOf with character & start & end offsets failed: "
    781                             "expected to find 10 occurrences, found ") + occurrences);
    782 
    783     //testing for UChar32
    784     UnicodeString subString;
    785     for( occurrences =0, startPos=0; startPos < test3.length(); startPos +=1){
    786         subString.append(test3, startPos, test3.length());
    787         if(subString.indexOf(testChar32) != -1 ){
    788              ++occurrences;
    789         }
    790         subString.remove();
    791     }
    792     if (occurrences != 14)
    793         errln((UnicodeString)"indexOf failed: expected to find 14 occurrences, found " + occurrences);
    794 
    795     for ( occurrences = 0, startPos = 0;
    796           startPos != -1 && startPos < test3.length();
    797           (startPos = test3.indexOf(testChar32, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    798         ;
    799     if (occurrences != 4)
    800         errln((UnicodeString)"indexOf failed: expected to find 4 occurrences, found " + occurrences);
    801 
    802     endPos=test3.length();
    803     for ( occurrences = 0, startPos = 5;
    804           startPos != -1 && startPos < test3.length();
    805           (startPos = test3.indexOf(testChar32, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    806         ;
    807     if (occurrences != 3)
    808         errln((UnicodeString)"indexOf with character & start & end offsets failed: expected to find 2 occurrences, found " + occurrences);
    809     //---
    810 
    811     if(test1.lastIndexOf(test2)!=29) {
    812         errln("test1.lastIndexOf(test2)!=29");
    813     }
    814 
    815     if(test1.lastIndexOf(test2, 15)!=29 || test1.lastIndexOf(test2, 29)!=29 || test1.lastIndexOf(test2, 30)!=-1) {
    816         errln("test1.lastIndexOf(test2, start) failed");
    817     }
    818 
    819     for ( occurrences = 0, startPos = 32;
    820           startPos != -1;
    821           (startPos = test1.lastIndexOf(test2, 5, startPos - 5)) != -1 ? ++occurrences : 0)
    822         ;
    823     if (occurrences != 4)
    824         errln(UnicodeString("lastIndexOf with starting and ending offsets failed: "
    825                             "expected to find 4 occurrences, found ") + occurrences);
    826 
    827     for ( occurrences = 0, startPos = 32;
    828           startPos != -1;
    829           (startPos = test1.lastIndexOf(testChar, 5, startPos - 5)) != -1 ? ++occurrences : 0)
    830         ;
    831     if (occurrences != 11)
    832         errln(UnicodeString("lastIndexOf with character & start & end offsets failed: "
    833                             "expected to find 11 occurrences, found ") + occurrences);
    834 
    835     //testing UChar32
    836     startPos=test3.length();
    837     for ( occurrences = 0;
    838           startPos != -1;
    839           (startPos = test3.lastIndexOf(testChar32, 5, startPos - 5)) != -1 ? ++occurrences : 0)
    840         ;
    841     if (occurrences != 3)
    842         errln((UnicodeString)"lastIndexOf with character & start & end offsets failed: expected to find 3 occurrences, found " + occurrences);
    843 
    844 
    845     for ( occurrences = 0, endPos = test3.length();  endPos > 0; endPos -= 1){
    846         subString.remove();
    847         subString.append(test3, 0, endPos);
    848         if(subString.lastIndexOf(testChar32) != -1 ){
    849             ++occurrences;
    850         }
    851     }
    852     if (occurrences != 18)
    853         errln((UnicodeString)"indexOf failed: expected to find 18 occurrences, found " + occurrences);
    854     //---
    855 
    856     // test that indexOf(UChar32) and lastIndexOf(UChar32)
    857     // do not find surrogate code points when they are part of matched pairs
    858     // (= part of supplementary code points)
    859     // Jitterbug 1542
    860     if(test3.indexOf((UChar32)0xd841) != 4 || test3.indexOf((UChar32)0xdc02) != 3) {
    861         errln("error: UnicodeString::indexOf(UChar32 surrogate) finds a partial supplementary code point");
    862     }
    863     if( UnicodeString(test3, 0, 17).lastIndexOf((UChar)0xd841, 0) != 4 ||
    864         UnicodeString(test3, 0, 17).lastIndexOf((UChar32)0xd841, 2) != 4 ||
    865         test3.lastIndexOf((UChar32)0xd841, 0, 17) != 4 || test3.lastIndexOf((UChar32)0xdc02, 0, 17) != 16
    866     ) {
    867         errln("error: UnicodeString::lastIndexOf(UChar32 surrogate) finds a partial supplementary code point");
    868     }
    869 }
    870 
    871 void
    872 UnicodeStringTest::TestSpacePadding()
    873 {
    874     UnicodeString test1("hello");
    875     UnicodeString test2("   there");
    876     UnicodeString test3("Hi!  How ya doin'?  Beautiful day, isn't it?");
    877     UnicodeString test4;
    878     UBool returnVal;
    879     UnicodeString expectedValue;
    880 
    881     returnVal = test1.padLeading(15);
    882     expectedValue = "          hello";
    883     if (returnVal == FALSE || test1 != expectedValue)
    884         errln("padLeading() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
    885 
    886     returnVal = test2.padTrailing(15);
    887     expectedValue = "   there       ";
    888     if (returnVal == FALSE || test2 != expectedValue)
    889         errln("padTrailing() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
    890 
    891     expectedValue = test3;
    892     returnVal = test3.padTrailing(15);
    893     if (returnVal == TRUE || test3 != expectedValue)
    894         errln("padTrailing() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
    895 
    896     expectedValue = "hello";
    897     test4.setTo(test1).trim();
    898 
    899     if (test4 != expectedValue || test1 == expectedValue || test4 != expectedValue)
    900         errln("trim(UnicodeString&) failed");
    901 
    902     test1.trim();
    903     if (test1 != expectedValue)
    904         errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
    905 
    906     test2.trim();
    907     expectedValue = "there";
    908     if (test2 != expectedValue)
    909         errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
    910 
    911     test3.trim();
    912     expectedValue = "Hi!  How ya doin'?  Beautiful day, isn't it?";
    913     if (test3 != expectedValue)
    914         errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
    915 
    916     returnVal = test1.truncate(15);
    917     expectedValue = "hello";
    918     if (returnVal == TRUE || test1 != expectedValue)
    919         errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
    920 
    921     returnVal = test2.truncate(15);
    922     expectedValue = "there";
    923     if (returnVal == TRUE || test2 != expectedValue)
    924         errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
    925 
    926     returnVal = test3.truncate(15);
    927     expectedValue = "Hi!  How ya doi";
    928     if (returnVal == FALSE || test3 != expectedValue)
    929         errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
    930 }
    931 
    932 void
    933 UnicodeStringTest::TestPrefixAndSuffix()
    934 {
    935     UnicodeString test1("Now is the time for all good men to come to the aid of their country.");
    936     UnicodeString test2("Now");
    937     UnicodeString test3("country.");
    938     UnicodeString test4("count");
    939 
    940     if (!test1.startsWith(test2) || !test1.startsWith(test2, 0, test2.length())) {
    941         errln("startsWith() failed: \"" + test2 + "\" should be a prefix of \"" + test1 + "\".");
    942     }
    943 
    944     if (test1.startsWith(test3) ||
    945         test1.startsWith(test3.getBuffer(), test3.length()) ||
    946         test1.startsWith(test3.getTerminatedBuffer(), 0, -1)
    947     ) {
    948         errln("startsWith() failed: \"" + test3 + "\" shouldn't be a prefix of \"" + test1 + "\".");
    949     }
    950 
    951     if (test1.endsWith(test2)) {
    952         errln("endsWith() failed: \"" + test2 + "\" shouldn't be a suffix of \"" + test1 + "\".");
    953     }
    954 
    955     if (!test1.endsWith(test3)) {
    956         errln("endsWith(test3) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
    957     }
    958     if (!test1.endsWith(test3, 0, INT32_MAX)) {
    959         errln("endsWith(test3, 0, INT32_MAX) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
    960     }
    961 
    962     if(!test1.endsWith(test3.getBuffer(), test3.length())) {
    963         errln("endsWith(test3.getBuffer(), test3.length()) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
    964     }
    965     if(!test1.endsWith(test3.getTerminatedBuffer(), 0, -1)) {
    966         errln("endsWith(test3.getTerminatedBuffer(), 0, -1) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
    967     }
    968 
    969     if (!test3.startsWith(test4)) {
    970         errln("endsWith(test4) failed: \"" + test4 + "\" should be a prefix of \"" + test3 + "\".");
    971     }
    972 
    973     if (test4.startsWith(test3)) {
    974         errln("startsWith(test3) failed: \"" + test3 + "\" shouldn't be a prefix of \"" + test4 + "\".");
    975     }
    976 }
    977 
    978 void
    979 UnicodeStringTest::TestStartsWithAndEndsWithNulTerminated() {
    980     UnicodeString test("abcde");
    981     const UChar ab[] = { 0x61, 0x62, 0 };
    982     const UChar de[] = { 0x64, 0x65, 0 };
    983     assertTrue("abcde.startsWith(ab, -1)", test.startsWith(ab, -1));
    984     assertTrue("abcde.startsWith(ab, 0, -1)", test.startsWith(ab, 0, -1));
    985     assertTrue("abcde.endsWith(de, -1)", test.endsWith(de, -1));
    986     assertTrue("abcde.endsWith(de, 0, -1)", test.endsWith(de, 0, -1));
    987 }
    988 
    989 void
    990 UnicodeStringTest::TestFindAndReplace()
    991 {
    992     UnicodeString test1("One potato, two potato, three potato, four\n");
    993     UnicodeString test2("potato");
    994     UnicodeString test3("MISSISSIPPI");
    995 
    996     UnicodeString expectedValue;
    997 
    998     test1.findAndReplace(test2, test3);
    999     expectedValue = "One MISSISSIPPI, two MISSISSIPPI, three MISSISSIPPI, four\n";
   1000     if (test1 != expectedValue)
   1001         errln("findAndReplace failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
   1002     test1.findAndReplace(2, 32, test3, test2);
   1003     expectedValue = "One potato, two potato, three MISSISSIPPI, four\n";
   1004     if (test1 != expectedValue)
   1005         errln("findAndReplace failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
   1006 }
   1007 
   1008 void
   1009 UnicodeStringTest::TestReverse()
   1010 {
   1011     UnicodeString test("backwards words say to used I");
   1012 
   1013     test.reverse();
   1014     test.reverse(2, 4);
   1015     test.reverse(7, 2);
   1016     test.reverse(10, 3);
   1017     test.reverse(14, 5);
   1018     test.reverse(20, 9);
   1019 
   1020     if (test != "I used to say words backwards")
   1021         errln("reverse() failed:  Expected \"I used to say words backwards\",\n got \""
   1022             + test + "\"");
   1023 
   1024     test=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
   1025     test.reverse();
   1026     if(test.char32At(0)!=0x1ed0 || test.char32At(1)!=0xc4 || test.char32At(2)!=0x1d15f || test.char32At(4)!=0x2f999) {
   1027         errln("reverse() failed with supplementary characters");
   1028     }
   1029 
   1030     // Test case for ticket #8091:
   1031     // UnicodeString::reverse() failed to see a lead surrogate in the middle of
   1032     // an odd-length string that contains no other lead surrogates.
   1033     test=UNICODE_STRING_SIMPLE("ab\\U0001F4A9e").unescape();
   1034     UnicodeString expected=UNICODE_STRING_SIMPLE("e\\U0001F4A9ba").unescape();
   1035     test.reverse();
   1036     if(test!=expected) {
   1037         errln("reverse() failed with only lead surrogate in the middle");
   1038     }
   1039 }
   1040 
   1041 void
   1042 UnicodeStringTest::TestMiscellaneous()
   1043 {
   1044     UnicodeString   test1("This is a test");
   1045     UnicodeString   test2("This is a test");
   1046     UnicodeString   test3("Me too!");
   1047 
   1048     // test getBuffer(minCapacity) and releaseBuffer()
   1049     test1=UnicodeString(); // make sure that it starts with its stackBuffer
   1050     UChar *p=test1.getBuffer(20);
   1051     if(test1.getCapacity()<20) {
   1052         errln("UnicodeString::getBuffer(20).getCapacity()<20");
   1053     }
   1054 
   1055     test1.append((UChar)7); // must not be able to modify the string here
   1056     test1.setCharAt(3, 7);
   1057     test1.reverse();
   1058     if( test1.length()!=0 ||
   1059         test1.charAt(0)!=0xffff || test1.charAt(3)!=0xffff ||
   1060         test1.getBuffer(10)!=0 || test1.getBuffer()!=0
   1061     ) {
   1062         errln("UnicodeString::getBuffer(minCapacity) allows read or write access to the UnicodeString");
   1063     }
   1064 
   1065     p[0]=1;
   1066     p[1]=2;
   1067     p[2]=3;
   1068     test1.releaseBuffer(3);
   1069     test1.append((UChar)4);
   1070 
   1071     if(test1.length()!=4 || test1.charAt(0)!=1 || test1.charAt(1)!=2 || test1.charAt(2)!=3 || test1.charAt(3)!=4) {
   1072         errln("UnicodeString::releaseBuffer(newLength) does not properly reallow access to the UnicodeString");
   1073     }
   1074 
   1075     // test releaseBuffer() without getBuffer(minCapacity) - must not have any effect
   1076     test1.releaseBuffer(1);
   1077     if(test1.length()!=4 || test1.charAt(0)!=1 || test1.charAt(1)!=2 || test1.charAt(2)!=3 || test1.charAt(3)!=4) {
   1078         errln("UnicodeString::releaseBuffer(newLength) without getBuffer(minCapacity) changed the UnicodeString");
   1079     }
   1080 
   1081     // test getBuffer(const)
   1082     const UChar *q=test1.getBuffer(), *r=test1.getBuffer();
   1083     if( test1.length()!=4 ||
   1084         q[0]!=1 || q[1]!=2 || q[2]!=3 || q[3]!=4 ||
   1085         r[0]!=1 || r[1]!=2 || r[2]!=3 || r[3]!=4
   1086     ) {
   1087         errln("UnicodeString::getBuffer(const) does not return a usable buffer pointer");
   1088     }
   1089 
   1090     // test releaseBuffer() with a NUL-terminated buffer
   1091     test1.getBuffer(20)[2]=0;
   1092     test1.releaseBuffer(); // implicit -1
   1093     if(test1.length()!=2 || test1.charAt(0)!=1 || test1.charAt(1) !=2) {
   1094         errln("UnicodeString::releaseBuffer(-1) does not properly set the length of the UnicodeString");
   1095     }
   1096 
   1097     // test releaseBuffer() with a non-NUL-terminated buffer
   1098     p=test1.getBuffer(256);
   1099     for(int32_t i=0; i<test1.getCapacity(); ++i) {
   1100         p[i]=(UChar)1;      // fill the buffer with all non-NUL code units
   1101     }
   1102     test1.releaseBuffer();  // implicit -1
   1103     if(test1.length()!=test1.getCapacity() || test1.charAt(1)!=1 || test1.charAt(100)!=1 || test1.charAt(test1.getCapacity()-1)!=1) {
   1104         errln("UnicodeString::releaseBuffer(-1 but no NUL) does not properly set the length of the UnicodeString");
   1105     }
   1106 
   1107     // test getTerminatedBuffer()
   1108     test1=UnicodeString("This is another test.", "");
   1109     test2=UnicodeString("This is another test.", "");
   1110     q=test1.getTerminatedBuffer();
   1111     if(q[test1.length()]!=0 || test1!=test2 || test2.compare(q, -1)!=0) {
   1112         errln("getTerminatedBuffer()[length]!=0");
   1113     }
   1114 
   1115     const UChar u[]={ 5, 6, 7, 8, 0 };
   1116     test1.setTo(FALSE, u, 3);
   1117     q=test1.getTerminatedBuffer();
   1118     if(q==u || q[0]!=5 || q[1]!=6 || q[2]!=7 || q[3]!=0) {
   1119         errln("UnicodeString(u[3]).getTerminatedBuffer() returns a bad buffer");
   1120     }
   1121 
   1122     test1.setTo(TRUE, u, -1);
   1123     q=test1.getTerminatedBuffer();
   1124     if(q!=u || test1.length()!=4 || q[3]!=8 || q[4]!=0) {
   1125         errln("UnicodeString(u[-1]).getTerminatedBuffer() returns a bad buffer");
   1126     }
   1127 
   1128     test1=UNICODE_STRING("la", 2);
   1129     test1.append(UNICODE_STRING(" lila", 5).getTerminatedBuffer(), 0, -1);
   1130     if(test1!=UNICODE_STRING("la lila", 7)) {
   1131         errln("UnicodeString::append(const UChar *, start, length) failed");
   1132     }
   1133 
   1134     test1.insert(3, UNICODE_STRING("dudum ", 6), 0, INT32_MAX);
   1135     if(test1!=UNICODE_STRING("la dudum lila", 13)) {
   1136         errln("UnicodeString::insert(start, const UniStr &, start, length) failed");
   1137     }
   1138 
   1139     static const UChar ucs[]={ 0x68, 0x6d, 0x20, 0 };
   1140     test1.insert(9, ucs, -1);
   1141     if(test1!=UNICODE_STRING("la dudum hm lila", 16)) {
   1142         errln("UnicodeString::insert(start, const UChar *, length) failed");
   1143     }
   1144 
   1145     test1.replace(9, 2, (UChar)0x2b);
   1146     if(test1!=UNICODE_STRING("la dudum + lila", 15)) {
   1147         errln("UnicodeString::replace(start, length, UChar) failed");
   1148     }
   1149 
   1150     if(test1.hasMetaData() || UnicodeString().hasMetaData()) {
   1151         errln("UnicodeString::hasMetaData() returns TRUE");
   1152     }
   1153 
   1154     // test getTerminatedBuffer() on a truncated, shared, heap-allocated string
   1155     test1=UNICODE_STRING_SIMPLE("abcdefghijklmnopqrstuvwxyz0123456789.");
   1156     test1.truncate(36);  // ensure length()<getCapacity()
   1157     test2=test1;  // share the buffer
   1158     test1.truncate(5);
   1159     if(test1.length()!=5 || test1.getTerminatedBuffer()[5]!=0) {
   1160         errln("UnicodeString(shared buffer).truncate() failed");
   1161     }
   1162     if(test2.length()!=36 || test2[5]!=0x66 || u_strlen(test2.getTerminatedBuffer())!=36) {
   1163         errln("UnicodeString(shared buffer).truncate().getTerminatedBuffer() "
   1164               "modified another copy of the string!");
   1165     }
   1166     test1=UNICODE_STRING_SIMPLE("abcdefghijklmnopqrstuvwxyz0123456789.");
   1167     test1.truncate(36);  // ensure length()<getCapacity()
   1168     test2=test1;  // share the buffer
   1169     test1.remove();
   1170     if(test1.length()!=0 || test1.getTerminatedBuffer()[0]!=0) {
   1171         errln("UnicodeString(shared buffer).remove() failed");
   1172     }
   1173     if(test2.length()!=36 || test2[0]!=0x61 || u_strlen(test2.getTerminatedBuffer())!=36) {
   1174         errln("UnicodeString(shared buffer).remove().getTerminatedBuffer() "
   1175               "modified another copy of the string!");
   1176     }
   1177 
   1178     // ticket #9740
   1179     test1.setTo(TRUE, ucs, 3);
   1180     assertEquals("length of read-only alias", 3, test1.length());
   1181     test1.trim();
   1182     assertEquals("length of read-only alias after trim()", 2, test1.length());
   1183     assertEquals("length of terminated buffer of read-only alias + trim()",
   1184                  2, u_strlen(test1.getTerminatedBuffer()));
   1185 }
   1186 
   1187 void
   1188 UnicodeStringTest::TestStackAllocation()
   1189 {
   1190     UChar           testString[] ={
   1191         0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x72, 0x61, 0x7a, 0x79, 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0 };
   1192     UChar           guardWord = 0x4DED;
   1193     UnicodeString*  test = 0;
   1194 
   1195     test = new  UnicodeString(testString);
   1196     if (*test != "This is a crazy test.")
   1197         errln("Test string failed to initialize properly.");
   1198     if (guardWord != 0x04DED)
   1199         errln("Test string initialization overwrote guard word!");
   1200 
   1201     test->insert(8, "only ");
   1202     test->remove(15, 6);
   1203     if (*test != "This is only a test.")
   1204         errln("Manipulation of test string failed to work right.");
   1205     if (guardWord != 0x4DED)
   1206         errln("Manipulation of test string overwrote guard word!");
   1207 
   1208     // we have to deinitialize and release the backing store by calling the destructor
   1209     // explicitly, since we can't overload operator delete
   1210     delete test;
   1211 
   1212     UChar workingBuffer[] = {
   1213         0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
   1214         0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20,
   1215         0x63, 0x6f, 0x6d, 0x65, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   1216         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,
   1217         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   1218     UChar guardWord2 = 0x4DED;
   1219 
   1220     test = new UnicodeString(workingBuffer, 35, 100);
   1221     if (*test != "Now is the time for all men to come")
   1222         errln("Stack-allocated backing store failed to initialize correctly.");
   1223     if (guardWord2 != 0x4DED)
   1224         errln("Stack-allocated backing store overwrote guard word!");
   1225 
   1226     test->insert(24, "good ");
   1227     if (*test != "Now is the time for all good men to come")
   1228         errln("insert() on stack-allocated UnicodeString didn't work right");
   1229     if (guardWord2 != 0x4DED)
   1230         errln("insert() on stack-allocated UnicodeString overwrote guard word!");
   1231 
   1232     if (workingBuffer[24] != 0x67)
   1233         errln("insert() on stack-allocated UnicodeString didn't affect backing store");
   1234 
   1235     *test += " to the aid of their country.";
   1236     if (*test != "Now is the time for all good men to come to the aid of their country.")
   1237         errln("Stack-allocated UnicodeString overflow didn't work");
   1238     if (guardWord2 != 0x4DED)
   1239         errln("Stack-allocated UnicodeString overflow overwrote guard word!");
   1240 
   1241     *test = "ha!";
   1242     if (*test != "ha!")
   1243         errln("Assignment to stack-allocated UnicodeString didn't work");
   1244     if (workingBuffer[0] != 0x4e)
   1245         errln("Change to UnicodeString after overflow are still affecting original buffer");
   1246     if (guardWord2 != 0x4DED)
   1247         errln("Change to UnicodeString after overflow overwrote guard word!");
   1248 
   1249     // test read-only aliasing with setTo()
   1250     workingBuffer[0] = 0x20ac;
   1251     workingBuffer[1] = 0x125;
   1252     workingBuffer[2] = 0;
   1253     test->setTo(TRUE, workingBuffer, 2);
   1254     if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x125) {
   1255         errln("UnicodeString.setTo(readonly alias) does not alias correctly");
   1256     }
   1257 
   1258     UnicodeString *c=(UnicodeString *)test->clone();
   1259 
   1260     workingBuffer[1] = 0x109;
   1261     if(test->charAt(1) != 0x109) {
   1262         errln("UnicodeString.setTo(readonly alias) made a copy: did not see change in buffer");
   1263     }
   1264 
   1265     if(c->length() != 2 || c->charAt(1) != 0x125) {
   1266         errln("clone(alias) did not copy the buffer");
   1267     }
   1268     delete c;
   1269 
   1270     test->setTo(TRUE, workingBuffer, -1);
   1271     if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x109) {
   1272         errln("UnicodeString.setTo(readonly alias, length -1) does not alias correctly");
   1273     }
   1274 
   1275     test->setTo(FALSE, workingBuffer, -1);
   1276     if(!test->isBogus()) {
   1277         errln("UnicodeString.setTo(unterminated readonly alias, length -1) does not result in isBogus()");
   1278     }
   1279 
   1280     delete test;
   1281 
   1282     test=new UnicodeString();
   1283     UChar buffer[]={0x0061, 0x0062, 0x20ac, 0x0043, 0x0042, 0x0000};
   1284     test->setTo(buffer, 4, 10);
   1285     if(test->length() !=4 || test->charAt(0) != 0x0061 || test->charAt(1) != 0x0062 ||
   1286         test->charAt(2) != 0x20ac || test->charAt(3) != 0x0043){
   1287         errln((UnicodeString)"UnicodeString.setTo(UChar*, length, capacity) does not work correctly\n" + prettify(*test));
   1288     }
   1289     delete test;
   1290 
   1291 
   1292     // test the UChar32 constructor
   1293     UnicodeString c32Test((UChar32)0x10ff2a);
   1294     if( c32Test.length() != U16_LENGTH(0x10ff2a) ||
   1295         c32Test.char32At(c32Test.length() - 1) != 0x10ff2a
   1296     ) {
   1297         errln("The UnicodeString(UChar32) constructor does not work with a 0x10ff2a filler");
   1298     }
   1299 
   1300     // test the (new) capacity constructor
   1301     UnicodeString capTest(5, (UChar32)0x2a, 5);
   1302     if( capTest.length() != 5 * U16_LENGTH(0x2a) ||
   1303         capTest.char32At(0) != 0x2a ||
   1304         capTest.char32At(4) != 0x2a
   1305     ) {
   1306         errln("The UnicodeString capacity constructor does not work with an ASCII filler");
   1307     }
   1308 
   1309     capTest = UnicodeString(5, (UChar32)0x10ff2a, 5);
   1310     if( capTest.length() != 5 * U16_LENGTH(0x10ff2a) ||
   1311         capTest.char32At(0) != 0x10ff2a ||
   1312         capTest.char32At(4) != 0x10ff2a
   1313     ) {
   1314         errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
   1315     }
   1316 
   1317     capTest = UnicodeString(5, (UChar32)0, 0);
   1318     if(capTest.length() != 0) {
   1319         errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
   1320     }
   1321 }
   1322 
   1323 /**
   1324  * Test the unescape() function.
   1325  */
   1326 void UnicodeStringTest::TestUnescape(void) {
   1327     UnicodeString IN("abc\\u4567 \\n\\r \\U00101234xyz\\x1\\x{5289}\\x1b", -1, US_INV);
   1328     UnicodeString OUT("abc");
   1329     OUT.append((UChar)0x4567);
   1330     OUT.append(" ");
   1331     OUT.append((UChar)0xA);
   1332     OUT.append((UChar)0xD);
   1333     OUT.append(" ");
   1334     OUT.append((UChar32)0x00101234);
   1335     OUT.append("xyz");
   1336     OUT.append((UChar32)1).append((UChar32)0x5289).append((UChar)0x1b);
   1337     UnicodeString result = IN.unescape();
   1338     if (result != OUT) {
   1339         errln("FAIL: " + prettify(IN) + ".unescape() -> " +
   1340               prettify(result) + ", expected " +
   1341               prettify(OUT));
   1342     }
   1343 
   1344     // test that an empty string is returned in case of an error
   1345     if (!UNICODE_STRING("wrong \\u sequence", 17).unescape().isEmpty()) {
   1346         errln("FAIL: unescaping of a string with an illegal escape sequence did not return an empty string");
   1347     }
   1348 }
   1349 
   1350 /* test code point counting functions --------------------------------------- */
   1351 
   1352 /* reference implementation of UnicodeString::hasMoreChar32Than() */
   1353 static int32_t
   1354 _refUnicodeStringHasMoreChar32Than(const UnicodeString &s, int32_t start, int32_t length, int32_t number) {
   1355     int32_t count=s.countChar32(start, length);
   1356     return count>number;
   1357 }
   1358 
   1359 /* compare the real function against the reference */
   1360 void
   1361 UnicodeStringTest::_testUnicodeStringHasMoreChar32Than(const UnicodeString &s, int32_t start, int32_t length, int32_t number) {
   1362     if(s.hasMoreChar32Than(start, length, number)!=_refUnicodeStringHasMoreChar32Than(s, start, length, number)) {
   1363         errln("hasMoreChar32Than(%d, %d, %d)=%hd is wrong\n",
   1364                 start, length, number, s.hasMoreChar32Than(start, length, number));
   1365     }
   1366 }
   1367 
   1368 void
   1369 UnicodeStringTest::TestCountChar32(void) {
   1370     {
   1371         UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
   1372 
   1373         // test countChar32()
   1374         // note that this also calls and tests u_countChar32(length>=0)
   1375         if(
   1376             s.countChar32()!=4 ||
   1377             s.countChar32(1)!=4 ||
   1378             s.countChar32(2)!=3 ||
   1379             s.countChar32(2, 3)!=2 ||
   1380             s.countChar32(2, 0)!=0
   1381         ) {
   1382             errln("UnicodeString::countChar32() failed");
   1383         }
   1384 
   1385         // NUL-terminate the string buffer and test u_countChar32(length=-1)
   1386         const UChar *buffer=s.getTerminatedBuffer();
   1387         if(
   1388             u_countChar32(buffer, -1)!=4 ||
   1389             u_countChar32(buffer+1, -1)!=4 ||
   1390             u_countChar32(buffer+2, -1)!=3 ||
   1391             u_countChar32(buffer+3, -1)!=3 ||
   1392             u_countChar32(buffer+4, -1)!=2 ||
   1393             u_countChar32(buffer+5, -1)!=1 ||
   1394             u_countChar32(buffer+6, -1)!=0
   1395         ) {
   1396             errln("u_countChar32(length=-1) failed");
   1397         }
   1398 
   1399         // test u_countChar32() with bad input
   1400         if(u_countChar32(NULL, 5)!=0 || u_countChar32(buffer, -2)!=0) {
   1401             errln("u_countChar32(bad input) failed (returned non-zero counts)");
   1402         }
   1403     }
   1404 
   1405     /* test data and variables for hasMoreChar32Than() */
   1406     static const UChar str[]={
   1407         0x61, 0x62, 0xd800, 0xdc00,
   1408         0xd801, 0xdc01, 0x63, 0xd802,
   1409         0x64, 0xdc03, 0x65, 0x66,
   1410         0xd804, 0xdc04, 0xd805, 0xdc05,
   1411         0x67
   1412     };
   1413     UnicodeString string(str, LENGTHOF(str));
   1414     int32_t start, length, number;
   1415 
   1416     /* test hasMoreChar32Than() */
   1417     for(length=string.length(); length>=0; --length) {
   1418         for(start=0; start<=length; ++start) {
   1419             for(number=-1; number<=((length-start)+2); ++number) {
   1420                 _testUnicodeStringHasMoreChar32Than(string, start, length-start, number);
   1421             }
   1422         }
   1423     }
   1424 
   1425     /* test hasMoreChar32Than() with pinning */
   1426     for(start=-1; start<=string.length()+1; ++start) {
   1427         for(number=-1; number<=((string.length()-start)+2); ++number) {
   1428             _testUnicodeStringHasMoreChar32Than(string, start, 0x7fffffff, number);
   1429         }
   1430     }
   1431 
   1432     /* test hasMoreChar32Than() with a bogus string */
   1433     string.setToBogus();
   1434     for(length=-1; length<=1; ++length) {
   1435         for(start=-1; start<=length; ++start) {
   1436             for(number=-1; number<=((length-start)+2); ++number) {
   1437                 _testUnicodeStringHasMoreChar32Than(string, start, length-start, number);
   1438             }
   1439         }
   1440     }
   1441 }
   1442 
   1443 void
   1444 UnicodeStringTest::TestBogus() {
   1445     UnicodeString   test1("This is a test");
   1446     UnicodeString   test2("This is a test");
   1447     UnicodeString   test3("Me too!");
   1448 
   1449     // test isBogus() and setToBogus()
   1450     if (test1.isBogus() || test2.isBogus() || test3.isBogus()) {
   1451         errln("A string returned TRUE for isBogus()!");
   1452     }
   1453 
   1454     // NULL pointers are treated like empty strings
   1455     // use other illegal arguments to make a bogus string
   1456     test3.setTo(FALSE, test1.getBuffer(), -2);
   1457     if(!test3.isBogus()) {
   1458         errln("A bogus string returned FALSE for isBogus()!");
   1459     }
   1460     if (test1.hashCode() != test2.hashCode() || test1.hashCode() == test3.hashCode()) {
   1461         errln("hashCode() failed");
   1462     }
   1463     if(test3.getBuffer()!=0 || test3.getBuffer(20)!=0 || test3.getTerminatedBuffer()!=0) {
   1464         errln("bogus.getBuffer()!=0");
   1465     }
   1466     if (test1.indexOf(test3) != -1) {
   1467         errln("bogus.indexOf() != -1");
   1468     }
   1469     if (test1.lastIndexOf(test3) != -1) {
   1470         errln("bogus.lastIndexOf() != -1");
   1471     }
   1472     if (test1.caseCompare(test3, U_FOLD_CASE_DEFAULT) != 1 || test3.caseCompare(test1, U_FOLD_CASE_DEFAULT) != -1) {
   1473         errln("caseCompare() doesn't work with bogus strings");
   1474     }
   1475     if (test1.compareCodePointOrder(test3) != 1 || test3.compareCodePointOrder(test1) != -1) {
   1476         errln("compareCodePointOrder() doesn't work with bogus strings");
   1477     }
   1478 
   1479     // verify that non-assignment modifications fail and do not revive a bogus string
   1480     test3.setToBogus();
   1481     test3.append((UChar)0x61);
   1482     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1483         errln("bogus.append('a') worked but must not");
   1484     }
   1485 
   1486     test3.setToBogus();
   1487     test3.findAndReplace(UnicodeString((UChar)0x61), test2);
   1488     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1489         errln("bogus.findAndReplace() worked but must not");
   1490     }
   1491 
   1492     test3.setToBogus();
   1493     test3.trim();
   1494     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1495         errln("bogus.trim() revived bogus but must not");
   1496     }
   1497 
   1498     test3.setToBogus();
   1499     test3.remove(1);
   1500     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1501         errln("bogus.remove(1) revived bogus but must not");
   1502     }
   1503 
   1504     test3.setToBogus();
   1505     if(!test3.setCharAt(0, 0x62).isBogus() || !test3.isEmpty()) {
   1506         errln("bogus.setCharAt(0, 'b') worked but must not");
   1507     }
   1508 
   1509     test3.setToBogus();
   1510     if(test3.truncate(1) || !test3.isBogus() || !test3.isEmpty()) {
   1511         errln("bogus.truncate(1) revived bogus but must not");
   1512     }
   1513 
   1514     // verify that assignments revive a bogus string
   1515     test3.setToBogus();
   1516     if(!test3.isBogus() || (test3=test1).isBogus() || test3!=test1) {
   1517         errln("bogus.operator=() failed");
   1518     }
   1519 
   1520     test3.setToBogus();
   1521     if(!test3.isBogus() || test3.fastCopyFrom(test1).isBogus() || test3!=test1) {
   1522         errln("bogus.fastCopyFrom() failed");
   1523     }
   1524 
   1525     test3.setToBogus();
   1526     if(!test3.isBogus() || test3.setTo(test1).isBogus() || test3!=test1) {
   1527         errln("bogus.setTo(UniStr) failed");
   1528     }
   1529 
   1530     test3.setToBogus();
   1531     if(!test3.isBogus() || test3.setTo(test1, 0).isBogus() || test3!=test1) {
   1532         errln("bogus.setTo(UniStr, 0) failed");
   1533     }
   1534 
   1535     test3.setToBogus();
   1536     if(!test3.isBogus() || test3.setTo(test1, 0, 0x7fffffff).isBogus() || test3!=test1) {
   1537         errln("bogus.setTo(UniStr, 0, len) failed");
   1538     }
   1539 
   1540     test3.setToBogus();
   1541     if(!test3.isBogus() || test3.setTo(test1.getBuffer(), test1.length()).isBogus() || test3!=test1) {
   1542         errln("bogus.setTo(const UChar *, len) failed");
   1543     }
   1544 
   1545     test3.setToBogus();
   1546     if(!test3.isBogus() || test3.setTo((UChar)0x2028).isBogus() || test3!=UnicodeString((UChar)0x2028)) {
   1547         errln("bogus.setTo(UChar) failed");
   1548     }
   1549 
   1550     test3.setToBogus();
   1551     if(!test3.isBogus() || test3.setTo((UChar32)0x1d157).isBogus() || test3!=UnicodeString((UChar32)0x1d157)) {
   1552         errln("bogus.setTo(UChar32) failed");
   1553     }
   1554 
   1555     test3.setToBogus();
   1556     if(!test3.isBogus() || test3.setTo(FALSE, test1.getBuffer(), test1.length()).isBogus() || test3!=test1) {
   1557         errln("bogus.setTo(readonly alias) failed");
   1558     }
   1559 
   1560     // writable alias to another string's buffer: very bad idea, just convenient for this test
   1561     test3.setToBogus();
   1562     if(!test3.isBogus() || test3.setTo((UChar *)test1.getBuffer(), test1.length(), test1.getCapacity()).isBogus() || test3!=test1) {
   1563         errln("bogus.setTo(writable alias) failed");
   1564     }
   1565 
   1566     // verify simple, documented ways to turn a bogus string into an empty one
   1567     test3.setToBogus();
   1568     if(!test3.isBogus() || (test3=UnicodeString()).isBogus() || !test3.isEmpty()) {
   1569         errln("bogus.operator=(UnicodeString()) failed");
   1570     }
   1571 
   1572     test3.setToBogus();
   1573     if(!test3.isBogus() || test3.setTo(UnicodeString()).isBogus() || !test3.isEmpty()) {
   1574         errln("bogus.setTo(UnicodeString()) failed");
   1575     }
   1576 
   1577     test3.setToBogus();
   1578     if(test3.remove().isBogus() || test3.getBuffer()==0 || !test3.isEmpty()) {
   1579         errln("bogus.remove() failed");
   1580     }
   1581 
   1582     test3.setToBogus();
   1583     if(test3.remove(0, INT32_MAX).isBogus() || test3.getBuffer()==0 || !test3.isEmpty()) {
   1584         errln("bogus.remove(0, INT32_MAX) failed");
   1585     }
   1586 
   1587     test3.setToBogus();
   1588     if(test3.truncate(0) || test3.isBogus() || !test3.isEmpty()) {
   1589         errln("bogus.truncate(0) failed");
   1590     }
   1591 
   1592     test3.setToBogus();
   1593     if(!test3.isBogus() || test3.setTo((UChar32)-1).isBogus() || !test3.isEmpty()) {
   1594         errln("bogus.setTo((UChar32)-1) failed");
   1595     }
   1596 
   1597     static const UChar nul=0;
   1598 
   1599     test3.setToBogus();
   1600     if(!test3.isBogus() || test3.setTo(&nul, 0).isBogus() || !test3.isEmpty()) {
   1601         errln("bogus.setTo(&nul, 0) failed");
   1602     }
   1603 
   1604     test3.setToBogus();
   1605     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1606         errln("setToBogus() failed to make a string bogus");
   1607     }
   1608 
   1609     test3.setToBogus();
   1610     if(test1.isBogus() || !(test1=test3).isBogus()) {
   1611         errln("normal=bogus failed to make the left string bogus");
   1612     }
   1613 
   1614     // test that NULL primitive input string values are treated like
   1615     // empty strings, not errors (bogus)
   1616     test2.setTo((UChar32)0x10005);
   1617     if(test2.insert(1, NULL, 1).length()!=2) {
   1618         errln("UniStr.insert(...NULL...) should not modify the string but does");
   1619     }
   1620 
   1621     UErrorCode errorCode=U_ZERO_ERROR;
   1622     UnicodeString
   1623         test4((const UChar *)NULL),
   1624         test5(TRUE, (const UChar *)NULL, 1),
   1625         test6((UChar *)NULL, 5, 5),
   1626         test7((const char *)NULL, 3, NULL, errorCode);
   1627     if(test4.isBogus() || test5.isBogus() || test6.isBogus() || test7.isBogus()) {
   1628         errln("a constructor set to bogus for a NULL input string, should be empty");
   1629     }
   1630 
   1631     test4.setTo(NULL, 3);
   1632     test5.setTo(TRUE, (const UChar *)NULL, 1);
   1633     test6.setTo((UChar *)NULL, 5, 5);
   1634     if(test4.isBogus() || test5.isBogus() || test6.isBogus()) {
   1635         errln("a setTo() set to bogus for a NULL input string, should be empty");
   1636     }
   1637 
   1638     // test that bogus==bogus<any
   1639     if(test1!=test3 || test1.compare(test3)!=0) {
   1640         errln("bogus==bogus failed");
   1641     }
   1642 
   1643     test2.remove();
   1644     if(test1>=test2 || !(test2>test1) || test1.compare(test2)>=0 || !(test2.compare(test1)>0)) {
   1645         errln("bogus<empty failed");
   1646     }
   1647 }
   1648 
   1649 // StringEnumeration ------------------------------------------------------- ***
   1650 // most of StringEnumeration is tested elsewhere
   1651 // this test improves code coverage
   1652 
   1653 static const char *const
   1654 testEnumStrings[]={
   1655     "a",
   1656     "b",
   1657     "c",
   1658     "this is a long string which helps us test some buffer limits",
   1659     "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
   1660 };
   1661 
   1662 class TestEnumeration : public StringEnumeration {
   1663 public:
   1664     TestEnumeration() : i(0) {}
   1665 
   1666     virtual int32_t count(UErrorCode& /*status*/) const {
   1667         return LENGTHOF(testEnumStrings);
   1668     }
   1669 
   1670     virtual const UnicodeString *snext(UErrorCode &status) {
   1671         if(U_SUCCESS(status) && i<LENGTHOF(testEnumStrings)) {
   1672             unistr=UnicodeString(testEnumStrings[i++], "");
   1673             return &unistr;
   1674         }
   1675 
   1676         return NULL;
   1677     }
   1678 
   1679     virtual void reset(UErrorCode& /*status*/) {
   1680         i=0;
   1681     }
   1682 
   1683     static inline UClassID getStaticClassID() {
   1684         return (UClassID)&fgClassID;
   1685     }
   1686     virtual UClassID getDynamicClassID() const {
   1687         return getStaticClassID();
   1688     }
   1689 
   1690 private:
   1691     static const char fgClassID;
   1692 
   1693     int32_t i;
   1694 };
   1695 
   1696 const char TestEnumeration::fgClassID=0;
   1697 
   1698 void
   1699 UnicodeStringTest::TestStringEnumeration() {
   1700     UnicodeString s;
   1701     TestEnumeration ten;
   1702     int32_t i, length;
   1703     UErrorCode status;
   1704 
   1705     const UChar *pu;
   1706     const char *pc;
   1707 
   1708     // test the next() default implementation and ensureCharsCapacity()
   1709     for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
   1710         status=U_ZERO_ERROR;
   1711         pc=ten.next(&length, status);
   1712         s=UnicodeString(testEnumStrings[i], "");
   1713         if(U_FAILURE(status) || pc==NULL || length!=s.length() || UnicodeString(pc, length, "")!=s) {
   1714             errln("StringEnumeration.next(%d) failed", i);
   1715         }
   1716     }
   1717     status=U_ZERO_ERROR;
   1718     if(ten.next(&length, status)!=NULL) {
   1719         errln("StringEnumeration.next(done)!=NULL");
   1720     }
   1721 
   1722     // test the unext() default implementation
   1723     ten.reset(status);
   1724     for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
   1725         status=U_ZERO_ERROR;
   1726         pu=ten.unext(&length, status);
   1727         s=UnicodeString(testEnumStrings[i], "");
   1728         if(U_FAILURE(status) || pu==NULL || length!=s.length() || UnicodeString(TRUE, pu, length)!=s) {
   1729             errln("StringEnumeration.unext(%d) failed", i);
   1730         }
   1731     }
   1732     status=U_ZERO_ERROR;
   1733     if(ten.unext(&length, status)!=NULL) {
   1734         errln("StringEnumeration.unext(done)!=NULL");
   1735     }
   1736 
   1737     // test that the default clone() implementation works, and returns NULL
   1738     if(ten.clone()!=NULL) {
   1739         errln("StringEnumeration.clone()!=NULL");
   1740     }
   1741 
   1742     // test that uenum_openFromStringEnumeration() works
   1743     // Need a heap allocated string enumeration because it is adopted by the UEnumeration.
   1744     StringEnumeration *newTen = new TestEnumeration;
   1745     status=U_ZERO_ERROR;
   1746     UEnumeration *uten = uenum_openFromStringEnumeration(newTen, &status);
   1747     if (uten==NULL || U_FAILURE(status)) {
   1748         errln("fail at file %s, line %d, UErrorCode is %s\n", __FILE__, __LINE__, u_errorName(status));
   1749         return;
   1750     }
   1751 
   1752     // test  uenum_next()
   1753     for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
   1754         status=U_ZERO_ERROR;
   1755         pc=uenum_next(uten, &length, &status);
   1756         if(U_FAILURE(status) || pc==NULL || strcmp(pc, testEnumStrings[i]) != 0) {
   1757             errln("File %s, line %d, StringEnumeration.next(%d) failed", __FILE__, __LINE__, i);
   1758         }
   1759     }
   1760     status=U_ZERO_ERROR;
   1761     if(uenum_next(uten, &length, &status)!=NULL) {
   1762         errln("File %s, line %d, uenum_next(done)!=NULL");
   1763     }
   1764 
   1765     // test the uenum_unext()
   1766     uenum_reset(uten, &status);
   1767     for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
   1768         status=U_ZERO_ERROR;
   1769         pu=uenum_unext(uten, &length, &status);
   1770         s=UnicodeString(testEnumStrings[i], "");
   1771         if(U_FAILURE(status) || pu==NULL || length!=s.length() || UnicodeString(TRUE, pu, length)!=s) {
   1772             errln("File %s, Line %d, uenum_unext(%d) failed", __FILE__, __LINE__, i);
   1773         }
   1774     }
   1775     status=U_ZERO_ERROR;
   1776     if(uenum_unext(uten, &length, &status)!=NULL) {
   1777         errln("File %s, Line %d, uenum_unext(done)!=NULL" __FILE__, __LINE__);
   1778     }
   1779 
   1780     uenum_close(uten);
   1781 }
   1782 
   1783 /*
   1784  * Namespace test, to make sure that macros like UNICODE_STRING include the
   1785  * namespace qualifier.
   1786  *
   1787  * Define a (bogus) UnicodeString class in another namespace and check for ambiguity.
   1788  */
   1789 namespace bogus {
   1790     class UnicodeString {
   1791     public:
   1792         enum EInvariant { kInvariant };
   1793         UnicodeString() : i(1) {}
   1794         UnicodeString(UBool /*isTerminated*/, const UChar * /*text*/, int32_t textLength) : i(textLength) {(void)i;}
   1795         UnicodeString(const char * /*src*/, int32_t length, enum EInvariant /*inv*/
   1796 ) : i(length) {}
   1797     private:
   1798         int32_t i;
   1799     };
   1800 }
   1801 
   1802 void
   1803 UnicodeStringTest::TestNameSpace() {
   1804     // Provoke name collision unless the UnicodeString macros properly
   1805     // qualify the icu::UnicodeString class.
   1806     using namespace bogus;
   1807 
   1808     // Use all UnicodeString macros from unistr.h.
   1809     icu::UnicodeString s1=icu::UnicodeString("abc", 3, US_INV);
   1810     icu::UnicodeString s2=UNICODE_STRING("def", 3);
   1811     icu::UnicodeString s3=UNICODE_STRING_SIMPLE("ghi");
   1812 
   1813     // Make sure the compiler does not optimize away instantiation of s1, s2, s3.
   1814     icu::UnicodeString s4=s1+s2+s3;
   1815     if(s4.length()!=9) {
   1816         errln("Something wrong with UnicodeString::operator+().");
   1817     }
   1818 }
   1819 
   1820 void
   1821 UnicodeStringTest::TestUTF32() {
   1822     // Input string length US_STACKBUF_SIZE to cause overflow of the
   1823     // initially chosen fStackBuffer due to supplementary characters.
   1824     static const UChar32 utf32[] = {
   1825         0x41, 0xd900, 0x61, 0xdc00, -1, 0x110000, 0x5a, 0x50000, 0x7a,
   1826         0x10000, 0x20000, 0xe0000, 0x10ffff
   1827     };
   1828     static const UChar expected_utf16[] = {
   1829         0x41, 0xfffd, 0x61, 0xfffd, 0xfffd, 0xfffd, 0x5a, 0xd900, 0xdc00, 0x7a,
   1830         0xd800, 0xdc00, 0xd840, 0xdc00, 0xdb40, 0xdc00, 0xdbff, 0xdfff
   1831     };
   1832     UnicodeString from32 = UnicodeString::fromUTF32(utf32, LENGTHOF(utf32));
   1833     UnicodeString expected(FALSE, expected_utf16, LENGTHOF(expected_utf16));
   1834     if(from32 != expected) {
   1835         errln("UnicodeString::fromUTF32() did not create the expected string.");
   1836     }
   1837 
   1838     static const UChar utf16[] = {
   1839         0x41, 0xd900, 0x61, 0xdc00, 0x5a, 0xd900, 0xdc00, 0x7a, 0xd800, 0xdc00, 0xdbff, 0xdfff
   1840     };
   1841     static const UChar32 expected_utf32[] = {
   1842         0x41, 0xfffd, 0x61, 0xfffd, 0x5a, 0x50000, 0x7a, 0x10000, 0x10ffff
   1843     };
   1844     UChar32 result32[16];
   1845     UErrorCode errorCode = U_ZERO_ERROR;
   1846     int32_t length32 =
   1847         UnicodeString(FALSE, utf16, LENGTHOF(utf16)).
   1848         toUTF32(result32, LENGTHOF(result32), errorCode);
   1849     if( length32 != LENGTHOF(expected_utf32) ||
   1850         0 != uprv_memcmp(result32, expected_utf32, length32*4) ||
   1851         result32[length32] != 0
   1852     ) {
   1853         errln("UnicodeString::toUTF32() did not create the expected string.");
   1854     }
   1855 }
   1856 
   1857 class TestCheckedArrayByteSink : public CheckedArrayByteSink {
   1858 public:
   1859     TestCheckedArrayByteSink(char* outbuf, int32_t capacity)
   1860             : CheckedArrayByteSink(outbuf, capacity), calledFlush(FALSE) {}
   1861     virtual void Flush() { calledFlush = TRUE; }
   1862     UBool calledFlush;
   1863 };
   1864 
   1865 void
   1866 UnicodeStringTest::TestUTF8() {
   1867     static const uint8_t utf8[] = {
   1868         // Code points:
   1869         // 0x41, 0xd900,
   1870         // 0x61, 0xdc00,
   1871         // 0x110000, 0x5a,
   1872         // 0x50000, 0x7a,
   1873         // 0x10000, 0x20000,
   1874         // 0xe0000, 0x10ffff
   1875         0x41, 0xed, 0xa4, 0x80,
   1876         0x61, 0xed, 0xb0, 0x80,
   1877         0xf4, 0x90, 0x80, 0x80, 0x5a,
   1878         0xf1, 0x90, 0x80, 0x80, 0x7a,
   1879         0xf0, 0x90, 0x80, 0x80, 0xf0, 0xa0, 0x80, 0x80,
   1880         0xf3, 0xa0, 0x80, 0x80, 0xf4, 0x8f, 0xbf, 0xbf
   1881     };
   1882     static const UChar expected_utf16[] = {
   1883         0x41, 0xfffd,
   1884         0x61, 0xfffd,
   1885         0xfffd, 0x5a,
   1886         0xd900, 0xdc00, 0x7a,
   1887         0xd800, 0xdc00, 0xd840, 0xdc00,
   1888         0xdb40, 0xdc00, 0xdbff, 0xdfff
   1889     };
   1890     UnicodeString from8 = UnicodeString::fromUTF8(StringPiece((const char *)utf8, (int32_t)sizeof(utf8)));
   1891     UnicodeString expected(FALSE, expected_utf16, LENGTHOF(expected_utf16));
   1892 
   1893     if(from8 != expected) {
   1894         errln("UnicodeString::fromUTF8(StringPiece) did not create the expected string.");
   1895     }
   1896 #if U_HAVE_STD_STRING
   1897     std::string utf8_string((const char *)utf8, sizeof(utf8));
   1898     UnicodeString from8b = UnicodeString::fromUTF8(utf8_string);
   1899     if(from8b != expected) {
   1900         errln("UnicodeString::fromUTF8(std::string) did not create the expected string.");
   1901     }
   1902 #endif
   1903 
   1904     static const UChar utf16[] = {
   1905         0x41, 0xd900, 0x61, 0xdc00, 0x5a, 0xd900, 0xdc00, 0x7a, 0xd800, 0xdc00, 0xdbff, 0xdfff
   1906     };
   1907     static const uint8_t expected_utf8[] = {
   1908         0x41, 0xef, 0xbf, 0xbd, 0x61, 0xef, 0xbf, 0xbd, 0x5a, 0xf1, 0x90, 0x80, 0x80, 0x7a,
   1909         0xf0, 0x90, 0x80, 0x80, 0xf4, 0x8f, 0xbf, 0xbf
   1910     };
   1911     UnicodeString us(FALSE, utf16, LENGTHOF(utf16));
   1912 
   1913     char buffer[64];
   1914     TestCheckedArrayByteSink sink(buffer, (int32_t)sizeof(buffer));
   1915     us.toUTF8(sink);
   1916     if( sink.NumberOfBytesWritten() != (int32_t)sizeof(expected_utf8) ||
   1917         0 != uprv_memcmp(buffer, expected_utf8, sizeof(expected_utf8))
   1918     ) {
   1919         errln("UnicodeString::toUTF8() did not create the expected string.");
   1920     }
   1921     if(!sink.calledFlush) {
   1922         errln("UnicodeString::toUTF8(sink) did not sink.Flush().");
   1923     }
   1924 #if U_HAVE_STD_STRING
   1925     // Initial contents for testing that toUTF8String() appends.
   1926     std::string result8 = "-->";
   1927     std::string expected8 = "-->" + std::string((const char *)expected_utf8, sizeof(expected_utf8));
   1928     // Use the return value just for testing.
   1929     std::string &result8r = us.toUTF8String(result8);
   1930     if(result8r != expected8 || &result8r != &result8) {
   1931         errln("UnicodeString::toUTF8String() did not create the expected string.");
   1932     }
   1933 #endif
   1934 }
   1935 
   1936 // Test if this compiler supports Return Value Optimization of unnamed temporary objects.
   1937 static UnicodeString wrapUChars(const UChar *uchars) {
   1938     return UnicodeString(TRUE, uchars, -1);
   1939 }
   1940 
   1941 void
   1942 UnicodeStringTest::TestReadOnlyAlias() {
   1943     UChar uchars[]={ 0x61, 0x62, 0 };
   1944     UnicodeString alias(TRUE, uchars, 2);
   1945     if(alias.length()!=2 || alias.getBuffer()!=uchars || alias.getTerminatedBuffer()!=uchars) {
   1946         errln("UnicodeString read-only-aliasing constructor does not behave as expected.");
   1947         return;
   1948     }
   1949     alias.truncate(1);
   1950     if(alias.length()!=1 || alias.getBuffer()!=uchars) {
   1951         errln("UnicodeString(read-only-alias).truncate() did not preserve aliasing as expected.");
   1952     }
   1953     if(alias.getTerminatedBuffer()==uchars) {
   1954         errln("UnicodeString(read-only-alias).truncate().getTerminatedBuffer() "
   1955               "did not allocate and copy as expected.");
   1956     }
   1957     if(uchars[1]!=0x62) {
   1958         errln("UnicodeString(read-only-alias).truncate().getTerminatedBuffer() "
   1959               "modified the original buffer.");
   1960     }
   1961     if(1!=u_strlen(alias.getTerminatedBuffer())) {
   1962         errln("UnicodeString(read-only-alias).truncate().getTerminatedBuffer() "
   1963               "does not return a buffer terminated at the proper length.");
   1964     }
   1965 
   1966     alias.setTo(TRUE, uchars, 2);
   1967     if(alias.length()!=2 || alias.getBuffer()!=uchars || alias.getTerminatedBuffer()!=uchars) {
   1968         errln("UnicodeString read-only-aliasing setTo() does not behave as expected.");
   1969         return;
   1970     }
   1971     alias.remove();
   1972     if(alias.length()!=0) {
   1973         errln("UnicodeString(read-only-alias).remove() did not work.");
   1974     }
   1975     if(alias.getTerminatedBuffer()==uchars) {
   1976         errln("UnicodeString(read-only-alias).remove().getTerminatedBuffer() "
   1977               "did not un-alias as expected.");
   1978     }
   1979     if(uchars[0]!=0x61) {
   1980         errln("UnicodeString(read-only-alias).remove().getTerminatedBuffer() "
   1981               "modified the original buffer.");
   1982     }
   1983     if(0!=u_strlen(alias.getTerminatedBuffer())) {
   1984         errln("UnicodeString.setTo(read-only-alias).remove().getTerminatedBuffer() "
   1985               "does not return a buffer terminated at length 0.");
   1986     }
   1987 
   1988     UnicodeString longString=UNICODE_STRING_SIMPLE("abcdefghijklmnopqrstuvwxyz0123456789");
   1989     alias.setTo(FALSE, longString.getBuffer(), longString.length());
   1990     alias.remove(0, 10);
   1991     if(longString.compare(10, INT32_MAX, alias)!=0 || alias.getBuffer()!=longString.getBuffer()+10) {
   1992         errln("UnicodeString.setTo(read-only-alias).remove(0, 10) did not preserve aliasing as expected.");
   1993     }
   1994     alias.setTo(FALSE, longString.getBuffer(), longString.length());
   1995     alias.remove(27, 99);
   1996     if(longString.compare(0, 27, alias)!=0 || alias.getBuffer()!=longString.getBuffer()) {
   1997         errln("UnicodeString.setTo(read-only-alias).remove(27, 99) did not preserve aliasing as expected.");
   1998     }
   1999     alias.setTo(FALSE, longString.getBuffer(), longString.length());
   2000     alias.retainBetween(6, 30);
   2001     if(longString.compare(6, 24, alias)!=0 || alias.getBuffer()!=longString.getBuffer()+6) {
   2002         errln("UnicodeString.setTo(read-only-alias).retainBetween(6, 30) did not preserve aliasing as expected.");
   2003     }
   2004 
   2005     UChar abc[]={ 0x61, 0x62, 0x63, 0 };
   2006     UBool hasRVO= wrapUChars(abc).getBuffer()==abc;
   2007 
   2008     UnicodeString temp;
   2009     temp.fastCopyFrom(longString.tempSubString());
   2010     if(temp!=longString || (hasRVO && temp.getBuffer()!=longString.getBuffer())) {
   2011         errln("UnicodeString.tempSubString() failed");
   2012     }
   2013     temp.fastCopyFrom(longString.tempSubString(-3, 5));
   2014     if(longString.compare(0, 5, temp)!=0 || (hasRVO && temp.getBuffer()!=longString.getBuffer())) {
   2015         errln("UnicodeString.tempSubString(-3, 5) failed");
   2016     }
   2017     temp.fastCopyFrom(longString.tempSubString(17));
   2018     if(longString.compare(17, INT32_MAX, temp)!=0 || (hasRVO && temp.getBuffer()!=longString.getBuffer()+17)) {
   2019         errln("UnicodeString.tempSubString(17) failed");
   2020     }
   2021     temp.fastCopyFrom(longString.tempSubString(99));
   2022     if(!temp.isEmpty()) {
   2023         errln("UnicodeString.tempSubString(99) failed");
   2024     }
   2025     temp.fastCopyFrom(longString.tempSubStringBetween(6));
   2026     if(longString.compare(6, INT32_MAX, temp)!=0 || (hasRVO && temp.getBuffer()!=longString.getBuffer()+6)) {
   2027         errln("UnicodeString.tempSubStringBetween(6) failed");
   2028     }
   2029     temp.fastCopyFrom(longString.tempSubStringBetween(8, 18));
   2030     if(longString.compare(8, 10, temp)!=0 || (hasRVO && temp.getBuffer()!=longString.getBuffer()+8)) {
   2031         errln("UnicodeString.tempSubStringBetween(8, 18) failed");
   2032     }
   2033     UnicodeString bogusString;
   2034     bogusString.setToBogus();
   2035     temp.fastCopyFrom(bogusString.tempSubStringBetween(8, 18));
   2036     if(!temp.isBogus()) {
   2037         errln("UnicodeString.setToBogus().tempSubStringBetween(8, 18) failed");
   2038     }
   2039 }
   2040 
   2041 void
   2042 UnicodeStringTest::doTestAppendable(UnicodeString &dest, Appendable &app) {
   2043     static const UChar cde[3]={ 0x63, 0x64, 0x65 };
   2044     static const UChar fg[3]={ 0x66, 0x67, 0 };
   2045     if(!app.reserveAppendCapacity(12)) {
   2046         errln("Appendable.reserve(12) failed");
   2047     }
   2048     app.appendCodeUnit(0x61);
   2049     app.appendCodePoint(0x62);
   2050     app.appendCodePoint(0x50000);
   2051     app.appendString(cde, 3);
   2052     app.appendString(fg, -1);
   2053     UChar scratch[3];
   2054     int32_t capacity=-1;
   2055     UChar *buffer=app.getAppendBuffer(3, 3, scratch, 3, &capacity);
   2056     if(capacity<3) {
   2057         errln("Appendable.getAppendBuffer(min=3) returned capacity=%d<3", (int)capacity);
   2058         return;
   2059     }
   2060     static const UChar hij[3]={ 0x68, 0x69, 0x6a };
   2061     u_memcpy(buffer, hij, 3);
   2062     app.appendString(buffer, 3);
   2063     if(dest!=UNICODE_STRING_SIMPLE("ab\\U00050000cdefghij").unescape()) {
   2064         errln("Appendable.append(...) failed");
   2065     }
   2066     buffer=app.getAppendBuffer(0, 3, scratch, 3, &capacity);
   2067     if(buffer!=NULL || capacity!=0) {
   2068         errln("Appendable.getAppendBuffer(min=0) failed");
   2069     }
   2070     capacity=1;
   2071     buffer=app.getAppendBuffer(3, 3, scratch, 2, &capacity);
   2072     if(buffer!=NULL || capacity!=0) {
   2073         errln("Appendable.getAppendBuffer(scratch<min) failed");
   2074     }
   2075 }
   2076 
   2077 class SimpleAppendable : public Appendable {
   2078 public:
   2079     explicit SimpleAppendable(UnicodeString &dest) : str(dest) {}
   2080     virtual UBool appendCodeUnit(UChar c) { str.append(c); return TRUE; }
   2081     SimpleAppendable &reset() { str.remove(); return *this; }
   2082 private:
   2083     UnicodeString &str;
   2084 };
   2085 
   2086 void
   2087 UnicodeStringTest::TestAppendable() {
   2088     UnicodeString dest;
   2089     SimpleAppendable app(dest);
   2090     doTestAppendable(dest, app);
   2091 }
   2092 
   2093 void
   2094 UnicodeStringTest::TestUnicodeStringImplementsAppendable() {
   2095     UnicodeString dest;
   2096     UnicodeStringAppendable app(dest);
   2097     doTestAppendable(dest, app);
   2098 }
   2099 
   2100 void
   2101 UnicodeStringTest::TestSizeofUnicodeString() {
   2102     // See the comments in unistr.h near the declaration of UnicodeString's fields.
   2103     size_t sizeofUniStr=sizeof(UnicodeString);
   2104     size_t expected;
   2105     switch(sizeof(void *)) {
   2106     case 4:
   2107         expected=32;
   2108         break;
   2109     case 8:
   2110         expected=40;
   2111         break;
   2112     default:
   2113         logln("This platform has neither 32-bit nor 64-bit pointers.");
   2114         return;
   2115     }
   2116     if(expected!=sizeofUniStr) {
   2117         errln("sizeof(UnicodeString)=%d, expected %d", (int)sizeofUniStr, (int)expected);
   2118     }
   2119 }
   2120