Home | History | Annotate | Download | only in intltest
      1 /********************************************************************
      2  * COPYRIGHT:
      3  * Copyright (c) 1997-2011, 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("length() failed: expected 70, got " + test1.length());
    117     if (test2.length() != 30)
    118         errln("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("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("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("indexOf with starting offset failed: expected to find 4 occurrences, found " + occurrences);
    732 
    733     int32_t endPos = 28;
    734     for ( occurrences = 0, startPos = 5;
    735           startPos != -1 && startPos < test1.length();
    736           (startPos = test1.indexOf(test2, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 4) : 0)
    737         ;
    738     if (occurrences != 4)
    739         errln("indexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences);
    740 
    741     //using UChar32 string
    742     for ( startPos=0, occurrences=0;
    743           startPos != -1 && startPos < test3.length();
    744           (startPos = test3.indexOf(test4, startPos)) != -1 ? (++occurrences, startPos += 2) : 0)
    745         ;
    746     if (occurrences != 4)
    747         errln((UnicodeString)"indexOf failed: expected to find 4 occurrences, found " + occurrences);
    748 
    749     for ( startPos=10, occurrences=0;
    750           startPos != -1 && startPos < test3.length();
    751           (startPos = test3.indexOf(test4, startPos)) != -1 ? (++occurrences, startPos += 2) : 0)
    752         ;
    753     if (occurrences != 2)
    754         errln("indexOf failed: expected to find 2 occurrences, found " + occurrences);
    755     //---
    756 
    757     for ( occurrences = 0, startPos = 0;
    758           startPos != -1 && startPos < test1.length();
    759           (startPos = test1.indexOf(testChar, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    760         ;
    761     if (occurrences != 16)
    762         errln("indexOf with character failed: expected to find 16 occurrences, found " + occurrences);
    763 
    764     for ( occurrences = 0, startPos = 10;
    765           startPos != -1 && startPos < test1.length();
    766           (startPos = test1.indexOf(testChar, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    767         ;
    768     if (occurrences != 12)
    769         errln("indexOf with character & start offset failed: expected to find 12 occurrences, found " + occurrences);
    770 
    771     for ( occurrences = 0, startPos = 5, endPos = 28;
    772           startPos != -1 && startPos < test1.length();
    773           (startPos = test1.indexOf(testChar, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    774         ;
    775     if (occurrences != 10)
    776         errln("indexOf with character & start & end offsets failed: expected to find 10 occurrences, found " + occurrences);
    777 
    778     //testing for UChar32
    779     UnicodeString subString;
    780     for( occurrences =0, startPos=0; startPos < test3.length(); startPos +=1){
    781         subString.append(test3, startPos, test3.length());
    782         if(subString.indexOf(testChar32) != -1 ){
    783              ++occurrences;
    784         }
    785         subString.remove();
    786     }
    787     if (occurrences != 14)
    788         errln((UnicodeString)"indexOf failed: expected to find 14 occurrences, found " + occurrences);
    789 
    790     for ( occurrences = 0, startPos = 0;
    791           startPos != -1 && startPos < test3.length();
    792           (startPos = test3.indexOf(testChar32, startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    793         ;
    794     if (occurrences != 4)
    795         errln((UnicodeString)"indexOf failed: expected to find 4 occurrences, found " + occurrences);
    796 
    797     endPos=test3.length();
    798     for ( occurrences = 0, startPos = 5;
    799           startPos != -1 && startPos < test3.length();
    800           (startPos = test3.indexOf(testChar32, startPos, endPos - startPos)) != -1 ? (++occurrences, startPos += 1) : 0)
    801         ;
    802     if (occurrences != 3)
    803         errln((UnicodeString)"indexOf with character & start & end offsets failed: expected to find 2 occurrences, found " + occurrences);
    804     //---
    805 
    806     if(test1.lastIndexOf(test2)!=29) {
    807         errln("test1.lastIndexOf(test2)!=29");
    808     }
    809 
    810     if(test1.lastIndexOf(test2, 15)!=29 || test1.lastIndexOf(test2, 29)!=29 || test1.lastIndexOf(test2, 30)!=-1) {
    811         errln("test1.lastIndexOf(test2, start) failed");
    812     }
    813 
    814     for ( occurrences = 0, startPos = 32;
    815           startPos != -1;
    816           (startPos = test1.lastIndexOf(test2, 5, startPos - 5)) != -1 ? ++occurrences : 0)
    817         ;
    818     if (occurrences != 4)
    819         errln("lastIndexOf with starting and ending offsets failed: expected to find 4 occurrences, found " + occurrences);
    820 
    821     for ( occurrences = 0, startPos = 32;
    822           startPos != -1;
    823           (startPos = test1.lastIndexOf(testChar, 5, startPos - 5)) != -1 ? ++occurrences : 0)
    824         ;
    825     if (occurrences != 11)
    826         errln("lastIndexOf with character & start & end offsets failed: expected to find 11 occurrences, found " + occurrences);
    827 
    828     //testing UChar32
    829     startPos=test3.length();
    830     for ( occurrences = 0;
    831           startPos != -1;
    832           (startPos = test3.lastIndexOf(testChar32, 5, startPos - 5)) != -1 ? ++occurrences : 0)
    833         ;
    834     if (occurrences != 3)
    835         errln((UnicodeString)"lastIndexOf with character & start & end offsets failed: expected to find 3 occurrences, found " + occurrences);
    836 
    837 
    838     for ( occurrences = 0, endPos = test3.length();  endPos > 0; endPos -= 1){
    839         subString.remove();
    840         subString.append(test3, 0, endPos);
    841         if(subString.lastIndexOf(testChar32) != -1 ){
    842             ++occurrences;
    843         }
    844     }
    845     if (occurrences != 18)
    846         errln((UnicodeString)"indexOf failed: expected to find 18 occurrences, found " + occurrences);
    847     //---
    848 
    849     // test that indexOf(UChar32) and lastIndexOf(UChar32)
    850     // do not find surrogate code points when they are part of matched pairs
    851     // (= part of supplementary code points)
    852     // Jitterbug 1542
    853     if(test3.indexOf((UChar32)0xd841) != 4 || test3.indexOf((UChar32)0xdc02) != 3) {
    854         errln("error: UnicodeString::indexOf(UChar32 surrogate) finds a partial supplementary code point");
    855     }
    856     if( UnicodeString(test3, 0, 17).lastIndexOf((UChar)0xd841, 0) != 4 ||
    857         UnicodeString(test3, 0, 17).lastIndexOf((UChar32)0xd841, 2) != 4 ||
    858         test3.lastIndexOf((UChar32)0xd841, 0, 17) != 4 || test3.lastIndexOf((UChar32)0xdc02, 0, 17) != 16
    859     ) {
    860         errln("error: UnicodeString::lastIndexOf(UChar32 surrogate) finds a partial supplementary code point");
    861     }
    862 }
    863 
    864 void
    865 UnicodeStringTest::TestSpacePadding()
    866 {
    867     UnicodeString test1("hello");
    868     UnicodeString test2("   there");
    869     UnicodeString test3("Hi!  How ya doin'?  Beautiful day, isn't it?");
    870     UnicodeString test4;
    871     UBool returnVal;
    872     UnicodeString expectedValue;
    873 
    874     returnVal = test1.padLeading(15);
    875     expectedValue = "          hello";
    876     if (returnVal == FALSE || test1 != expectedValue)
    877         errln("padLeading() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
    878 
    879     returnVal = test2.padTrailing(15);
    880     expectedValue = "   there       ";
    881     if (returnVal == FALSE || test2 != expectedValue)
    882         errln("padTrailing() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
    883 
    884     expectedValue = test3;
    885     returnVal = test3.padTrailing(15);
    886     if (returnVal == TRUE || test3 != expectedValue)
    887         errln("padTrailing() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
    888 
    889     expectedValue = "hello";
    890     test4.setTo(test1).trim();
    891 
    892     if (test4 != expectedValue || test1 == expectedValue || test4 != expectedValue)
    893         errln("trim(UnicodeString&) failed");
    894 
    895     test1.trim();
    896     if (test1 != expectedValue)
    897         errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
    898 
    899     test2.trim();
    900     expectedValue = "there";
    901     if (test2 != expectedValue)
    902         errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
    903 
    904     test3.trim();
    905     expectedValue = "Hi!  How ya doin'?  Beautiful day, isn't it?";
    906     if (test3 != expectedValue)
    907         errln("trim() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
    908 
    909     returnVal = test1.truncate(15);
    910     expectedValue = "hello";
    911     if (returnVal == TRUE || test1 != expectedValue)
    912         errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
    913 
    914     returnVal = test2.truncate(15);
    915     expectedValue = "there";
    916     if (returnVal == TRUE || test2 != expectedValue)
    917         errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test2 + "\".");
    918 
    919     returnVal = test3.truncate(15);
    920     expectedValue = "Hi!  How ya doi";
    921     if (returnVal == FALSE || test3 != expectedValue)
    922         errln("truncate() failed: expected \"" + expectedValue + "\", got \"" + test3 + "\".");
    923 }
    924 
    925 void
    926 UnicodeStringTest::TestPrefixAndSuffix()
    927 {
    928     UnicodeString test1("Now is the time for all good men to come to the aid of their country.");
    929     UnicodeString test2("Now");
    930     UnicodeString test3("country.");
    931     UnicodeString test4("count");
    932 
    933     if (!test1.startsWith(test2) || !test1.startsWith(test2, 0, test2.length())) {
    934         errln("startsWith() failed: \"" + test2 + "\" should be a prefix of \"" + test1 + "\".");
    935     }
    936 
    937     if (test1.startsWith(test3) ||
    938         test1.startsWith(test3.getBuffer(), test3.length()) ||
    939         test1.startsWith(test3.getTerminatedBuffer(), 0, -1)
    940     ) {
    941         errln("startsWith() failed: \"" + test3 + "\" shouldn't be a prefix of \"" + test1 + "\".");
    942     }
    943 
    944     if (test1.endsWith(test2)) {
    945         errln("endsWith() failed: \"" + test2 + "\" shouldn't be a suffix of \"" + test1 + "\".");
    946     }
    947 
    948     if (!test1.endsWith(test3)) {
    949         errln("endsWith(test3) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
    950     }
    951     if (!test1.endsWith(test3, 0, INT32_MAX)) {
    952         errln("endsWith(test3, 0, INT32_MAX) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
    953     }
    954 
    955     if(!test1.endsWith(test3.getBuffer(), test3.length())) {
    956         errln("endsWith(test3.getBuffer(), test3.length()) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
    957     }
    958     if(!test1.endsWith(test3.getTerminatedBuffer(), 0, -1)) {
    959         errln("endsWith(test3.getTerminatedBuffer(), 0, -1) failed: \"" + test3 + "\" should be a suffix of \"" + test1 + "\".");
    960     }
    961 
    962     if (!test3.startsWith(test4)) {
    963         errln("endsWith(test4) failed: \"" + test4 + "\" should be a prefix of \"" + test3 + "\".");
    964     }
    965 
    966     if (test4.startsWith(test3)) {
    967         errln("startsWith(test3) failed: \"" + test3 + "\" shouldn't be a prefix of \"" + test4 + "\".");
    968     }
    969 }
    970 
    971 void
    972 UnicodeStringTest::TestStartsWithAndEndsWithNulTerminated() {
    973     UnicodeString test("abcde");
    974     const UChar ab[] = { 0x61, 0x62, 0 };
    975     const UChar de[] = { 0x64, 0x65, 0 };
    976     assertTrue("abcde.startsWith(ab, -1)", test.startsWith(ab, -1));
    977     assertTrue("abcde.startsWith(ab, 0, -1)", test.startsWith(ab, 0, -1));
    978     assertTrue("abcde.endsWith(de, -1)", test.endsWith(de, -1));
    979     assertTrue("abcde.endsWith(de, 0, -1)", test.endsWith(de, 0, -1));
    980 }
    981 
    982 void
    983 UnicodeStringTest::TestFindAndReplace()
    984 {
    985     UnicodeString test1("One potato, two potato, three potato, four\n");
    986     UnicodeString test2("potato");
    987     UnicodeString test3("MISSISSIPPI");
    988 
    989     UnicodeString expectedValue;
    990 
    991     test1.findAndReplace(test2, test3);
    992     expectedValue = "One MISSISSIPPI, two MISSISSIPPI, three MISSISSIPPI, four\n";
    993     if (test1 != expectedValue)
    994         errln("findAndReplace failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
    995     test1.findAndReplace(2, 32, test3, test2);
    996     expectedValue = "One potato, two potato, three MISSISSIPPI, four\n";
    997     if (test1 != expectedValue)
    998         errln("findAndReplace failed: expected \"" + expectedValue + "\", got \"" + test1 + "\".");
    999 }
   1000 
   1001 void
   1002 UnicodeStringTest::TestReverse()
   1003 {
   1004     UnicodeString test("backwards words say to used I");
   1005 
   1006     test.reverse();
   1007     test.reverse(2, 4);
   1008     test.reverse(7, 2);
   1009     test.reverse(10, 3);
   1010     test.reverse(14, 5);
   1011     test.reverse(20, 9);
   1012 
   1013     if (test != "I used to say words backwards")
   1014         errln("reverse() failed:  Expected \"I used to say words backwards\",\n got \""
   1015             + test + "\"");
   1016 
   1017     test=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
   1018     test.reverse();
   1019     if(test.char32At(0)!=0x1ed0 || test.char32At(1)!=0xc4 || test.char32At(2)!=0x1d15f || test.char32At(4)!=0x2f999) {
   1020         errln("reverse() failed with supplementary characters");
   1021     }
   1022 
   1023     // Test case for ticket #8091:
   1024     // UnicodeString::reverse() failed to see a lead surrogate in the middle of
   1025     // an odd-length string that contains no other lead surrogates.
   1026     test=UNICODE_STRING_SIMPLE("ab\\U0001F4A9e").unescape();
   1027     UnicodeString expected=UNICODE_STRING_SIMPLE("e\\U0001F4A9ba").unescape();
   1028     test.reverse();
   1029     if(test!=expected) {
   1030         errln("reverse() failed with only lead surrogate in the middle");
   1031     }
   1032 }
   1033 
   1034 void
   1035 UnicodeStringTest::TestMiscellaneous()
   1036 {
   1037     UnicodeString   test1("This is a test");
   1038     UnicodeString   test2("This is a test");
   1039     UnicodeString   test3("Me too!");
   1040 
   1041     // test getBuffer(minCapacity) and releaseBuffer()
   1042     test1=UnicodeString(); // make sure that it starts with its stackBuffer
   1043     UChar *p=test1.getBuffer(20);
   1044     if(test1.getCapacity()<20) {
   1045         errln("UnicodeString::getBuffer(20).getCapacity()<20");
   1046     }
   1047 
   1048     test1.append((UChar)7); // must not be able to modify the string here
   1049     test1.setCharAt(3, 7);
   1050     test1.reverse();
   1051     if( test1.length()!=0 ||
   1052         test1.charAt(0)!=0xffff || test1.charAt(3)!=0xffff ||
   1053         test1.getBuffer(10)!=0 || test1.getBuffer()!=0
   1054     ) {
   1055         errln("UnicodeString::getBuffer(minCapacity) allows read or write access to the UnicodeString");
   1056     }
   1057 
   1058     p[0]=1;
   1059     p[1]=2;
   1060     p[2]=3;
   1061     test1.releaseBuffer(3);
   1062     test1.append((UChar)4);
   1063 
   1064     if(test1.length()!=4 || test1.charAt(0)!=1 || test1.charAt(1)!=2 || test1.charAt(2)!=3 || test1.charAt(3)!=4) {
   1065         errln("UnicodeString::releaseBuffer(newLength) does not properly reallow access to the UnicodeString");
   1066     }
   1067 
   1068     // test releaseBuffer() without getBuffer(minCapacity) - must not have any effect
   1069     test1.releaseBuffer(1);
   1070     if(test1.length()!=4 || test1.charAt(0)!=1 || test1.charAt(1)!=2 || test1.charAt(2)!=3 || test1.charAt(3)!=4) {
   1071         errln("UnicodeString::releaseBuffer(newLength) without getBuffer(minCapacity) changed the UnicodeString");
   1072     }
   1073 
   1074     // test getBuffer(const)
   1075     const UChar *q=test1.getBuffer(), *r=test1.getBuffer();
   1076     if( test1.length()!=4 ||
   1077         q[0]!=1 || q[1]!=2 || q[2]!=3 || q[3]!=4 ||
   1078         r[0]!=1 || r[1]!=2 || r[2]!=3 || r[3]!=4
   1079     ) {
   1080         errln("UnicodeString::getBuffer(const) does not return a usable buffer pointer");
   1081     }
   1082 
   1083     // test releaseBuffer() with a NUL-terminated buffer
   1084     test1.getBuffer(20)[2]=0;
   1085     test1.releaseBuffer(); // implicit -1
   1086     if(test1.length()!=2 || test1.charAt(0)!=1 || test1.charAt(1) !=2) {
   1087         errln("UnicodeString::releaseBuffer(-1) does not properly set the length of the UnicodeString");
   1088     }
   1089 
   1090     // test releaseBuffer() with a non-NUL-terminated buffer
   1091     p=test1.getBuffer(256);
   1092     for(int32_t i=0; i<test1.getCapacity(); ++i) {
   1093         p[i]=(UChar)1;      // fill the buffer with all non-NUL code units
   1094     }
   1095     test1.releaseBuffer();  // implicit -1
   1096     if(test1.length()!=test1.getCapacity() || test1.charAt(1)!=1 || test1.charAt(100)!=1 || test1.charAt(test1.getCapacity()-1)!=1) {
   1097         errln("UnicodeString::releaseBuffer(-1 but no NUL) does not properly set the length of the UnicodeString");
   1098     }
   1099 
   1100     // test getTerminatedBuffer()
   1101     test1=UnicodeString("This is another test.", "");
   1102     test2=UnicodeString("This is another test.", "");
   1103     q=test1.getTerminatedBuffer();
   1104     if(q[test1.length()]!=0 || test1!=test2 || test2.compare(q, -1)!=0) {
   1105         errln("getTerminatedBuffer()[length]!=0");
   1106     }
   1107 
   1108     const UChar u[]={ 5, 6, 7, 8, 0 };
   1109     test1.setTo(FALSE, u, 3);
   1110     q=test1.getTerminatedBuffer();
   1111     if(q==u || q[0]!=5 || q[1]!=6 || q[2]!=7 || q[3]!=0) {
   1112         errln("UnicodeString(u[3]).getTerminatedBuffer() returns a bad buffer");
   1113     }
   1114 
   1115     test1.setTo(TRUE, u, -1);
   1116     q=test1.getTerminatedBuffer();
   1117     if(q!=u || test1.length()!=4 || q[3]!=8 || q[4]!=0) {
   1118         errln("UnicodeString(u[-1]).getTerminatedBuffer() returns a bad buffer");
   1119     }
   1120 
   1121     test1=UNICODE_STRING("la", 2);
   1122     test1.append(UNICODE_STRING(" lila", 5).getTerminatedBuffer(), 0, -1);
   1123     if(test1!=UNICODE_STRING("la lila", 7)) {
   1124         errln("UnicodeString::append(const UChar *, start, length) failed");
   1125     }
   1126 
   1127     test1.insert(3, UNICODE_STRING("dudum ", 6), 0, INT32_MAX);
   1128     if(test1!=UNICODE_STRING("la dudum lila", 13)) {
   1129         errln("UnicodeString::insert(start, const UniStr &, start, length) failed");
   1130     }
   1131 
   1132     static const UChar ucs[]={ 0x68, 0x6d, 0x20, 0 };
   1133     test1.insert(9, ucs, -1);
   1134     if(test1!=UNICODE_STRING("la dudum hm lila", 16)) {
   1135         errln("UnicodeString::insert(start, const UChar *, length) failed");
   1136     }
   1137 
   1138     test1.replace(9, 2, (UChar)0x2b);
   1139     if(test1!=UNICODE_STRING("la dudum + lila", 15)) {
   1140         errln("UnicodeString::replace(start, length, UChar) failed");
   1141     }
   1142 
   1143     if(test1.hasMetaData() || UnicodeString().hasMetaData()) {
   1144         errln("UnicodeString::hasMetaData() returns TRUE");
   1145     }
   1146 
   1147     // test getTerminatedBuffer() on a truncated, shared, heap-allocated string
   1148     test1=UNICODE_STRING_SIMPLE("abcdefghijklmnopqrstuvwxyz0123456789.");
   1149     test1.truncate(36);  // ensure length()<getCapacity()
   1150     test2=test1;  // share the buffer
   1151     test1.truncate(5);
   1152     if(test1.length()!=5 || test1.getTerminatedBuffer()[5]!=0) {
   1153         errln("UnicodeString(shared buffer).truncate() failed");
   1154     }
   1155     if(test2.length()!=36 || test2[5]!=0x66 || u_strlen(test2.getTerminatedBuffer())!=36) {
   1156         errln("UnicodeString(shared buffer).truncate().getTerminatedBuffer() "
   1157               "modified another copy of the string!");
   1158     }
   1159     test1=UNICODE_STRING_SIMPLE("abcdefghijklmnopqrstuvwxyz0123456789.");
   1160     test1.truncate(36);  // ensure length()<getCapacity()
   1161     test2=test1;  // share the buffer
   1162     test1.remove();
   1163     if(test1.length()!=0 || test1.getTerminatedBuffer()[0]!=0) {
   1164         errln("UnicodeString(shared buffer).remove() failed");
   1165     }
   1166     if(test2.length()!=36 || test2[0]!=0x61 || u_strlen(test2.getTerminatedBuffer())!=36) {
   1167         errln("UnicodeString(shared buffer).remove().getTerminatedBuffer() "
   1168               "modified another copy of the string!");
   1169     }
   1170 }
   1171 
   1172 void
   1173 UnicodeStringTest::TestStackAllocation()
   1174 {
   1175     UChar           testString[] ={
   1176         0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x63, 0x72, 0x61, 0x7a, 0x79, 0x20, 0x74, 0x65, 0x73, 0x74, 0x2e, 0 };
   1177     UChar           guardWord = 0x4DED;
   1178     UnicodeString*  test = 0;
   1179 
   1180     test = new  UnicodeString(testString);
   1181     if (*test != "This is a crazy test.")
   1182         errln("Test string failed to initialize properly.");
   1183     if (guardWord != 0x04DED)
   1184         errln("Test string initialization overwrote guard word!");
   1185 
   1186     test->insert(8, "only ");
   1187     test->remove(15, 6);
   1188     if (*test != "This is only a test.")
   1189         errln("Manipulation of test string failed to work right.");
   1190     if (guardWord != 0x4DED)
   1191         errln("Manipulation of test string overwrote guard word!");
   1192 
   1193     // we have to deinitialize and release the backing store by calling the destructor
   1194     // explicitly, since we can't overload operator delete
   1195     delete test;
   1196 
   1197     UChar workingBuffer[] = {
   1198         0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
   1199         0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x6d, 0x65, 0x6e, 0x20, 0x74, 0x6f, 0x20,
   1200         0x63, 0x6f, 0x6d, 0x65, 0xffff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   1201         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,
   1202         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
   1203     UChar guardWord2 = 0x4DED;
   1204 
   1205     test = new UnicodeString(workingBuffer, 35, 100);
   1206     if (*test != "Now is the time for all men to come")
   1207         errln("Stack-allocated backing store failed to initialize correctly.");
   1208     if (guardWord2 != 0x4DED)
   1209         errln("Stack-allocated backing store overwrote guard word!");
   1210 
   1211     test->insert(24, "good ");
   1212     if (*test != "Now is the time for all good men to come")
   1213         errln("insert() on stack-allocated UnicodeString didn't work right");
   1214     if (guardWord2 != 0x4DED)
   1215         errln("insert() on stack-allocated UnicodeString overwrote guard word!");
   1216 
   1217     if (workingBuffer[24] != 0x67)
   1218         errln("insert() on stack-allocated UnicodeString didn't affect backing store");
   1219 
   1220     *test += " to the aid of their country.";
   1221     if (*test != "Now is the time for all good men to come to the aid of their country.")
   1222         errln("Stack-allocated UnicodeString overflow didn't work");
   1223     if (guardWord2 != 0x4DED)
   1224         errln("Stack-allocated UnicodeString overflow overwrote guard word!");
   1225 
   1226     *test = "ha!";
   1227     if (*test != "ha!")
   1228         errln("Assignment to stack-allocated UnicodeString didn't work");
   1229     if (workingBuffer[0] != 0x4e)
   1230         errln("Change to UnicodeString after overflow are still affecting original buffer");
   1231     if (guardWord2 != 0x4DED)
   1232         errln("Change to UnicodeString after overflow overwrote guard word!");
   1233 
   1234     // test read-only aliasing with setTo()
   1235     workingBuffer[0] = 0x20ac;
   1236     workingBuffer[1] = 0x125;
   1237     workingBuffer[2] = 0;
   1238     test->setTo(TRUE, workingBuffer, 2);
   1239     if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x125) {
   1240         errln("UnicodeString.setTo(readonly alias) does not alias correctly");
   1241     }
   1242 
   1243     UnicodeString *c=(UnicodeString *)test->clone();
   1244 
   1245     workingBuffer[1] = 0x109;
   1246     if(test->charAt(1) != 0x109) {
   1247         errln("UnicodeString.setTo(readonly alias) made a copy: did not see change in buffer");
   1248     }
   1249 
   1250     if(c->length() != 2 || c->charAt(1) != 0x125) {
   1251         errln("clone(alias) did not copy the buffer");
   1252     }
   1253     delete c;
   1254 
   1255     test->setTo(TRUE, workingBuffer, -1);
   1256     if(test->length() != 2 || test->charAt(0) != 0x20ac || test->charAt(1) != 0x109) {
   1257         errln("UnicodeString.setTo(readonly alias, length -1) does not alias correctly");
   1258     }
   1259 
   1260     test->setTo(FALSE, workingBuffer, -1);
   1261     if(!test->isBogus()) {
   1262         errln("UnicodeString.setTo(unterminated readonly alias, length -1) does not result in isBogus()");
   1263     }
   1264 
   1265     delete test;
   1266 
   1267     test=new UnicodeString();
   1268     UChar buffer[]={0x0061, 0x0062, 0x20ac, 0x0043, 0x0042, 0x0000};
   1269     test->setTo(buffer, 4, 10);
   1270     if(test->length() !=4 || test->charAt(0) != 0x0061 || test->charAt(1) != 0x0062 ||
   1271         test->charAt(2) != 0x20ac || test->charAt(3) != 0x0043){
   1272         errln((UnicodeString)"UnicodeString.setTo(UChar*, length, capacity) does not work correctly\n" + prettify(*test));
   1273     }
   1274     delete test;
   1275 
   1276 
   1277     // test the UChar32 constructor
   1278     UnicodeString c32Test((UChar32)0x10ff2a);
   1279     if( c32Test.length() != U16_LENGTH(0x10ff2a) ||
   1280         c32Test.char32At(c32Test.length() - 1) != 0x10ff2a
   1281     ) {
   1282         errln("The UnicodeString(UChar32) constructor does not work with a 0x10ff2a filler");
   1283     }
   1284 
   1285     // test the (new) capacity constructor
   1286     UnicodeString capTest(5, (UChar32)0x2a, 5);
   1287     if( capTest.length() != 5 * U16_LENGTH(0x2a) ||
   1288         capTest.char32At(0) != 0x2a ||
   1289         capTest.char32At(4) != 0x2a
   1290     ) {
   1291         errln("The UnicodeString capacity constructor does not work with an ASCII filler");
   1292     }
   1293 
   1294     capTest = UnicodeString(5, (UChar32)0x10ff2a, 5);
   1295     if( capTest.length() != 5 * U16_LENGTH(0x10ff2a) ||
   1296         capTest.char32At(0) != 0x10ff2a ||
   1297         capTest.char32At(4) != 0x10ff2a
   1298     ) {
   1299         errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
   1300     }
   1301 
   1302     capTest = UnicodeString(5, (UChar32)0, 0);
   1303     if(capTest.length() != 0) {
   1304         errln("The UnicodeString capacity constructor does not work with a 0x10ff2a filler");
   1305     }
   1306 }
   1307 
   1308 /**
   1309  * Test the unescape() function.
   1310  */
   1311 void UnicodeStringTest::TestUnescape(void) {
   1312     UnicodeString IN("abc\\u4567 \\n\\r \\U00101234xyz\\x1\\x{5289}\\x1b", -1, US_INV);
   1313     UnicodeString OUT("abc");
   1314     OUT.append((UChar)0x4567);
   1315     OUT.append(" ");
   1316     OUT.append((UChar)0xA);
   1317     OUT.append((UChar)0xD);
   1318     OUT.append(" ");
   1319     OUT.append((UChar32)0x00101234);
   1320     OUT.append("xyz");
   1321     OUT.append((UChar32)1).append((UChar32)0x5289).append((UChar)0x1b);
   1322     UnicodeString result = IN.unescape();
   1323     if (result != OUT) {
   1324         errln("FAIL: " + prettify(IN) + ".unescape() -> " +
   1325               prettify(result) + ", expected " +
   1326               prettify(OUT));
   1327     }
   1328 
   1329     // test that an empty string is returned in case of an error
   1330     if (!UNICODE_STRING("wrong \\u sequence", 17).unescape().isEmpty()) {
   1331         errln("FAIL: unescaping of a string with an illegal escape sequence did not return an empty string");
   1332     }
   1333 }
   1334 
   1335 /* test code point counting functions --------------------------------------- */
   1336 
   1337 /* reference implementation of UnicodeString::hasMoreChar32Than() */
   1338 static int32_t
   1339 _refUnicodeStringHasMoreChar32Than(const UnicodeString &s, int32_t start, int32_t length, int32_t number) {
   1340     int32_t count=s.countChar32(start, length);
   1341     return count>number;
   1342 }
   1343 
   1344 /* compare the real function against the reference */
   1345 void
   1346 UnicodeStringTest::_testUnicodeStringHasMoreChar32Than(const UnicodeString &s, int32_t start, int32_t length, int32_t number) {
   1347     if(s.hasMoreChar32Than(start, length, number)!=_refUnicodeStringHasMoreChar32Than(s, start, length, number)) {
   1348         errln("hasMoreChar32Than(%d, %d, %d)=%hd is wrong\n",
   1349                 start, length, number, s.hasMoreChar32Than(start, length, number));
   1350     }
   1351 }
   1352 
   1353 void
   1354 UnicodeStringTest::TestCountChar32(void) {
   1355     {
   1356         UnicodeString s=UNICODE_STRING("\\U0002f999\\U0001d15f\\u00c4\\u1ed0", 32).unescape();
   1357 
   1358         // test countChar32()
   1359         // note that this also calls and tests u_countChar32(length>=0)
   1360         if(
   1361             s.countChar32()!=4 ||
   1362             s.countChar32(1)!=4 ||
   1363             s.countChar32(2)!=3 ||
   1364             s.countChar32(2, 3)!=2 ||
   1365             s.countChar32(2, 0)!=0
   1366         ) {
   1367             errln("UnicodeString::countChar32() failed");
   1368         }
   1369 
   1370         // NUL-terminate the string buffer and test u_countChar32(length=-1)
   1371         const UChar *buffer=s.getTerminatedBuffer();
   1372         if(
   1373             u_countChar32(buffer, -1)!=4 ||
   1374             u_countChar32(buffer+1, -1)!=4 ||
   1375             u_countChar32(buffer+2, -1)!=3 ||
   1376             u_countChar32(buffer+3, -1)!=3 ||
   1377             u_countChar32(buffer+4, -1)!=2 ||
   1378             u_countChar32(buffer+5, -1)!=1 ||
   1379             u_countChar32(buffer+6, -1)!=0
   1380         ) {
   1381             errln("u_countChar32(length=-1) failed");
   1382         }
   1383 
   1384         // test u_countChar32() with bad input
   1385         if(u_countChar32(NULL, 5)!=0 || u_countChar32(buffer, -2)!=0) {
   1386             errln("u_countChar32(bad input) failed (returned non-zero counts)");
   1387         }
   1388     }
   1389 
   1390     /* test data and variables for hasMoreChar32Than() */
   1391     static const UChar str[]={
   1392         0x61, 0x62, 0xd800, 0xdc00,
   1393         0xd801, 0xdc01, 0x63, 0xd802,
   1394         0x64, 0xdc03, 0x65, 0x66,
   1395         0xd804, 0xdc04, 0xd805, 0xdc05,
   1396         0x67
   1397     };
   1398     UnicodeString string(str, LENGTHOF(str));
   1399     int32_t start, length, number;
   1400 
   1401     /* test hasMoreChar32Than() */
   1402     for(length=string.length(); length>=0; --length) {
   1403         for(start=0; start<=length; ++start) {
   1404             for(number=-1; number<=((length-start)+2); ++number) {
   1405                 _testUnicodeStringHasMoreChar32Than(string, start, length-start, number);
   1406             }
   1407         }
   1408     }
   1409 
   1410     /* test hasMoreChar32Than() with pinning */
   1411     for(start=-1; start<=string.length()+1; ++start) {
   1412         for(number=-1; number<=((string.length()-start)+2); ++number) {
   1413             _testUnicodeStringHasMoreChar32Than(string, start, 0x7fffffff, number);
   1414         }
   1415     }
   1416 
   1417     /* test hasMoreChar32Than() with a bogus string */
   1418     string.setToBogus();
   1419     for(length=-1; length<=1; ++length) {
   1420         for(start=-1; start<=length; ++start) {
   1421             for(number=-1; number<=((length-start)+2); ++number) {
   1422                 _testUnicodeStringHasMoreChar32Than(string, start, length-start, number);
   1423             }
   1424         }
   1425     }
   1426 }
   1427 
   1428 void
   1429 UnicodeStringTest::TestBogus() {
   1430     UnicodeString   test1("This is a test");
   1431     UnicodeString   test2("This is a test");
   1432     UnicodeString   test3("Me too!");
   1433 
   1434     // test isBogus() and setToBogus()
   1435     if (test1.isBogus() || test2.isBogus() || test3.isBogus()) {
   1436         errln("A string returned TRUE for isBogus()!");
   1437     }
   1438 
   1439     // NULL pointers are treated like empty strings
   1440     // use other illegal arguments to make a bogus string
   1441     test3.setTo(FALSE, test1.getBuffer(), -2);
   1442     if(!test3.isBogus()) {
   1443         errln("A bogus string returned FALSE for isBogus()!");
   1444     }
   1445     if (test1.hashCode() != test2.hashCode() || test1.hashCode() == test3.hashCode()) {
   1446         errln("hashCode() failed");
   1447     }
   1448     if(test3.getBuffer()!=0 || test3.getBuffer(20)!=0 || test3.getTerminatedBuffer()!=0) {
   1449         errln("bogus.getBuffer()!=0");
   1450     }
   1451     if (test1.indexOf(test3) != -1) {
   1452         errln("bogus.indexOf() != -1");
   1453     }
   1454     if (test1.lastIndexOf(test3) != -1) {
   1455         errln("bogus.lastIndexOf() != -1");
   1456     }
   1457     if (test1.caseCompare(test3, U_FOLD_CASE_DEFAULT) != 1 || test3.caseCompare(test1, U_FOLD_CASE_DEFAULT) != -1) {
   1458         errln("caseCompare() doesn't work with bogus strings");
   1459     }
   1460     if (test1.compareCodePointOrder(test3) != 1 || test3.compareCodePointOrder(test1) != -1) {
   1461         errln("compareCodePointOrder() doesn't work with bogus strings");
   1462     }
   1463 
   1464     // verify that non-assignment modifications fail and do not revive a bogus string
   1465     test3.setToBogus();
   1466     test3.append((UChar)0x61);
   1467     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1468         errln("bogus.append('a') worked but must not");
   1469     }
   1470 
   1471     test3.setToBogus();
   1472     test3.findAndReplace(UnicodeString((UChar)0x61), test2);
   1473     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1474         errln("bogus.findAndReplace() worked but must not");
   1475     }
   1476 
   1477     test3.setToBogus();
   1478     test3.trim();
   1479     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1480         errln("bogus.trim() revived bogus but must not");
   1481     }
   1482 
   1483     test3.setToBogus();
   1484     test3.remove(1);
   1485     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1486         errln("bogus.remove(1) revived bogus but must not");
   1487     }
   1488 
   1489     test3.setToBogus();
   1490     if(!test3.setCharAt(0, 0x62).isBogus() || !test3.isEmpty()) {
   1491         errln("bogus.setCharAt(0, 'b') worked but must not");
   1492     }
   1493 
   1494     test3.setToBogus();
   1495     if(test3.truncate(1) || !test3.isBogus() || !test3.isEmpty()) {
   1496         errln("bogus.truncate(1) revived bogus but must not");
   1497     }
   1498 
   1499     // verify that assignments revive a bogus string
   1500     test3.setToBogus();
   1501     if(!test3.isBogus() || (test3=test1).isBogus() || test3!=test1) {
   1502         errln("bogus.operator=() failed");
   1503     }
   1504 
   1505     test3.setToBogus();
   1506     if(!test3.isBogus() || test3.fastCopyFrom(test1).isBogus() || test3!=test1) {
   1507         errln("bogus.fastCopyFrom() failed");
   1508     }
   1509 
   1510     test3.setToBogus();
   1511     if(!test3.isBogus() || test3.setTo(test1).isBogus() || test3!=test1) {
   1512         errln("bogus.setTo(UniStr) failed");
   1513     }
   1514 
   1515     test3.setToBogus();
   1516     if(!test3.isBogus() || test3.setTo(test1, 0).isBogus() || test3!=test1) {
   1517         errln("bogus.setTo(UniStr, 0) failed");
   1518     }
   1519 
   1520     test3.setToBogus();
   1521     if(!test3.isBogus() || test3.setTo(test1, 0, 0x7fffffff).isBogus() || test3!=test1) {
   1522         errln("bogus.setTo(UniStr, 0, len) failed");
   1523     }
   1524 
   1525     test3.setToBogus();
   1526     if(!test3.isBogus() || test3.setTo(test1.getBuffer(), test1.length()).isBogus() || test3!=test1) {
   1527         errln("bogus.setTo(const UChar *, len) failed");
   1528     }
   1529 
   1530     test3.setToBogus();
   1531     if(!test3.isBogus() || test3.setTo((UChar)0x2028).isBogus() || test3!=UnicodeString((UChar)0x2028)) {
   1532         errln("bogus.setTo(UChar) failed");
   1533     }
   1534 
   1535     test3.setToBogus();
   1536     if(!test3.isBogus() || test3.setTo((UChar32)0x1d157).isBogus() || test3!=UnicodeString((UChar32)0x1d157)) {
   1537         errln("bogus.setTo(UChar32) failed");
   1538     }
   1539 
   1540     test3.setToBogus();
   1541     if(!test3.isBogus() || test3.setTo(FALSE, test1.getBuffer(), test1.length()).isBogus() || test3!=test1) {
   1542         errln("bogus.setTo(readonly alias) failed");
   1543     }
   1544 
   1545     // writable alias to another string's buffer: very bad idea, just convenient for this test
   1546     test3.setToBogus();
   1547     if(!test3.isBogus() || test3.setTo((UChar *)test1.getBuffer(), test1.length(), test1.getCapacity()).isBogus() || test3!=test1) {
   1548         errln("bogus.setTo(writable alias) failed");
   1549     }
   1550 
   1551     // verify simple, documented ways to turn a bogus string into an empty one
   1552     test3.setToBogus();
   1553     if(!test3.isBogus() || (test3=UnicodeString()).isBogus() || !test3.isEmpty()) {
   1554         errln("bogus.operator=(UnicodeString()) failed");
   1555     }
   1556 
   1557     test3.setToBogus();
   1558     if(!test3.isBogus() || test3.setTo(UnicodeString()).isBogus() || !test3.isEmpty()) {
   1559         errln("bogus.setTo(UnicodeString()) failed");
   1560     }
   1561 
   1562     test3.setToBogus();
   1563     if(test3.remove().isBogus() || test3.getBuffer()==0 || !test3.isEmpty()) {
   1564         errln("bogus.remove() failed");
   1565     }
   1566 
   1567     test3.setToBogus();
   1568     if(test3.remove(0, INT32_MAX).isBogus() || test3.getBuffer()==0 || !test3.isEmpty()) {
   1569         errln("bogus.remove(0, INT32_MAX) failed");
   1570     }
   1571 
   1572     test3.setToBogus();
   1573     if(test3.truncate(0) || test3.isBogus() || !test3.isEmpty()) {
   1574         errln("bogus.truncate(0) failed");
   1575     }
   1576 
   1577     test3.setToBogus();
   1578     if(!test3.isBogus() || test3.setTo((UChar32)-1).isBogus() || !test3.isEmpty()) {
   1579         errln("bogus.setTo((UChar32)-1) failed");
   1580     }
   1581 
   1582     static const UChar nul=0;
   1583 
   1584     test3.setToBogus();
   1585     if(!test3.isBogus() || test3.setTo(&nul, 0).isBogus() || !test3.isEmpty()) {
   1586         errln("bogus.setTo(&nul, 0) failed");
   1587     }
   1588 
   1589     test3.setToBogus();
   1590     if(!test3.isBogus() || test3.getBuffer()!=0) {
   1591         errln("setToBogus() failed to make a string bogus");
   1592     }
   1593 
   1594     test3.setToBogus();
   1595     if(test1.isBogus() || !(test1=test3).isBogus()) {
   1596         errln("normal=bogus failed to make the left string bogus");
   1597     }
   1598 
   1599     // test that NULL primitive input string values are treated like
   1600     // empty strings, not errors (bogus)
   1601     test2.setTo((UChar32)0x10005);
   1602     if(test2.insert(1, NULL, 1).length()!=2) {
   1603         errln("UniStr.insert(...NULL...) should not modify the string but does");
   1604     }
   1605 
   1606     UErrorCode errorCode=U_ZERO_ERROR;
   1607     UnicodeString
   1608         test4((const UChar *)NULL),
   1609         test5(TRUE, (const UChar *)NULL, 1),
   1610         test6((UChar *)NULL, 5, 5),
   1611         test7((const char *)NULL, 3, NULL, errorCode);
   1612     if(test4.isBogus() || test5.isBogus() || test6.isBogus() || test7.isBogus()) {
   1613         errln("a constructor set to bogus for a NULL input string, should be empty");
   1614     }
   1615 
   1616     test4.setTo(NULL, 3);
   1617     test5.setTo(TRUE, (const UChar *)NULL, 1);
   1618     test6.setTo((UChar *)NULL, 5, 5);
   1619     if(test4.isBogus() || test5.isBogus() || test6.isBogus()) {
   1620         errln("a setTo() set to bogus for a NULL input string, should be empty");
   1621     }
   1622 
   1623     // test that bogus==bogus<any
   1624     if(test1!=test3 || test1.compare(test3)!=0) {
   1625         errln("bogus==bogus failed");
   1626     }
   1627 
   1628     test2.remove();
   1629     if(test1>=test2 || !(test2>test1) || test1.compare(test2)>=0 || !(test2.compare(test1)>0)) {
   1630         errln("bogus<empty failed");
   1631     }
   1632 }
   1633 
   1634 // StringEnumeration ------------------------------------------------------- ***
   1635 // most of StringEnumeration is tested elsewhere
   1636 // this test improves code coverage
   1637 
   1638 static const char *const
   1639 testEnumStrings[]={
   1640     "a",
   1641     "b",
   1642     "c",
   1643     "this is a long string which helps us test some buffer limits",
   1644     "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
   1645 };
   1646 
   1647 class TestEnumeration : public StringEnumeration {
   1648 public:
   1649     TestEnumeration() : i(0) {}
   1650 
   1651     virtual int32_t count(UErrorCode& /*status*/) const {
   1652         return LENGTHOF(testEnumStrings);
   1653     }
   1654 
   1655     virtual const UnicodeString *snext(UErrorCode &status) {
   1656         if(U_SUCCESS(status) && i<LENGTHOF(testEnumStrings)) {
   1657             unistr=UnicodeString(testEnumStrings[i++], "");
   1658             return &unistr;
   1659         }
   1660 
   1661         return NULL;
   1662     }
   1663 
   1664     virtual void reset(UErrorCode& /*status*/) {
   1665         i=0;
   1666     }
   1667 
   1668     static inline UClassID getStaticClassID() {
   1669         return (UClassID)&fgClassID;
   1670     }
   1671     virtual UClassID getDynamicClassID() const {
   1672         return getStaticClassID();
   1673     }
   1674 
   1675 private:
   1676     static const char fgClassID;
   1677 
   1678     int32_t i, length;
   1679 };
   1680 
   1681 const char TestEnumeration::fgClassID=0;
   1682 
   1683 void
   1684 UnicodeStringTest::TestStringEnumeration() {
   1685     UnicodeString s;
   1686     TestEnumeration ten;
   1687     int32_t i, length;
   1688     UErrorCode status;
   1689 
   1690     const UChar *pu;
   1691     const char *pc;
   1692 
   1693     // test the next() default implementation and ensureCharsCapacity()
   1694     for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
   1695         status=U_ZERO_ERROR;
   1696         pc=ten.next(&length, status);
   1697         s=UnicodeString(testEnumStrings[i], "");
   1698         if(U_FAILURE(status) || pc==NULL || length!=s.length() || UnicodeString(pc, length, "")!=s) {
   1699             errln("StringEnumeration.next(%d) failed", i);
   1700         }
   1701     }
   1702     status=U_ZERO_ERROR;
   1703     if(ten.next(&length, status)!=NULL) {
   1704         errln("StringEnumeration.next(done)!=NULL");
   1705     }
   1706 
   1707     // test the unext() default implementation
   1708     ten.reset(status);
   1709     for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
   1710         status=U_ZERO_ERROR;
   1711         pu=ten.unext(&length, status);
   1712         s=UnicodeString(testEnumStrings[i], "");
   1713         if(U_FAILURE(status) || pu==NULL || length!=s.length() || UnicodeString(TRUE, pu, length)!=s) {
   1714             errln("StringEnumeration.unext(%d) failed", i);
   1715         }
   1716     }
   1717     status=U_ZERO_ERROR;
   1718     if(ten.unext(&length, status)!=NULL) {
   1719         errln("StringEnumeration.unext(done)!=NULL");
   1720     }
   1721 
   1722     // test that the default clone() implementation works, and returns NULL
   1723     if(ten.clone()!=NULL) {
   1724         errln("StringEnumeration.clone()!=NULL");
   1725     }
   1726 
   1727     // test that uenum_openFromStringEnumeration() works
   1728     // Need a heap allocated string enumeration because it is adopted by the UEnumeration.
   1729     StringEnumeration *newTen = new TestEnumeration;
   1730     status=U_ZERO_ERROR;
   1731     UEnumeration *uten = uenum_openFromStringEnumeration(newTen, &status);
   1732     if (uten==NULL || U_FAILURE(status)) {
   1733         errln("fail at file %s, line %d, UErrorCode is %s\n", __FILE__, __LINE__, u_errorName(status));
   1734         return;
   1735     }
   1736 
   1737     // test  uenum_next()
   1738     for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
   1739         status=U_ZERO_ERROR;
   1740         pc=uenum_next(uten, &length, &status);
   1741         if(U_FAILURE(status) || pc==NULL || strcmp(pc, testEnumStrings[i]) != 0) {
   1742             errln("File %s, line %d, StringEnumeration.next(%d) failed", __FILE__, __LINE__, i);
   1743         }
   1744     }
   1745     status=U_ZERO_ERROR;
   1746     if(uenum_next(uten, &length, &status)!=NULL) {
   1747         errln("File %s, line %d, uenum_next(done)!=NULL");
   1748     }
   1749 
   1750     // test the uenum_unext()
   1751     uenum_reset(uten, &status);
   1752     for(i=0; i<LENGTHOF(testEnumStrings); ++i) {
   1753         status=U_ZERO_ERROR;
   1754         pu=uenum_unext(uten, &length, &status);
   1755         s=UnicodeString(testEnumStrings[i], "");
   1756         if(U_FAILURE(status) || pu==NULL || length!=s.length() || UnicodeString(TRUE, pu, length)!=s) {
   1757             errln("File %s, Line %d, uenum_unext(%d) failed", __FILE__, __LINE__, i);
   1758         }
   1759     }
   1760     status=U_ZERO_ERROR;
   1761     if(uenum_unext(uten, &length, &status)!=NULL) {
   1762         errln("File %s, Line %d, uenum_unext(done)!=NULL" __FILE__, __LINE__);
   1763     }
   1764 
   1765     uenum_close(uten);
   1766 }
   1767 
   1768 /*
   1769  * Namespace test, to make sure that macros like UNICODE_STRING include the
   1770  * namespace qualifier.
   1771  *
   1772  * Define a (bogus) UnicodeString class in another namespace and check for ambiguity.
   1773  */
   1774 namespace bogus {
   1775     class UnicodeString {
   1776     public:
   1777         enum EInvariant { kInvariant };
   1778         UnicodeString() : i(1) {}
   1779         UnicodeString(UBool /*isTerminated*/, const UChar * /*text*/, int32_t textLength) : i(textLength) {}
   1780         UnicodeString(const char * /*src*/, int32_t length, enum EInvariant /*inv*/
   1781 ) : i(length) {}
   1782     private:
   1783         int32_t i;
   1784     };
   1785 }
   1786 
   1787 void
   1788 UnicodeStringTest::TestNameSpace() {
   1789     // Provoke name collision unless the UnicodeString macros properly
   1790     // qualify the icu::UnicodeString class.
   1791     using namespace bogus;
   1792 
   1793     // Use all UnicodeString macros from unistr.h.
   1794     icu::UnicodeString s1=icu::UnicodeString("abc", 3, US_INV);
   1795     icu::UnicodeString s2=UNICODE_STRING("def", 3);
   1796     icu::UnicodeString s3=UNICODE_STRING_SIMPLE("ghi");
   1797 
   1798     // Make sure the compiler does not optimize away instantiation of s1, s2, s3.
   1799     icu::UnicodeString s4=s1+s2+s3;
   1800     if(s4.length()!=9) {
   1801         errln("Something wrong with UnicodeString::operator+().");
   1802     }
   1803 }
   1804 
   1805 void
   1806 UnicodeStringTest::TestUTF32() {
   1807     // Input string length US_STACKBUF_SIZE to cause overflow of the
   1808     // initially chosen fStackBuffer due to supplementary characters.
   1809     static const UChar32 utf32[] = {
   1810         0x41, 0xd900, 0x61, 0xdc00, -1, 0x110000, 0x5a, 0x50000, 0x7a,
   1811         0x10000, 0x20000, 0xe0000, 0x10ffff
   1812     };
   1813     static const UChar expected_utf16[] = {
   1814         0x41, 0xfffd, 0x61, 0xfffd, 0xfffd, 0xfffd, 0x5a, 0xd900, 0xdc00, 0x7a,
   1815         0xd800, 0xdc00, 0xd840, 0xdc00, 0xdb40, 0xdc00, 0xdbff, 0xdfff
   1816     };
   1817     UnicodeString from32 = UnicodeString::fromUTF32(utf32, LENGTHOF(utf32));
   1818     UnicodeString expected(FALSE, expected_utf16, LENGTHOF(expected_utf16));
   1819     if(from32 != expected) {
   1820         errln("UnicodeString::fromUTF32() did not create the expected string.");
   1821     }
   1822 
   1823     static const UChar utf16[] = {
   1824         0x41, 0xd900, 0x61, 0xdc00, 0x5a, 0xd900, 0xdc00, 0x7a, 0xd800, 0xdc00, 0xdbff, 0xdfff
   1825     };
   1826     static const UChar32 expected_utf32[] = {
   1827         0x41, 0xfffd, 0x61, 0xfffd, 0x5a, 0x50000, 0x7a, 0x10000, 0x10ffff
   1828     };
   1829     UChar32 result32[16];
   1830     UErrorCode errorCode = U_ZERO_ERROR;
   1831     int32_t length32 =
   1832         UnicodeString(FALSE, utf16, LENGTHOF(utf16)).
   1833         toUTF32(result32, LENGTHOF(result32), errorCode);
   1834     if( length32 != LENGTHOF(expected_utf32) ||
   1835         0 != uprv_memcmp(result32, expected_utf32, length32*4) ||
   1836         result32[length32] != 0
   1837     ) {
   1838         errln("UnicodeString::toUTF32() did not create the expected string.");
   1839     }
   1840 }
   1841 
   1842 class TestCheckedArrayByteSink : public CheckedArrayByteSink {
   1843 public:
   1844     TestCheckedArrayByteSink(char* outbuf, int32_t capacity)
   1845             : CheckedArrayByteSink(outbuf, capacity), calledFlush(FALSE) {}
   1846     virtual void Flush() { calledFlush = TRUE; }
   1847     UBool calledFlush;
   1848 };
   1849 
   1850 void
   1851 UnicodeStringTest::TestUTF8() {
   1852     static const uint8_t utf8[] = {
   1853         // Code points:
   1854         // 0x41, 0xd900,
   1855         // 0x61, 0xdc00,
   1856         // 0x110000, 0x5a,
   1857         // 0x50000, 0x7a,
   1858         // 0x10000, 0x20000,
   1859         // 0xe0000, 0x10ffff
   1860         0x41, 0xed, 0xa4, 0x80,
   1861         0x61, 0xed, 0xb0, 0x80,
   1862         0xf4, 0x90, 0x80, 0x80, 0x5a,
   1863         0xf1, 0x90, 0x80, 0x80, 0x7a,
   1864         0xf0, 0x90, 0x80, 0x80, 0xf0, 0xa0, 0x80, 0x80,
   1865         0xf3, 0xa0, 0x80, 0x80, 0xf4, 0x8f, 0xbf, 0xbf
   1866     };
   1867     static const UChar expected_utf16[] = {
   1868         0x41, 0xfffd,
   1869         0x61, 0xfffd,
   1870         0xfffd, 0x5a,
   1871         0xd900, 0xdc00, 0x7a,
   1872         0xd800, 0xdc00, 0xd840, 0xdc00,
   1873         0xdb40, 0xdc00, 0xdbff, 0xdfff
   1874     };
   1875     UnicodeString from8 = UnicodeString::fromUTF8(StringPiece((const char *)utf8, (int32_t)sizeof(utf8)));
   1876     UnicodeString expected(FALSE, expected_utf16, LENGTHOF(expected_utf16));
   1877 
   1878     if(from8 != expected) {
   1879         errln("UnicodeString::fromUTF8(StringPiece) did not create the expected string.");
   1880     }
   1881 #if U_HAVE_STD_STRING
   1882     std::string utf8_string((const char *)utf8, sizeof(utf8));
   1883     UnicodeString from8b = UnicodeString::fromUTF8(utf8_string);
   1884     if(from8b != expected) {
   1885         errln("UnicodeString::fromUTF8(std::string) did not create the expected string.");
   1886     }
   1887 #endif
   1888 
   1889     static const UChar utf16[] = {
   1890         0x41, 0xd900, 0x61, 0xdc00, 0x5a, 0xd900, 0xdc00, 0x7a, 0xd800, 0xdc00, 0xdbff, 0xdfff
   1891     };
   1892     static const uint8_t expected_utf8[] = {
   1893         0x41, 0xef, 0xbf, 0xbd, 0x61, 0xef, 0xbf, 0xbd, 0x5a, 0xf1, 0x90, 0x80, 0x80, 0x7a,
   1894         0xf0, 0x90, 0x80, 0x80, 0xf4, 0x8f, 0xbf, 0xbf
   1895     };
   1896     UnicodeString us(FALSE, utf16, LENGTHOF(utf16));
   1897 
   1898     char buffer[64];
   1899     TestCheckedArrayByteSink sink(buffer, (int32_t)sizeof(buffer));
   1900     us.toUTF8(sink);
   1901     if( sink.NumberOfBytesWritten() != (int32_t)sizeof(expected_utf8) ||
   1902         0 != uprv_memcmp(buffer, expected_utf8, sizeof(expected_utf8))
   1903     ) {
   1904         errln("UnicodeString::toUTF8() did not create the expected string.");
   1905     }
   1906     if(!sink.calledFlush) {
   1907         errln("UnicodeString::toUTF8(sink) did not sink.Flush().");
   1908     }
   1909 #if U_HAVE_STD_STRING
   1910     // Initial contents for testing that toUTF8String() appends.
   1911     std::string result8 = "-->";
   1912     std::string expected8 = "-->" + std::string((const char *)expected_utf8, sizeof(expected_utf8));
   1913     // Use the return value just for testing.
   1914     std::string &result8r = us.toUTF8String(result8);
   1915     if(result8r != expected8 || &result8r != &result8) {
   1916         errln("UnicodeString::toUTF8String() did not create the expected string.");
   1917     }
   1918 #endif
   1919 }
   1920 
   1921 // Test if this compiler supports Return Value Optimization of unnamed temporary objects.
   1922 static UnicodeString wrapUChars(const UChar *uchars) {
   1923     return UnicodeString(TRUE, uchars, -1);
   1924 }
   1925 
   1926 void
   1927 UnicodeStringTest::TestReadOnlyAlias() {
   1928     UChar uchars[]={ 0x61, 0x62, 0 };
   1929     UnicodeString alias(TRUE, uchars, 2);
   1930     if(alias.length()!=2 || alias.getBuffer()!=uchars || alias.getTerminatedBuffer()!=uchars) {
   1931         errln("UnicodeString read-only-aliasing constructor does not behave as expected.");
   1932         return;
   1933     }
   1934     alias.truncate(1);
   1935     if(alias.length()!=1 || alias.getBuffer()!=uchars) {
   1936         errln("UnicodeString(read-only-alias).truncate() did not preserve aliasing as expected.");
   1937     }
   1938     if(alias.getTerminatedBuffer()==uchars) {
   1939         errln("UnicodeString(read-only-alias).truncate().getTerminatedBuffer() "
   1940               "did not allocate and copy as expected.");
   1941     }
   1942     if(uchars[1]!=0x62) {
   1943         errln("UnicodeString(read-only-alias).truncate().getTerminatedBuffer() "
   1944               "modified the original buffer.");
   1945     }
   1946     if(1!=u_strlen(alias.getTerminatedBuffer())) {
   1947         errln("UnicodeString(read-only-alias).truncate().getTerminatedBuffer() "
   1948               "does not return a buffer terminated at the proper length.");
   1949     }
   1950 
   1951     alias.setTo(TRUE, uchars, 2);
   1952     if(alias.length()!=2 || alias.getBuffer()!=uchars || alias.getTerminatedBuffer()!=uchars) {
   1953         errln("UnicodeString read-only-aliasing setTo() does not behave as expected.");
   1954         return;
   1955     }
   1956     alias.remove();
   1957     if(alias.length()!=0) {
   1958         errln("UnicodeString(read-only-alias).remove() did not work.");
   1959     }
   1960     if(alias.getTerminatedBuffer()==uchars) {
   1961         errln("UnicodeString(read-only-alias).remove().getTerminatedBuffer() "
   1962               "did not un-alias as expected.");
   1963     }
   1964     if(uchars[0]!=0x61) {
   1965         errln("UnicodeString(read-only-alias).remove().getTerminatedBuffer() "
   1966               "modified the original buffer.");
   1967     }
   1968     if(0!=u_strlen(alias.getTerminatedBuffer())) {
   1969         errln("UnicodeString.setTo(read-only-alias).remove().getTerminatedBuffer() "
   1970               "does not return a buffer terminated at length 0.");
   1971     }
   1972 
   1973     UnicodeString longString=UNICODE_STRING_SIMPLE("abcdefghijklmnopqrstuvwxyz0123456789");
   1974     alias.setTo(FALSE, longString.getBuffer(), longString.length());
   1975     alias.remove(0, 10);
   1976     if(longString.compare(10, INT32_MAX, alias)!=0 || alias.getBuffer()!=longString.getBuffer()+10) {
   1977         errln("UnicodeString.setTo(read-only-alias).remove(0, 10) did not preserve aliasing as expected.");
   1978     }
   1979     alias.setTo(FALSE, longString.getBuffer(), longString.length());
   1980     alias.remove(27, 99);
   1981     if(longString.compare(0, 27, alias)!=0 || alias.getBuffer()!=longString.getBuffer()) {
   1982         errln("UnicodeString.setTo(read-only-alias).remove(27, 99) did not preserve aliasing as expected.");
   1983     }
   1984     alias.setTo(FALSE, longString.getBuffer(), longString.length());
   1985     alias.retainBetween(6, 30);
   1986     if(longString.compare(6, 24, alias)!=0 || alias.getBuffer()!=longString.getBuffer()+6) {
   1987         errln("UnicodeString.setTo(read-only-alias).retainBetween(6, 30) did not preserve aliasing as expected.");
   1988     }
   1989 
   1990     UChar abc[]={ 0x61, 0x62, 0x63, 0 };
   1991     UBool hasRVO= wrapUChars(abc).getBuffer()==abc;
   1992 
   1993     UnicodeString temp;
   1994     temp.fastCopyFrom(longString.tempSubString());
   1995     if(temp!=longString || (hasRVO && temp.getBuffer()!=longString.getBuffer())) {
   1996         errln("UnicodeString.tempSubString() failed");
   1997     }
   1998     temp.fastCopyFrom(longString.tempSubString(-3, 5));
   1999     if(longString.compare(0, 5, temp)!=0 || (hasRVO && temp.getBuffer()!=longString.getBuffer())) {
   2000         errln("UnicodeString.tempSubString(-3, 5) failed");
   2001     }
   2002     temp.fastCopyFrom(longString.tempSubString(17));
   2003     if(longString.compare(17, INT32_MAX, temp)!=0 || (hasRVO && temp.getBuffer()!=longString.getBuffer()+17)) {
   2004         errln("UnicodeString.tempSubString(17) failed");
   2005     }
   2006     temp.fastCopyFrom(longString.tempSubString(99));
   2007     if(!temp.isEmpty()) {
   2008         errln("UnicodeString.tempSubString(99) failed");
   2009     }
   2010     temp.fastCopyFrom(longString.tempSubStringBetween(6));
   2011     if(longString.compare(6, INT32_MAX, temp)!=0 || (hasRVO && temp.getBuffer()!=longString.getBuffer()+6)) {
   2012         errln("UnicodeString.tempSubStringBetween(6) failed");
   2013     }
   2014     temp.fastCopyFrom(longString.tempSubStringBetween(8, 18));
   2015     if(longString.compare(8, 10, temp)!=0 || (hasRVO && temp.getBuffer()!=longString.getBuffer()+8)) {
   2016         errln("UnicodeString.tempSubStringBetween(8, 18) failed");
   2017     }
   2018     UnicodeString bogusString;
   2019     bogusString.setToBogus();
   2020     temp.fastCopyFrom(bogusString.tempSubStringBetween(8, 18));
   2021     if(!temp.isBogus()) {
   2022         errln("UnicodeString.setToBogus().tempSubStringBetween(8, 18) failed");
   2023     }
   2024 }
   2025 
   2026 void
   2027 UnicodeStringTest::doTestAppendable(UnicodeString &dest, Appendable &app) {
   2028     static const UChar cde[3]={ 0x63, 0x64, 0x65 };
   2029     static const UChar fg[3]={ 0x66, 0x67, 0 };
   2030     if(!app.reserveAppendCapacity(12)) {
   2031         errln("Appendable.reserve(12) failed");
   2032     }
   2033     app.appendCodeUnit(0x61);
   2034     app.appendCodePoint(0x62);
   2035     app.appendCodePoint(0x50000);
   2036     app.appendString(cde, 3);
   2037     app.appendString(fg, -1);
   2038     UChar scratch[3];
   2039     int32_t capacity=-1;
   2040     UChar *buffer=app.getAppendBuffer(3, 3, scratch, 3, &capacity);
   2041     if(capacity<3) {
   2042         errln("Appendable.getAppendBuffer(min=3) returned capacity=%d<3", (int)capacity);
   2043         return;
   2044     }
   2045     static const UChar hij[3]={ 0x68, 0x69, 0x6a };
   2046     u_memcpy(buffer, hij, 3);
   2047     app.appendString(buffer, 3);
   2048     if(dest!=UNICODE_STRING_SIMPLE("ab\\U00050000cdefghij").unescape()) {
   2049         errln("Appendable.append(...) failed");
   2050     }
   2051     buffer=app.getAppendBuffer(0, 3, scratch, 3, &capacity);
   2052     if(buffer!=NULL || capacity!=0) {
   2053         errln("Appendable.getAppendBuffer(min=0) failed");
   2054     }
   2055     capacity=1;
   2056     buffer=app.getAppendBuffer(3, 3, scratch, 2, &capacity);
   2057     if(buffer!=NULL || capacity!=0) {
   2058         errln("Appendable.getAppendBuffer(scratch<min) failed");
   2059     }
   2060 }
   2061 
   2062 class SimpleAppendable : public Appendable {
   2063 public:
   2064     explicit SimpleAppendable(UnicodeString &dest) : str(dest) {}
   2065     virtual UBool appendCodeUnit(UChar c) { str.append(c); return TRUE; }
   2066     SimpleAppendable &reset() { str.remove(); return *this; }
   2067 private:
   2068     UnicodeString &str;
   2069 };
   2070 
   2071 void
   2072 UnicodeStringTest::TestAppendable() {
   2073     UnicodeString dest;
   2074     SimpleAppendable app(dest);
   2075     doTestAppendable(dest, app);
   2076 }
   2077 
   2078 void
   2079 UnicodeStringTest::TestUnicodeStringImplementsAppendable() {
   2080     UnicodeString dest;
   2081     UnicodeStringAppendable app(dest);
   2082     doTestAppendable(dest, app);
   2083 }
   2084 
   2085 void
   2086 UnicodeStringTest::TestSizeofUnicodeString() {
   2087     // See the comments in unistr.h near the declaration of UnicodeString's fields.
   2088     size_t sizeofUniStr=sizeof(UnicodeString);
   2089     size_t expected;
   2090     switch(sizeof(void *)) {
   2091     case 4:
   2092         expected=32;
   2093         break;
   2094     case 8:
   2095         expected=40;
   2096         break;
   2097     default:
   2098         logln("This platform has neither 32-bit nor 64-bit pointers.");
   2099         return;
   2100     }
   2101     if(expected!=sizeofUniStr) {
   2102         errln("sizeof(UnicodeString)=%d, expected %d", (int)sizeofUniStr, (int)expected);
   2103     }
   2104 }
   2105