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