| // © 2016 and later: Unicode, Inc. and others. | 
 | // License & terms of use: http://www.unicode.org/copyright.html | 
 | /************************************************************************ | 
 |  * COPYRIGHT:  | 
 |  * Copyright (c) 2000-2016, International Business Machines Corporation | 
 |  * and others. All Rights Reserved. | 
 |  ************************************************************************/ | 
 | /************************************************************************ | 
 | *   Date        Name        Description | 
 | *   1/03/2000   Madhu        Creation. | 
 | ************************************************************************/ | 
 |  | 
 | #include "unicode/utypes.h" | 
 |  | 
 | #if !UCONFIG_NO_TRANSLITERATION | 
 |  | 
 | #include "ittrans.h" | 
 | #include "transapi.h" | 
 | #include "unicode/utypes.h" | 
 | #include "unicode/translit.h" | 
 | #include "unicode/unifilt.h" | 
 | #include "cpdtrans.h" | 
 | #include "cmemory.h" | 
 | #include <string.h> | 
 | #include <stdio.h> | 
 | #include <stdlib.h> | 
 | #include "unicode/rep.h" | 
 | #include "unicode/locid.h" | 
 | #include "unicode/uniset.h" | 
 |  | 
 | int32_t getInt(UnicodeString str) | 
 | { | 
 |     char buffer[20]; | 
 |     int len=str.length(); | 
 |     if(len>=20) { | 
 |         len=19; | 
 |     } | 
 |     str.extract(0, len, buffer, ""); | 
 |     buffer[len]=0; | 
 |     return atoi(buffer); | 
 | } | 
 |  | 
 | //--------------------------------------------- | 
 | // runIndexedTest | 
 | //--------------------------------------------- | 
 |  | 
 | void | 
 | TransliteratorAPITest::runIndexedTest(int32_t index, UBool exec, | 
 |                                       const char* &name, char* /*par*/) { | 
 |     switch (index) { | 
 |         TESTCASE(0,TestgetInverse); | 
 |         TESTCASE(1,TestgetID); | 
 |         TESTCASE(2,TestGetDisplayName); | 
 |         TESTCASE(3,TestTransliterate1); | 
 |         TESTCASE(4,TestTransliterate2); | 
 |         TESTCASE(5,TestTransliterate3); | 
 |         TESTCASE(6,TestSimpleKeyboardTransliterator); | 
 |         TESTCASE(7,TestKeyboardTransliterator1); | 
 |         TESTCASE(8,TestKeyboardTransliterator2); | 
 |         TESTCASE(9,TestKeyboardTransliterator3); | 
 |         TESTCASE(10,TestGetAdoptFilter); | 
 |         TESTCASE(11,TestClone); | 
 |         TESTCASE(12,TestNullTransliterator); | 
 |         TESTCASE(13,TestRegisterUnregister); | 
 |         TESTCASE(14,TestUnicodeFunctor); | 
 |         default: name = ""; break; | 
 |     } | 
 | } | 
 |  | 
 |  | 
 | void TransliteratorAPITest::TestgetID() { | 
 |     UnicodeString trans="Latin-Greek"; | 
 |     UnicodeString ID; | 
 |     UParseError parseError; | 
 |     UErrorCode status = U_ZERO_ERROR; | 
 |     Transliterator* t= Transliterator::createInstance(trans, UTRANS_FORWARD, parseError, status); | 
 |     if(t==0 || U_FAILURE(status)){ | 
 |         dataerrln("FAIL: construction of Latin-Greek -  %s",u_errorName(status)); | 
 |         return; | 
 |     }else{ | 
 |         ID= t->getID(); | 
 |         if(ID != trans) | 
 |             errln("FAIL: getID returned " + ID + " instead of Latin-Greek"); | 
 |         delete t; | 
 |     } | 
 |     int i; | 
 |     for (i=0; i<Transliterator::countAvailableIDs(); i++){ | 
 |         status = U_ZERO_ERROR; | 
 |         ID = (UnicodeString) Transliterator::getAvailableID(i); | 
 |         if(ID.indexOf("Thai")>-1){ | 
 |             continue; | 
 |         }    | 
 |         t = Transliterator::createInstance(ID, UTRANS_FORWARD, parseError, status); | 
 |         if(t == 0){ | 
 |             errln("FAIL: " + ID); | 
 |             continue; | 
 |         } | 
 |         if(ID != t->getID()) | 
 |             errln("FAIL: getID() returned " + t->getID() + " instead of " + ID); | 
 |         delete t; | 
 |     } | 
 |     ID=(UnicodeString)Transliterator::getAvailableID(i); | 
 |     if(ID != (UnicodeString)Transliterator::getAvailableID(0)){ | 
 |         errln("FAIL: calling getAvailableID(index > coundAvailableIDs) should make index=0\n"); | 
 |     } | 
 |  | 
 |     Transliterator* t1=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); | 
 |     Transliterator* t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORWARD, parseError, status); | 
 |     if(t1 ==0 || t2 == 0){ | 
 |         errln("FAIL: construction"); | 
 |         return; | 
 |     } | 
 |     Transliterator* t3=t1->clone(); | 
 |     Transliterator* t4=t2->clone(); | 
 |  | 
 |     if(t1->getID() != t3->getID() || t2->getID() != t4->getID() ||  | 
 |        t1->getID() == t4->getID() || t2->getID() == t3->getID() ||  | 
 |        t1->getID()== t4->getID() ) | 
 |             errln("FAIL: getID or clone failed"); | 
 |  | 
 |  | 
 |     Transliterator* t5=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); | 
 |     if(t5 == 0) | 
 |         errln("FAIL: construction"); | 
 |     else if(t1->getID() != t5->getID() || t5->getID() != t3->getID() || t1->getID() != t3->getID()) | 
 |         errln("FAIL: getID or clone failed"); | 
 |  | 
 |  | 
 |     delete t1; | 
 |     delete t2; | 
 |     delete t3; | 
 |     delete t4; | 
 |     delete t5; | 
 | } | 
 |  | 
 | void TransliteratorAPITest::TestgetInverse() { | 
 |      UErrorCode status = U_ZERO_ERROR; | 
 |      UParseError parseError; | 
 |      Transliterator* t1    = Transliterator::createInstance("Katakana-Latin", UTRANS_FORWARD, parseError, status); | 
 |      Transliterator* invt1 = Transliterator::createInstance("Latin-Katakana", UTRANS_FORWARD, parseError, status); | 
 |      Transliterator* t2    = Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); | 
 |      Transliterator* invt2 = Transliterator::createInstance("Devanagari-Latin", UTRANS_FORWARD, parseError, status); | 
 |      if(t1 == 0 || invt1 == 0 || t2 == 0 || invt2 == 0) { | 
 |          dataerrln("FAIL: in instantiation - %s", u_errorName(status)); | 
 |          return; | 
 |      } | 
 |  | 
 |      Transliterator* inverse1=t1->createInverse(status); | 
 |      Transliterator* inverse2=t2->createInverse(status); | 
 |      if(inverse1->getID() != invt1->getID() || inverse2->getID() != invt2->getID() | 
 |         || inverse1->getID() == invt2->getID() || inverse2->getID() == invt1->getID() )  | 
 |         errln("FAIL: getInverse() "); | 
 |  | 
 |      UnicodeString TransID[]={ | 
 |        "Halfwidth-Fullwidth", | 
 |        "Fullwidth-Halfwidth", | 
 |        "Greek-Latin" , | 
 |        "Latin-Greek",  | 
 |        //"Arabic-Latin", // removed in 2.0 | 
 |        //"Latin-Arabic", | 
 |        "Katakana-Latin", | 
 |        "Latin-Katakana", | 
 |        //"Hebrew-Latin", // removed in 2.0 | 
 |        //"Latin-Hebrew", | 
 |        "Cyrillic-Latin",  | 
 |        "Latin-Cyrillic",  | 
 |        "Devanagari-Latin",  | 
 |        "Latin-Devanagari",  | 
 |        "Any-Hex", | 
 |        "Hex-Any" | 
 |      }; | 
 |      for(uint32_t i=0; i<UPRV_LENGTHOF(TransID); i=i+2){ | 
 |          Transliterator *trans1=Transliterator::createInstance(TransID[i], UTRANS_FORWARD, parseError, status); | 
 |          if(t1 == 0){ | 
 |            errln("FAIL: in instantiation for" + TransID[i]); | 
 |            continue; | 
 |          } | 
 |          Transliterator *inver1=trans1->createInverse(status); | 
 |          if(inver1->getID() != TransID[i+1] ) | 
 |              errln("FAIL :getInverse() for " + TransID[i] + " returned " + inver1->getID() + " instead of " + TransID[i+1]); | 
 |          delete inver1; | 
 |          delete trans1; | 
 |      } | 
 |      delete t1; | 
 |      delete t2; | 
 |      delete invt1; | 
 |      delete invt2; | 
 |      delete inverse1; | 
 |      delete inverse2; | 
 |  | 
 | } | 
 |  | 
 | void TransliteratorAPITest::TestClone(){ | 
 |     Transliterator *t1, *t2, *t3, *t4; | 
 |     UErrorCode status = U_ZERO_ERROR; | 
 |     UParseError parseError; | 
 |     t1=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); | 
 |     t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORWARD, parseError, status); | 
 |     if(t1 == 0 || t2 == 0){ | 
 |         dataerrln("FAIL: construction - %s", u_errorName(status)); | 
 |         return; | 
 |     } | 
 |     t3=t1->clone(); | 
 |     t4=t2->clone(); | 
 |  | 
 |     if(t1->getID() != t3->getID() || t2->getID() != t4->getID() ) | 
 |         errln("FAIL: clone or getID failed"); | 
 |     if(t1->getID()==t4->getID() || t2->getID()==t3->getID() ||  t1->getID()==t4->getID()) | 
 |         errln("FAIL: clone or getID failed"); | 
 |       | 
 |     delete t1; | 
 |     delete t2; | 
 |     delete t3; | 
 |     delete t4; | 
 |  | 
 | } | 
 |  | 
 | void TransliteratorAPITest::TestGetDisplayName() { | 
 |     UnicodeString dispNames[]= {  | 
 |          //ID, displayName | 
 |         //"CurlyQuotes-StraightQuotes" ,"CurlyQuotes to StraightQuotes", | 
 |           "Any-Hex"                ,"Any to Hex Escape", | 
 |           "Halfwidth-Fullwidth"        ,"Halfwidth to Fullwidth" , | 
 |           //"Latin-Arabic"               ,"Latin to Arabic"      , | 
 |           "Latin-Devanagari"           ,"Latin to Devanagari"  , | 
 |           "Greek-Latin"                ,"Greek to Latin"       , | 
 |           //"Arabic-Latin"               ,"Arabic to Latin"      , | 
 |           "Hex-Any"                ,"Hex Escape to Any", | 
 |           "Cyrillic-Latin"             ,"Cyrillic to Latin"    , | 
 |           "Latin-Greek"                ,"Latin to Greek"       , | 
 |           "Latin-Katakana"                 ,"Latin to Katakana"        , | 
 |           //"Latin-Hebrew"               ,"Latin to Hebrew"      , | 
 |           "Katakana-Latin"                 ,"Katakana to Latin"         | 
 |       }; | 
 |     UnicodeString name=""; | 
 |     Transliterator* t; | 
 |     UnicodeString message; | 
 |     UErrorCode status = U_ZERO_ERROR; | 
 |     UParseError parseError; | 
 |  | 
 | #if UCONFIG_NO_FORMATTING | 
 |     logln("Skipping, UCONFIG_NO_FORMATTING is set\n"); | 
 |     return; | 
 | #else | 
 |  | 
 |     for (uint32_t i=0; i<UPRV_LENGTHOF(dispNames); i=i+2 ) { | 
 |         t = Transliterator::createInstance(dispNames[i+0], UTRANS_FORWARD, parseError, status); | 
 |         if(t==0){ | 
 |              dataerrln("FAIL: construction: " + dispNames[i+0] + " - " + u_errorName(status)); | 
 |              status = U_ZERO_ERROR; | 
 |              continue; | 
 |         } | 
 |         t->getDisplayName(t->getID(), name); | 
 |         message="Display name for ID:" + t->getID(); | 
 |       //  doTest(message, name, dispNames[i+1]); //!!! This will obviously fail for any locale other than english and its children!!! | 
 |         name="";  | 
 |         t->getDisplayName(t->getID(), Locale::getUS(), name); | 
 |         message.remove(); | 
 |         message.append("Display name for on english locale ID:"); | 
 |         message.append(t->getID()); | 
 |     // message="Display name for on english locale ID:" + t->getID(); | 
 |         doTest(message, name, dispNames[i+1]); | 
 |         name=""; | 
 |  | 
 |         delete t; | 
 |     } | 
 | #endif | 
 |  | 
 | } | 
 |  | 
 | void TransliteratorAPITest::TestTransliterate1(){ | 
 |  | 
 |     UnicodeString Data[]={  | 
 |          //ID, input string, transliterated string | 
 |          "Any-Hex",         "hello",    UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", "") , | 
 |          "Hex-Any",         UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""), "hello"  , | 
 |          "Latin-Devanagari",CharsToUnicodeString("bha\\u0304rata"), CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924") , | 
 |          "Latin-Devanagari",UnicodeString("kra ksha khra gra cra dya dhya",""), CharsToUnicodeString("\\u0915\\u094D\\u0930 \\u0915\\u094D\\u0936 \\u0916\\u094D\\u0930 \\u0917\\u094D\\u0930 \\u091a\\u094D\\u0930 \\u0926\\u094D\\u092F \\u0927\\u094D\\u092F") , | 
 |  | 
 |          "Devanagari-Latin",    CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"),        CharsToUnicodeString("bh\\u0101rata"), | 
 |      //  "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"),               CharsToUnicodeString("\\u0041\\u0300\\u0041\\u0301\\u0042") , | 
 |      //  "Expanded-Contracted", CharsToUnicodeString("\\u0041\\u0300\\u0041\\u0301\\u0042"), CharsToUnicodeString("\\u00C0\\u00C1\\u0042") , | 
 |          //"Latin-Arabic",        "aap",                                 CharsToUnicodeString("\\u0627\\u06A4")     , | 
 |          //"Arabic-Latin",        CharsToUnicodeString("\\u0627\\u06A4"),                      "aap"  | 
 |     }; | 
 |  | 
 |     UnicodeString gotResult; | 
 |     UnicodeString temp; | 
 |     UnicodeString message; | 
 |     Transliterator* t; | 
 |     logln("Testing transliterate"); | 
 |     UErrorCode status = U_ZERO_ERROR; | 
 |     UParseError parseError; | 
 |  | 
 |     for(uint32_t i=0;i<UPRV_LENGTHOF(Data); i=i+3){ | 
 |         t=Transliterator::createInstance(Data[i+0], UTRANS_FORWARD, parseError, status); | 
 |         if(t==0){ | 
 |             dataerrln("FAIL: construction: " + Data[i+0] + " Error: "  + u_errorName(status)); | 
 |             dataerrln("PreContext: " + prettify(parseError.preContext) + " PostContext: " + prettify( parseError.postContext) ); | 
 |             status = U_ZERO_ERROR; | 
 |             continue; | 
 |         } | 
 |         gotResult = Data[i+1]; | 
 |         t->transliterate(gotResult); | 
 |         message=t->getID() + "->transliterate(UnicodeString, UnicodeString) for\n\t Source:" + prettify(Data[i+1]); | 
 |         doTest(message, gotResult, Data[i+2]); | 
 |  | 
 |         //doubt here | 
 |         temp=Data[i+1]; | 
 |         t->transliterate(temp); | 
 |         message.remove(); | 
 |         message.append(t->getID()); | 
 |         message.append("->transliterate(Replaceable) for \n\tSource:"); | 
 |         message.append(Data[i][1]); | 
 |         doTest(message, temp, Data[i+2]); | 
 |  | 
 |         callEverything(t, __LINE__); | 
 |         delete t; | 
 |     } | 
 | } | 
 |  | 
 | void TransliteratorAPITest::TestTransliterate2(){ | 
 |      //testing tranliterate(String text, int start, int limit, StringBuffer result) | 
 |    UnicodeString Data2[]={ | 
 |          //ID, input string, start, limit, transliterated string | 
 |          "Any-Hex",         "hello! How are you?",  "0", "5", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""), UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F! How are you?", "") , | 
 |          "Any-Hex",         "hello! How are you?",  "7", "12", UnicodeString("\\u0048\\u006F\\u0077\\u0020\\u0061", ""), UnicodeString("hello! \\u0048\\u006F\\u0077\\u0020\\u0061re you?", ""), | 
 |          "Hex-Any",         CharsToUnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F\\u0021\\u0020"), "0", "5",  "hello", "hello! "  , | 
 |        //  "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"),        "1", "2",  CharsToUnicodeString("\\u0041\\u0301"), CharsToUnicodeString("\\u00C0\\u0041\\u0301\\u0042") , | 
 |          "Devanagari-Latin",    CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), "0", "1",  "bha", CharsToUnicodeString("bha\\u093E\\u0930\\u0924") , | 
 |          "Devanagari-Latin",    CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), "1", "2",  CharsToUnicodeString("\\u0314\\u0101"), CharsToUnicodeString("\\u092D\\u0314\\u0101\\u0930\\u0924")   | 
 |  | 
 |     }; | 
 |     logln("\n   Testing transliterate(String, int, int, StringBuffer)"); | 
 |     Transliterator* t; | 
 |     UnicodeString gotResBuf; | 
 |     UnicodeString temp; | 
 |     int32_t start, limit; | 
 |     UErrorCode status = U_ZERO_ERROR; | 
 |     UParseError parseError; | 
 |  | 
 |     for(uint32_t i=0; i<UPRV_LENGTHOF(Data2); i=i+6){ | 
 |         t=Transliterator::createInstance(Data2[i+0], UTRANS_FORWARD, parseError, status); | 
 |         if(t==0){ | 
 |             dataerrln("FAIL: construction: " + prettify(Data2[i+0]) + " - " + u_errorName(status)); | 
 |             continue; | 
 |         } | 
 |         start=getInt(Data2[i+2]); | 
 |         limit=getInt(Data2[i+3]); | 
 |         Data2[i+1].extractBetween(start, limit, gotResBuf); | 
 |         t->transliterate(gotResBuf); | 
 |         //  errln("FAIL: calling transliterate on " + t->getID()); | 
 |         doTest(t->getID() + ".transliterate(UnicodeString, int32_t, int32_t, UnicodeString):(" + start + "," + limit + ")  for \n\t source: " + prettify(Data2[i+1]), gotResBuf, Data2[i+4]); | 
 |  | 
 |         temp=Data2[i+1]; | 
 |         t->transliterate(temp, start, limit); | 
 |         doTest(t->getID() + ".transliterate(Replaceable, int32_t, int32_t, ):(" + start + "," + limit + ")  for \n\t source: " + prettify(Data2[i+1]), temp, Data2[i+5]); | 
 |         status = U_ZERO_ERROR; | 
 |         callEverything(t, __LINE__); | 
 |         delete t; | 
 |         t = NULL; | 
 |     } | 
 |  | 
 |     status = U_ZERO_ERROR; | 
 |     logln("\n   Try calling transliterate with illegal start and limit values"); | 
 |     t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); | 
 |     if(U_FAILURE(status)) { | 
 |       errln("Error creating transliterator %s", u_errorName(status)); | 
 |       delete t; | 
 |       return; | 
 |     } | 
 |     gotResBuf = temp = "try start greater than limit"; | 
 |     t->transliterate(gotResBuf, 10, 5); | 
 |     if(gotResBuf == temp) { | 
 |         logln("OK: start greater than limit value handled correctly"); | 
 |     } else { | 
 |         errln("FAIL: start greater than limit value returned" + gotResBuf); | 
 |     } | 
 |  | 
 |     callEverything(t, __LINE__); | 
 |     delete t; | 
 |  | 
 | } | 
 | void TransliteratorAPITest::TestTransliterate3(){ | 
 |     UnicodeString rs="This is the replaceable String"; | 
 |     UnicodeString Data[] = { | 
 |         "0",  "0",  "This is the replaceable String", | 
 |         "2",  "3",  UnicodeString("Th\\u0069s is the replaceable String", ""), | 
 |         "21", "23", UnicodeString("Th\\u0069s is the repl\\u0061\\u0063eable String", ""), | 
 |         "14", "17", UnicodeString("Th\\u0069s is t\\u0068\\u0065\\u0020repl\\u0061\\u0063eable String", ""), | 
 |     }; | 
 |     int start, limit; | 
 |     UnicodeString message; | 
 |     UParseError parseError; | 
 |     UErrorCode status = U_ZERO_ERROR; | 
 |     Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); | 
 |     if(U_FAILURE(status)) { | 
 |       errln("Error creating transliterator %s", u_errorName(status)); | 
 |       delete t; | 
 |       return; | 
 |     } | 
 |  | 
 |     if(t == 0) | 
 |         errln("FAIL : construction"); | 
 |     for(uint32_t i=0; i<UPRV_LENGTHOF(Data); i=i+3){ | 
 |         start=getInt(Data[i+0]); | 
 |         limit=getInt(Data[i+1]); | 
 |         t->transliterate(rs, start, limit); | 
 |         message=t->getID() + ".transliterate(ReplaceableString, start, limit):("+start+","+limit+"):"; | 
 |         doTest(message, rs, Data[i+2]);  | 
 |     } | 
 |     delete t; | 
 | } | 
 |  | 
 | void TransliteratorAPITest::TestSimpleKeyboardTransliterator(){ | 
 |     logln("simple call to transliterate"); | 
 |     UErrorCode status=U_ZERO_ERROR; | 
 |     UParseError parseError; | 
 |     Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); | 
 |     if(t == 0) { | 
 |         UnicodeString context; | 
 |  | 
 |         if (parseError.preContext[0]) { | 
 |             context += (UnicodeString)" at " + parseError.preContext; | 
 |         } | 
 |         if (parseError.postContext[0]) { | 
 |             context += (UnicodeString)" | " + parseError.postContext; | 
 |         } | 
 |         errln((UnicodeString)"FAIL: can't create Any-Hex, " + | 
 |               (UnicodeString)u_errorName(status) + context); | 
 |         return; | 
 |     } | 
 |     UTransPosition index={19,20,20,20}; | 
 |     UnicodeString rs= "Transliterate this-''"; | 
 |     UnicodeString insertion="abc"; | 
 |     UnicodeString expected=UnicodeString("Transliterate this-'\\u0061\\u0062\\u0063'", ""); | 
 |     t->transliterate(rs, index, insertion, status); | 
 |     if(U_FAILURE(status)) | 
 |         errln("FAIL: " + t->getID()+ ".translitere(Replaceable, int[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status)); | 
 |     t->finishTransliteration(rs, index); | 
 |     UnicodeString message="transliterate"; | 
 |     doTest(message, rs, expected); | 
 |  | 
 |     logln("try calling transliterate with invalid index values"); | 
 |     UTransPosition index1[]={ | 
 |         //START, LIMIT, CURSOR | 
 |         {10, 10, 12, 10},   //invalid since CURSOR>LIMIT valid:-START <= CURSOR <= LIMIT | 
 |         {17, 16, 17, 17},   //invalid since START>LIMIT valid:-0<=START<=LIMIT | 
 |         {-1, 16, 14, 16},   //invalid since START<0 | 
 |         {3,  50, 2,  50}    //invalid since LIMIT>text.length() | 
 |     }; | 
 |     for(uint32_t i=0; i<UPRV_LENGTHOF(index1); i++){ | 
 |         status=U_ZERO_ERROR; | 
 |         t->transliterate(rs, index1[i], insertion, status); | 
 |         if(status == U_ILLEGAL_ARGUMENT_ERROR) | 
 |             logln("OK: invalid index values handled correctly"); | 
 |         else | 
 |             errln("FAIL: invalid index values didn't throw U_ILLEGAL_ARGUMENT_ERROR throw" + (UnicodeString)u_errorName(status)); | 
 |     } | 
 |  | 
 |     delete t; | 
 | } | 
 | void TransliteratorAPITest::TestKeyboardTransliterator1(){ | 
 |     UnicodeString Data[]={ | 
 |         //insertion, buffer | 
 |         "a",   UnicodeString("\\u0061", "")                                           , | 
 |         "bbb", UnicodeString("\\u0061\\u0062\\u0062\\u0062", "")                      , | 
 |         "ca",  UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061", "")        , | 
 |         " ",   UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020", "") , | 
 |         "",    UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020", "")   , | 
 |  | 
 |         "a",   UnicodeString("\\u0061", "")                                           , | 
 |         "b",   UnicodeString("\\u0061\\u0062", "")                                    , | 
 |         "z",   UnicodeString("\\u0061\\u0062\\u007A", "")                             , | 
 |         "",    UnicodeString("\\u0061\\u0062\\u007A", "")                               | 
 |  | 
 |     }; | 
 |     UParseError parseError; | 
 |     UErrorCode status = U_ZERO_ERROR; | 
 |     Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); | 
 |     if(U_FAILURE(status)) { | 
 |       errln("Error creating transliterator %s", u_errorName(status)); | 
 |       delete t; | 
 |       return; | 
 |     } | 
 |     //keyboardAux(t, Data); | 
 |     UTransPosition index={0, 0, 0, 0}; | 
 |     UnicodeString s; | 
 |     uint32_t i; | 
 |     logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)"); | 
 |     for (i=0; i<10; i=i+2) { | 
 |        UnicodeString log; | 
 |        if (Data[i+0] != "") { | 
 |            log = s + " + " + Data[i+0] + " -> "; | 
 |            t->transliterate(s, index, Data[i+0], status); | 
 |            if(U_FAILURE(status)){ | 
 |                errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status)); | 
 |            continue; | 
 |            } | 
 |        }else { | 
 |            log = s + " => "; | 
 |            t->finishTransliteration(s, index); | 
 |        } | 
 |        // Show the start index '{' and the cursor '|' | 
 |        displayOutput(s, Data[i+1], log, index); | 
 |             | 
 |     } | 
 |      | 
 |     s=""; | 
 |     status=U_ZERO_ERROR; | 
 |     index.contextStart = index.contextLimit = index.start = index.limit = 0; | 
 |     logln("Testing transliterate(Replaceable, int32_t, UChar, UErrorCode)"); | 
 |     for(i=10; i<UPRV_LENGTHOF(Data); i=i+2){ | 
 |         UnicodeString log; | 
 |         if (Data[i+0] != "") { | 
 |             log = s + " + " + Data[i+0] + " -> "; | 
 |             UChar c=Data[i+0].charAt(0); | 
 |             t->transliterate(s, index, c, status); | 
 |             if(U_FAILURE(status)) { | 
 |                errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UChar, UErrorCode)-->" + (UnicodeString)u_errorName(status)); | 
 |                continue; | 
 |             } | 
 |         } else { | 
 |            log = s + " => "; | 
 |            t->finishTransliteration(s, index); | 
 |         } | 
 |         // Show the start index '{' and the cursor '|' | 
 |         displayOutput(s, Data[i+1], log, index);  | 
 |     } | 
 |  | 
 |     delete t; | 
 | } | 
 |  | 
 | void TransliteratorAPITest::TestKeyboardTransliterator2(){ | 
 |     UnicodeString Data[]={ | 
 |         //insertion, buffer, index[START], index[LIMIT], index[CURSOR] | 
 |         //data for Any-Hex | 
 |         "abc",    UnicodeString("Initial String: add-\\u0061\\u0062\\u0063-", ""),                     "19", "20", "20", | 
 |         "a",      UnicodeString("In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""),        "2",  "3",  "2" , | 
 |         "b",      UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0",  "0",  "0" , | 
 |         "",       UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0",  "0",  "0" , | 
 |         //data for Latin-Devanagiri | 
 |         CharsToUnicodeString("a\\u0304"),     CharsToUnicodeString("Hindi -\\u0906-"),                            "6", "7", "6", | 
 |         CharsToUnicodeString("ma\\u0304"),    CharsToUnicodeString("Hindi -\\u0906\\u092E\\u093E-"),              "7", "8", "7", | 
 |         CharsToUnicodeString("ra\\u0304"),    CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2", | 
 |         CharsToUnicodeString(""),       CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2" | 
 |         //data for contracted-Expanded | 
 |      //   CharsToUnicodeString("\\u00C1"), CharsToUnicodeString("Ad\\u0041\\u0301d here:"),             "1",  "2",  "1" , | 
 |      //   CharsToUnicodeString("\\u00C0"), CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11", | 
 |      //   "",     CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11", | 
 |     }; | 
 |     Transliterator *t; | 
 |     UnicodeString rs; | 
 |     UnicodeString dataStr; | 
 |     logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)");        | 
 |     UErrorCode status = U_ZERO_ERROR; | 
 |     UParseError parseError; | 
 |     rs="Initial String: add--"; | 
 |     t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); | 
 |     if(t == 0) | 
 |         dataerrln("FAIL : construction - %s", u_errorName(status)); | 
 |     else { | 
 |         keyboardAux(t, Data, rs, 0, 20); | 
 |         delete t; | 
 |     } | 
 |  | 
 |     rs="Hindi --"; | 
 |     t=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); | 
 |     if(t == 0) | 
 |         dataerrln("FAIL : construction - %s", u_errorName(status)); | 
 |     else | 
 |         keyboardAux(t, Data, rs, 20, 40); | 
 |  | 
 |  | 
 |   //  rs="Add here:"; | 
 |  //   t=Transliterator::createInstance("Contracted-Expanded"); | 
 |  //   keyboardAux(t, Data, rs, 35, 55); | 
 |  | 
 |  | 
 |     delete t; | 
 | } | 
 |  | 
 | void TransliteratorAPITest::TestKeyboardTransliterator3(){ | 
 |     UnicodeString s="This is the main string"; | 
 |     UnicodeString Data[] = { | 
 |         "0", "0", "0",  "This is the main string", | 
 |         "1", "3", "2",  UnicodeString("Th\\u0069s is the main string", ""), | 
 |         "20", "21", "20",  UnicodeString("Th\\u0069s is the mai\\u006E string", "") | 
 |     }; | 
 |  | 
 |     UErrorCode status=U_ZERO_ERROR; | 
 |     UParseError parseError; | 
 |     UTransPosition index={0, 0, 0, 0}; | 
 |     logln("Testing transliterate(Replaceable, int32_t, UErrorCode)"); | 
 |     Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); | 
 |     if(t == 0 || U_FAILURE(status)) { | 
 |       errln("Error creating transliterator %s", u_errorName(status)); | 
 |       delete t; | 
 |       return; | 
 |     } | 
 |     for(uint32_t i=0; i<UPRV_LENGTHOF(Data); i=i+4){ | 
 |         UnicodeString log; | 
 |         index.contextStart=getInt(Data[i+0]); | 
 |         index.contextLimit=index.limit=getInt(Data[i+1]); | 
 |         index.start=getInt(Data[i+2]); | 
 |         t->transliterate(s, index, status); | 
 |         if(U_FAILURE(status)){ | 
 |            errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UErrorCode)-->" + (UnicodeString)u_errorName(status)); | 
 |            continue; | 
 |         } | 
 |         t->finishTransliteration(s, index); | 
 |         log = s + " => "; | 
 |         // Show the start index '{' and the cursor '|' | 
 |         displayOutput(s, Data[i+3], log, index);  | 
 |     } | 
 |  | 
 |     delete t; | 
 | } | 
 | void TransliteratorAPITest::TestNullTransliterator(){ | 
 |     UErrorCode status=U_ZERO_ERROR; | 
 |     UnicodeString s("Transliterate using null transliterator"); | 
 |     Transliterator *nullTrans=Transliterator::createInstance("Any-Null", UTRANS_FORWARD, status); | 
 |     int32_t transLimit; | 
 |     int32_t start=0; | 
 |     int32_t limit=s.length(); | 
 |     UnicodeString replaceable=s; | 
 |     transLimit=nullTrans->transliterate(replaceable, start, limit); | 
 |     if(transLimit != limit){ | 
 |         errln("ERROR: NullTransliterator->transliterate() failed"); | 
 |     } | 
 |     doTest((UnicodeString)"nulTrans->transliterate", replaceable, s); | 
 |     replaceable.remove(); | 
 |     replaceable.append(s); | 
 |     UTransPosition index; | 
 |     index.contextStart =start; | 
 |     index.contextLimit = limit; | 
 |     index.start = 0; | 
 |     index.limit = limit; | 
 |     nullTrans->finishTransliteration(replaceable, index); | 
 |     if(index.start != limit){ | 
 |         errln("ERROR: NullTransliterator->handleTransliterate() failed"); | 
 |     } | 
 |     doTest((UnicodeString)"NullTransliterator->handleTransliterate", replaceable, s); | 
 |     callEverything(nullTrans, __LINE__); | 
 |     delete nullTrans; | 
 |  | 
 |      | 
 | } | 
 | void TransliteratorAPITest::TestRegisterUnregister(){ | 
 |     | 
 |    UErrorCode status=U_ZERO_ERROR; | 
 |     /* Make sure it doesn't exist */ | 
 |    if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) { | 
 |       errln("FAIL: TestA-TestB already registered\n"); | 
 |       return; | 
 |    } | 
 |    /* Check inverse too  | 
 |    if (Transliterator::createInstance("TestA-TestB", | 
 |                                       (UTransDirection)UTRANS_REVERSE) != NULL) { | 
 |       errln("FAIL: TestA-TestB inverse already registered\n"); | 
 |       return; | 
 |    } | 
 |    */ | 
 |    status =U_ZERO_ERROR; | 
 |  | 
 |    /* Create it */ | 
 |    UParseError parseError; | 
 |    Transliterator *t = Transliterator::createFromRules("TestA-TestB", | 
 |                                                    "a<>b", | 
 |                                                    UTRANS_FORWARD, parseError, | 
 |                                                    status); | 
 |    /* Register it */ | 
 |    Transliterator::registerInstance(t); | 
 |  | 
 |    /* Now check again -- should exist now*/ | 
 |    Transliterator *s = Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status); | 
 |    if (s == NULL) { | 
 |       errln("FAIL: TestA-TestB not registered\n"); | 
 |       return; | 
 |    } | 
 |    callEverything(s, __LINE__); | 
 |    callEverything(t, __LINE__); | 
 |    delete s; | 
 |     | 
 |    /* Check inverse too | 
 |    s = Transliterator::createInstance("TestA-TestB", | 
 |                                       (UTransDirection)UTRANS_REVERSE); | 
 |    if (s == NULL) { | 
 |       errln("FAIL: TestA-TestB inverse not registered\n"); | 
 |       return; | 
 |    } | 
 |    delete s; | 
 |    */ | 
 |     | 
 |    /*unregister the instance*/ | 
 |    Transliterator::unregister("TestA-TestB"); | 
 |    /* now Make sure it doesn't exist */ | 
 |    if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) { | 
 |       errln("FAIL: TestA-TestB isn't unregistered\n"); | 
 |       return; | 
 |    } | 
 |  | 
 | } | 
 |  | 
 |  | 
 | int gTestFilter1ClassID = 0; | 
 | int gTestFilter2ClassID = 0; | 
 | int gTestFilter3ClassID = 0; | 
 |  | 
 | /** | 
 |  * Used by TestFiltering(). | 
 |  */ | 
 | class TestFilter1 : public UnicodeFilter { | 
 |     UClassID getDynamicClassID()const { return &gTestFilter1ClassID; } | 
 |     virtual TestFilter1* clone() const { | 
 |         return new TestFilter1(*this); | 
 |     } | 
 |     virtual UBool contains(UChar32 c) const { | 
 |        if(c==0x63 || c==0x61 || c==0x43 || c==0x41) | 
 |           return FALSE; | 
 |        else | 
 |           return TRUE; | 
 |     } | 
 |     // Stubs | 
 |     virtual UnicodeString& toPattern(UnicodeString& result, | 
 |                                      UBool /*escapeUnprintable*/) const { | 
 |         return result; | 
 |     } | 
 |     virtual UBool matchesIndexValue(uint8_t /*v*/) const { | 
 |         return FALSE; | 
 |     } | 
 |     virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} | 
 | }; | 
 | class TestFilter2 : public UnicodeFilter { | 
 |     UClassID getDynamicClassID()const { return &gTestFilter2ClassID; } | 
 |     virtual TestFilter2* clone() const { | 
 |         return new TestFilter2(*this); | 
 |     } | 
 |     virtual UBool contains(UChar32 c) const { | 
 |         if(c==0x65 || c==0x6c) | 
 |            return FALSE; | 
 |         else | 
 |            return TRUE; | 
 |     } | 
 |     // Stubs | 
 |     virtual UnicodeString& toPattern(UnicodeString& result, | 
 |                                      UBool /*escapeUnprintable*/) const { | 
 |         return result; | 
 |     } | 
 |     virtual UBool matchesIndexValue(uint8_t /*v*/) const { | 
 |         return FALSE; | 
 |     } | 
 |     virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} | 
 | }; | 
 | class TestFilter3 : public UnicodeFilter { | 
 |     UClassID getDynamicClassID()const { return &gTestFilter3ClassID; } | 
 |     virtual TestFilter3* clone() const { | 
 |         return new TestFilter3(*this); | 
 |     } | 
 |     virtual UBool contains(UChar32 c) const { | 
 |         if(c==0x6f || c==0x77) | 
 |            return FALSE; | 
 |         else | 
 |            return TRUE; | 
 |     } | 
 |     // Stubs | 
 |     virtual UnicodeString& toPattern(UnicodeString& result, | 
 |                                      UBool /*escapeUnprintable*/) const { | 
 |         return result; | 
 |     } | 
 |     virtual UBool matchesIndexValue(uint8_t /*v*/) const { | 
 |         return FALSE; | 
 |     } | 
 |     virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} | 
 | }; | 
 |  | 
 |  | 
 | void TransliteratorAPITest::TestGetAdoptFilter(){ | 
 |     UErrorCode status = U_ZERO_ERROR; | 
 |     UParseError parseError; | 
 |     Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); | 
 |     if(t == 0 || U_FAILURE(status)) { | 
 |         errln("Error creating transliterator %s", u_errorName(status)); | 
 |         delete t; | 
 |         return; | 
 |     } | 
 |     const UnicodeFilter *u=t->getFilter(); | 
 |     if(u != NULL){ | 
 |         errln("FAIL: getFilter failed. Didn't return null when the transliterator used no filtering"); | 
 |         delete t; | 
 |         return; | 
 |     } | 
 |  | 
 |     UnicodeString got, temp, message; | 
 |     UnicodeString data="ABCabcbbCBa"; | 
 |     temp = data; | 
 |     t->transliterate(temp); | 
 |     t->adoptFilter(new TestFilter1); | 
 |  | 
 |     got = data; | 
 |     t->transliterate(got); | 
 |     UnicodeString exp=UnicodeString("A\\u0042Ca\\u0062c\\u0062\\u0062C\\u0042a", ""); | 
 |     message="transliteration after adoptFilter(a,A,c,C) "; | 
 |     doTest(message, got, exp); | 
 |           | 
 |     logln("Testing round trip"); | 
 |     t->adoptFilter((UnicodeFilter*)u); | 
 |     if(t->getFilter() == NULL) | 
 |        logln("OK: adoptFilter and getFilter round trip worked"); | 
 |     else | 
 |        errln("FAIL: adoptFilter or getFilter round trip failed");   | 
 |  | 
 |     got = data; | 
 |     t->transliterate(got); | 
 |     exp=UnicodeString("\\u0041\\u0042\\u0043\\u0061\\u0062\\u0063\\u0062\\u0062\\u0043\\u0042\\u0061", ""); | 
 |     message="transliteration after adopting null filter"; | 
 |     doTest(message, got, exp); | 
 |     message="adoptFilter round trip";  | 
 |     doTest("adoptFilter round trip", got, temp); | 
 |  | 
 |     t->adoptFilter(new TestFilter2); | 
 |     callEverything(t, __LINE__); | 
 |     data="heelloe"; | 
 |     exp=UnicodeString("\\u0068eell\\u006Fe", ""); | 
 |     got = data; | 
 |     t->transliterate(got); | 
 |     message="transliteration using (e,l) filter"; | 
 |     doTest("transliteration using (e,l) filter", got, exp); | 
 |  | 
 |     data="are well"; | 
 |     exp=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", ""); | 
 |     got = data; | 
 |     t->transliterate(got); | 
 |     doTest(message, got, exp); | 
 |  | 
 |     t->adoptFilter(new TestFilter3); | 
 |     data="ho, wow!"; | 
 |     exp=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", ""); | 
 |     got = data; | 
 |     t->transliterate(got); | 
 |     message="transliteration using (o,w) filter"; | 
 |     doTest("transliteration using (o,w) filter", got, exp); | 
 |  | 
 |     data="owl"; | 
 |     exp=UnicodeString("ow\\u006C", ""); | 
 |     got = data; | 
 |     t->transliterate(got); | 
 |     doTest("transliteration using (o,w) filter", got, exp); | 
 |  | 
 |     delete t; | 
 |  | 
 | } | 
 |  | 
 |  | 
 |  | 
 | void TransliteratorAPITest::keyboardAux(Transliterator *t, UnicodeString DATA[], UnicodeString& s, int32_t begin, int32_t end) { | 
 |     UTransPosition index={0, 0, 0, 0}; | 
 |     UErrorCode status=U_ZERO_ERROR; | 
 |     for (int32_t i=begin; i<end; i=i+5) { | 
 |         UnicodeString log; | 
 |         if (DATA[i+0] != "") { | 
 |              log = s + " + " + DATA[i] + " -> "; | 
 |              index.contextStart=getInt(DATA[i+2]); | 
 |              index.contextLimit=index.limit=getInt(DATA[i+3]); | 
 |              index.start=getInt(DATA[i+4]); | 
 |              t->transliterate(s, index, DATA[i+0], status); | 
 |              if(U_FAILURE(status)){ | 
 |                  errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status)); | 
 |              continue; | 
 |              } | 
 |            log = s + " => "; | 
 |            t->finishTransliteration(s, index); | 
 |         } | 
 |          // Show the start index '{' and the cursor '|' | 
 |       displayOutput(s, DATA[i+1], log, index); | 
 |          | 
 |     } | 
 | } | 
 |  | 
 | void TransliteratorAPITest::displayOutput(const UnicodeString& got, const UnicodeString& expected, UnicodeString& log, UTransPosition& index){ | 
 |  // Show the start index '{' and the cursor '|' | 
 |     UnicodeString a, b, c, d, e; | 
 |     got.extractBetween(0, index.contextStart, a); | 
 |     got.extractBetween(index.contextStart, index.start, b); | 
 |     got.extractBetween(index.start, index.limit, c); | 
 |     got.extractBetween(index.limit, index.contextLimit, d); | 
 |     got.extractBetween(index.contextLimit, got.length(), e); | 
 |     log.append(a). | 
 |         append((UChar)0x7b/*{*/). | 
 |         append(b). | 
 |         append((UChar)0x7c/*|*/). | 
 |         append(c). | 
 |         append((UChar)0x7c). | 
 |         append(d). | 
 |         append((UChar)0x7d/*}*/). | 
 |         append(e); | 
 |     if (got == expected)  | 
 |         logln("OK:" + prettify(log)); | 
 |     else  | 
 |         errln("FAIL: " + prettify(log)  + ", expected " + prettify(expected)); | 
 | } | 
 |  | 
 |  | 
 | /*Internal Functions used*/ | 
 | void TransliteratorAPITest::doTest(const UnicodeString& message, const UnicodeString& result, const UnicodeString& expected){ | 
 |     if (prettify(result) == prettify(expected))  | 
 |         logln((UnicodeString)"Ok: " + prettify(message) + " passed \"" + prettify(expected) + "\""); | 
 |     else  | 
 |         dataerrln((UnicodeString)"FAIL:" + message + " failed  Got-->" + prettify(result)+ ", Expected--> " + prettify(expected) ); | 
 | } | 
 |  | 
 |  | 
 | // | 
 | //  callEverything    call all of the const (non-destructive) methods on a | 
 | //                    transliterator, just to verify that they don't fail in some | 
 | //                    destructive way. | 
 | // | 
 | #define CEASSERT(a) UPRV_BLOCK_MACRO_BEGIN { \ | 
 |     if (!(a)) { \ | 
 |         errln("FAIL at line %d from line %d: %s", __LINE__, line, #a); \ | 
 |         return; \ | 
 |     } \ | 
 | } UPRV_BLOCK_MACRO_END | 
 |  | 
 | void TransliteratorAPITest::callEverything(const Transliterator *tr, int line) { | 
 |     Transliterator *clonedTR = tr->clone(); | 
 |     CEASSERT(clonedTR != NULL); | 
 |  | 
 |     int32_t  maxcl = tr->getMaximumContextLength(); | 
 |     CEASSERT(clonedTR->getMaximumContextLength() == maxcl); | 
 |  | 
 |     UnicodeString id; | 
 |     UnicodeString clonedId; | 
 |     id = tr->getID(); | 
 |     clonedId = clonedTR->getID(); | 
 |     CEASSERT(id == clonedId); | 
 |  | 
 |     const UnicodeFilter *filter = tr->getFilter(); | 
 |     const UnicodeFilter *clonedFilter = clonedTR->getFilter(); | 
 |     if (filter == NULL || clonedFilter == NULL) { | 
 |         // If one filter is NULL they better both be NULL. | 
 |         CEASSERT(filter == clonedFilter); | 
 |     } else { | 
 |         CEASSERT(filter != clonedFilter); | 
 |     } | 
 |  | 
 |     UnicodeString rules; | 
 |     UnicodeString clonedRules; | 
 |     rules = tr->toRules(rules, FALSE); | 
 |     clonedRules = clonedTR->toRules(clonedRules, FALSE); | 
 |     CEASSERT(rules == clonedRules); | 
 |  | 
 |     UnicodeSet sourceSet; | 
 |     UnicodeSet clonedSourceSet; | 
 |     tr->getSourceSet(sourceSet); | 
 |     clonedTR->getSourceSet(clonedSourceSet); | 
 |     CEASSERT(clonedSourceSet == sourceSet); | 
 |  | 
 |     UnicodeSet targetSet; | 
 |     UnicodeSet clonedTargetSet; | 
 |     tr->getTargetSet(targetSet); | 
 |     clonedTR->getTargetSet(clonedTargetSet); | 
 |     CEASSERT(targetSet == clonedTargetSet); | 
 |  | 
 |     UClassID classID = tr->getDynamicClassID(); | 
 |     CEASSERT(classID == clonedTR->getDynamicClassID()); | 
 |     CEASSERT(classID != 0); | 
 |  | 
 |     delete clonedTR; | 
 | } | 
 |  | 
 | static const int MyUnicodeFunctorTestClassID = 0; | 
 | class MyUnicodeFunctorTestClass : public UnicodeFunctor { | 
 | public: | 
 |     virtual UnicodeFunctor* clone() const {return NULL;} | 
 |     static UClassID getStaticClassID(void) {return (UClassID)&MyUnicodeFunctorTestClassID;} | 
 |     virtual UClassID getDynamicClassID(void) const {return getStaticClassID();} | 
 |     virtual void setData(const TransliterationRuleData*) {} | 
 | }; | 
 |  | 
 | void TransliteratorAPITest::TestUnicodeFunctor() { | 
 |     MyUnicodeFunctorTestClass myClass; | 
 |     if (myClass.toMatcher() != NULL) { | 
 |         errln("FAIL: UnicodeFunctor::toMatcher did not return NULL"); | 
 |     } | 
 |     if (myClass.toReplacer() != NULL) { | 
 |         errln("FAIL: UnicodeFunctor::toReplacer did not return NULL"); | 
 |     } | 
 | } | 
 |  | 
 |  | 
 | #endif /* #if !UCONFIG_NO_TRANSLITERATION */ |