1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /************************************************************************ 4 * COPYRIGHT: 5 * Copyright (c) 2000-2016, International Business Machines Corporation 6 * and others. All Rights Reserved. 7 ************************************************************************/ 8 /************************************************************************ 9 * Date Name Description 10 * 1/03/2000 Madhu Creation. 11 ************************************************************************/ 12 13 #include "unicode/utypes.h" 14 15 #if !UCONFIG_NO_TRANSLITERATION 16 17 #include "ittrans.h" 18 #include "transapi.h" 19 #include "unicode/utypes.h" 20 #include "unicode/translit.h" 21 #include "unicode/unifilt.h" 22 #include "cpdtrans.h" 23 #include "cmemory.h" 24 #include <string.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include "unicode/rep.h" 28 #include "unicode/locid.h" 29 #include "unicode/uniset.h" 30 31 int32_t getInt(UnicodeString str) 32 { 33 char buffer[20]; 34 int len=str.length(); 35 if(len>=20) { 36 len=19; 37 } 38 str.extract(0, len, buffer, ""); 39 buffer[len]=0; 40 return atoi(buffer); 41 } 42 43 //--------------------------------------------- 44 // runIndexedTest 45 //--------------------------------------------- 46 47 void 48 TransliteratorAPITest::runIndexedTest(int32_t index, UBool exec, 49 const char* &name, char* /*par*/) { 50 switch (index) { 51 TESTCASE(0,TestgetInverse); 52 TESTCASE(1,TestgetID); 53 TESTCASE(2,TestGetDisplayName); 54 TESTCASE(3,TestTransliterate1); 55 TESTCASE(4,TestTransliterate2); 56 TESTCASE(5,TestTransliterate3); 57 TESTCASE(6,TestSimpleKeyboardTransliterator); 58 TESTCASE(7,TestKeyboardTransliterator1); 59 TESTCASE(8,TestKeyboardTransliterator2); 60 TESTCASE(9,TestKeyboardTransliterator3); 61 TESTCASE(10,TestGetAdoptFilter); 62 TESTCASE(11,TestClone); 63 TESTCASE(12,TestNullTransliterator); 64 TESTCASE(13,TestRegisterUnregister); 65 TESTCASE(14,TestUnicodeFunctor); 66 default: name = ""; break; 67 } 68 } 69 70 71 void TransliteratorAPITest::TestgetID() { 72 UnicodeString trans="Latin-Greek"; 73 UnicodeString ID; 74 UParseError parseError; 75 UErrorCode status = U_ZERO_ERROR; 76 Transliterator* t= Transliterator::createInstance(trans, UTRANS_FORWARD, parseError, status); 77 if(t==0 || U_FAILURE(status)){ 78 dataerrln("FAIL: construction of Latin-Greek - %s",u_errorName(status)); 79 return; 80 }else{ 81 ID= t->getID(); 82 if(ID != trans) 83 errln("FAIL: getID returned " + ID + " instead of Latin-Greek"); 84 delete t; 85 } 86 int i; 87 for (i=0; i<Transliterator::countAvailableIDs(); i++){ 88 status = U_ZERO_ERROR; 89 ID = (UnicodeString) Transliterator::getAvailableID(i); 90 if(ID.indexOf("Thai")>-1){ 91 continue; 92 } 93 t = Transliterator::createInstance(ID, UTRANS_FORWARD, parseError, status); 94 if(t == 0){ 95 errln("FAIL: " + ID); 96 continue; 97 } 98 if(ID != t->getID()) 99 errln("FAIL: getID() returned " + t->getID() + " instead of " + ID); 100 delete t; 101 } 102 ID=(UnicodeString)Transliterator::getAvailableID(i); 103 if(ID != (UnicodeString)Transliterator::getAvailableID(0)){ 104 errln("FAIL: calling getAvailableID(index > coundAvailableIDs) should make index=0\n"); 105 } 106 107 Transliterator* t1=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); 108 Transliterator* t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORWARD, parseError, status); 109 if(t1 ==0 || t2 == 0){ 110 errln("FAIL: construction"); 111 return; 112 } 113 Transliterator* t3=t1->clone(); 114 Transliterator* t4=t2->clone(); 115 116 if(t1->getID() != t3->getID() || t2->getID() != t4->getID() || 117 t1->getID() == t4->getID() || t2->getID() == t3->getID() || 118 t1->getID()== t4->getID() ) 119 errln("FAIL: getID or clone failed"); 120 121 122 Transliterator* t5=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); 123 if(t5 == 0) 124 errln("FAIL: construction"); 125 else if(t1->getID() != t5->getID() || t5->getID() != t3->getID() || t1->getID() != t3->getID()) 126 errln("FAIL: getID or clone failed"); 127 128 129 delete t1; 130 delete t2; 131 delete t3; 132 delete t4; 133 delete t5; 134 } 135 136 void TransliteratorAPITest::TestgetInverse() { 137 UErrorCode status = U_ZERO_ERROR; 138 UParseError parseError; 139 Transliterator* t1 = Transliterator::createInstance("Katakana-Latin", UTRANS_FORWARD, parseError, status); 140 Transliterator* invt1 = Transliterator::createInstance("Latin-Katakana", UTRANS_FORWARD, parseError, status); 141 Transliterator* t2 = Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); 142 Transliterator* invt2 = Transliterator::createInstance("Devanagari-Latin", UTRANS_FORWARD, parseError, status); 143 if(t1 == 0 || invt1 == 0 || t2 == 0 || invt2 == 0) { 144 dataerrln("FAIL: in instantiation - %s", u_errorName(status)); 145 return; 146 } 147 148 Transliterator* inverse1=t1->createInverse(status); 149 Transliterator* inverse2=t2->createInverse(status); 150 if(inverse1->getID() != invt1->getID() || inverse2->getID() != invt2->getID() 151 || inverse1->getID() == invt2->getID() || inverse2->getID() == invt1->getID() ) 152 errln("FAIL: getInverse() "); 153 154 UnicodeString TransID[]={ 155 "Halfwidth-Fullwidth", 156 "Fullwidth-Halfwidth", 157 "Greek-Latin" , 158 "Latin-Greek", 159 //"Arabic-Latin", // removed in 2.0 160 //"Latin-Arabic", 161 "Katakana-Latin", 162 "Latin-Katakana", 163 //"Hebrew-Latin", // removed in 2.0 164 //"Latin-Hebrew", 165 "Cyrillic-Latin", 166 "Latin-Cyrillic", 167 "Devanagari-Latin", 168 "Latin-Devanagari", 169 "Any-Hex", 170 "Hex-Any" 171 }; 172 for(uint32_t i=0; i<UPRV_LENGTHOF(TransID); i=i+2){ 173 Transliterator *trans1=Transliterator::createInstance(TransID[i], UTRANS_FORWARD, parseError, status); 174 if(t1 == 0){ 175 errln("FAIL: in instantiation for" + TransID[i]); 176 continue; 177 } 178 Transliterator *inver1=trans1->createInverse(status); 179 if(inver1->getID() != TransID[i+1] ) 180 errln("FAIL :getInverse() for " + TransID[i] + " returned " + inver1->getID() + " instead of " + TransID[i+1]); 181 delete inver1; 182 delete trans1; 183 } 184 delete t1; 185 delete t2; 186 delete invt1; 187 delete invt2; 188 delete inverse1; 189 delete inverse2; 190 191 } 192 193 void TransliteratorAPITest::TestClone(){ 194 Transliterator *t1, *t2, *t3, *t4; 195 UErrorCode status = U_ZERO_ERROR; 196 UParseError parseError; 197 t1=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); 198 t2=Transliterator::createInstance("Latin-Greek", UTRANS_FORWARD, parseError, status); 199 if(t1 == 0 || t2 == 0){ 200 dataerrln("FAIL: construction - %s", u_errorName(status)); 201 return; 202 } 203 t3=t1->clone(); 204 t4=t2->clone(); 205 206 if(t1->getID() != t3->getID() || t2->getID() != t4->getID() ) 207 errln("FAIL: clone or getID failed"); 208 if(t1->getID()==t4->getID() || t2->getID()==t3->getID() || t1->getID()==t4->getID()) 209 errln("FAIL: clone or getID failed"); 210 211 delete t1; 212 delete t2; 213 delete t3; 214 delete t4; 215 216 } 217 218 void TransliteratorAPITest::TestGetDisplayName() { 219 UnicodeString dispNames[]= { 220 //ID, displayName 221 //"CurlyQuotes-StraightQuotes" ,"CurlyQuotes to StraightQuotes", 222 "Any-Hex" ,"Any to Hex Escape", 223 "Halfwidth-Fullwidth" ,"Halfwidth to Fullwidth" , 224 //"Latin-Arabic" ,"Latin to Arabic" , 225 "Latin-Devanagari" ,"Latin to Devanagari" , 226 "Greek-Latin" ,"Greek to Latin" , 227 //"Arabic-Latin" ,"Arabic to Latin" , 228 "Hex-Any" ,"Hex Escape to Any", 229 "Cyrillic-Latin" ,"Cyrillic to Latin" , 230 "Latin-Greek" ,"Latin to Greek" , 231 "Latin-Katakana" ,"Latin to Katakana" , 232 //"Latin-Hebrew" ,"Latin to Hebrew" , 233 "Katakana-Latin" ,"Katakana to Latin" 234 }; 235 UnicodeString name=""; 236 Transliterator* t; 237 UnicodeString message; 238 UErrorCode status = U_ZERO_ERROR; 239 UParseError parseError; 240 241 #if UCONFIG_NO_FORMATTING 242 logln("Skipping, UCONFIG_NO_FORMATTING is set\n"); 243 return; 244 #else 245 246 for (uint32_t i=0; i<UPRV_LENGTHOF(dispNames); i=i+2 ) { 247 t = Transliterator::createInstance(dispNames[i+0], UTRANS_FORWARD, parseError, status); 248 if(t==0){ 249 dataerrln("FAIL: construction: " + dispNames[i+0] + " - " + u_errorName(status)); 250 status = U_ZERO_ERROR; 251 continue; 252 } 253 t->getDisplayName(t->getID(), name); 254 message="Display name for ID:" + t->getID(); 255 // doTest(message, name, dispNames[i+1]); //!!! This will obviously fail for any locale other than english and its children!!! 256 name=""; 257 t->getDisplayName(t->getID(), Locale::getUS(), name); 258 message.remove(); 259 message.append("Display name for on english locale ID:"); 260 message.append(t->getID()); 261 // message="Display name for on english locale ID:" + t->getID(); 262 doTest(message, name, dispNames[i+1]); 263 name=""; 264 265 delete t; 266 } 267 #endif 268 269 } 270 271 void TransliteratorAPITest::TestTransliterate1(){ 272 273 UnicodeString Data[]={ 274 //ID, input string, transliterated string 275 "Any-Hex", "hello", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", "") , 276 "Hex-Any", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""), "hello" , 277 "Latin-Devanagari",CharsToUnicodeString("bha\\u0304rata"), CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924") , 278 "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") , 279 280 "Devanagari-Latin", CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), CharsToUnicodeString("bh\\u0101rata"), 281 // "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"), CharsToUnicodeString("\\u0041\\u0300\\u0041\\u0301\\u0042") , 282 // "Expanded-Contracted", CharsToUnicodeString("\\u0041\\u0300\\u0041\\u0301\\u0042"), CharsToUnicodeString("\\u00C0\\u00C1\\u0042") , 283 //"Latin-Arabic", "aap", CharsToUnicodeString("\\u0627\\u06A4") , 284 //"Arabic-Latin", CharsToUnicodeString("\\u0627\\u06A4"), "aap" 285 }; 286 287 UnicodeString gotResult; 288 UnicodeString temp; 289 UnicodeString message; 290 Transliterator* t; 291 logln("Testing transliterate"); 292 UErrorCode status = U_ZERO_ERROR; 293 UParseError parseError; 294 295 for(uint32_t i=0;i<UPRV_LENGTHOF(Data); i=i+3){ 296 t=Transliterator::createInstance(Data[i+0], UTRANS_FORWARD, parseError, status); 297 if(t==0){ 298 dataerrln("FAIL: construction: " + Data[i+0] + " Error: " + u_errorName(status)); 299 dataerrln("PreContext: " + prettify(parseError.preContext) + " PostContext: " + prettify( parseError.postContext) ); 300 status = U_ZERO_ERROR; 301 continue; 302 } 303 gotResult = Data[i+1]; 304 t->transliterate(gotResult); 305 message=t->getID() + "->transliterate(UnicodeString, UnicodeString) for\n\t Source:" + prettify(Data[i+1]); 306 doTest(message, gotResult, Data[i+2]); 307 308 //doubt here 309 temp=Data[i+1]; 310 t->transliterate(temp); 311 message.remove(); 312 message.append(t->getID()); 313 message.append("->transliterate(Replaceable) for \n\tSource:"); 314 message.append(Data[i][1]); 315 doTest(message, temp, Data[i+2]); 316 317 callEverything(t, __LINE__); 318 delete t; 319 } 320 } 321 322 void TransliteratorAPITest::TestTransliterate2(){ 323 //testing tranliterate(String text, int start, int limit, StringBuffer result) 324 UnicodeString Data2[]={ 325 //ID, input string, start, limit, transliterated string 326 "Any-Hex", "hello! How are you?", "0", "5", UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F", ""), UnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F! How are you?", "") , 327 "Any-Hex", "hello! How are you?", "7", "12", UnicodeString("\\u0048\\u006F\\u0077\\u0020\\u0061", ""), UnicodeString("hello! \\u0048\\u006F\\u0077\\u0020\\u0061re you?", ""), 328 "Hex-Any", CharsToUnicodeString("\\u0068\\u0065\\u006C\\u006C\\u006F\\u0021\\u0020"), "0", "5", "hello", "hello! " , 329 // "Contracted-Expanded", CharsToUnicodeString("\\u00C0\\u00C1\\u0042"), "1", "2", CharsToUnicodeString("\\u0041\\u0301"), CharsToUnicodeString("\\u00C0\\u0041\\u0301\\u0042") , 330 "Devanagari-Latin", CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), "0", "1", "bha", CharsToUnicodeString("bha\\u093E\\u0930\\u0924") , 331 "Devanagari-Latin", CharsToUnicodeString("\\u092D\\u093E\\u0930\\u0924"), "1", "2", CharsToUnicodeString("\\u0314\\u0101"), CharsToUnicodeString("\\u092D\\u0314\\u0101\\u0930\\u0924") 332 333 }; 334 logln("\n Testing transliterate(String, int, int, StringBuffer)"); 335 Transliterator* t; 336 UnicodeString gotResBuf; 337 UnicodeString temp; 338 int32_t start, limit; 339 UErrorCode status = U_ZERO_ERROR; 340 UParseError parseError; 341 342 for(uint32_t i=0; i<UPRV_LENGTHOF(Data2); i=i+6){ 343 t=Transliterator::createInstance(Data2[i+0], UTRANS_FORWARD, parseError, status); 344 if(t==0){ 345 dataerrln("FAIL: construction: " + prettify(Data2[i+0]) + " - " + u_errorName(status)); 346 continue; 347 } 348 start=getInt(Data2[i+2]); 349 limit=getInt(Data2[i+3]); 350 Data2[i+1].extractBetween(start, limit, gotResBuf); 351 t->transliterate(gotResBuf); 352 // errln("FAIL: calling transliterate on " + t->getID()); 353 doTest(t->getID() + ".transliterate(UnicodeString, int32_t, int32_t, UnicodeString):(" + start + "," + limit + ") for \n\t source: " + prettify(Data2[i+1]), gotResBuf, Data2[i+4]); 354 355 temp=Data2[i+1]; 356 t->transliterate(temp, start, limit); 357 doTest(t->getID() + ".transliterate(Replaceable, int32_t, int32_t, ):(" + start + "," + limit + ") for \n\t source: " + prettify(Data2[i+1]), temp, Data2[i+5]); 358 status = U_ZERO_ERROR; 359 callEverything(t, __LINE__); 360 delete t; 361 t = NULL; 362 } 363 364 status = U_ZERO_ERROR; 365 logln("\n Try calling transliterate with illegal start and limit values"); 366 t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); 367 if(U_FAILURE(status)) { 368 errln("Error creating transliterator %s", u_errorName(status)); 369 delete t; 370 return; 371 } 372 gotResBuf = temp = "try start greater than limit"; 373 t->transliterate(gotResBuf, 10, 5); 374 if(gotResBuf == temp) { 375 logln("OK: start greater than limit value handled correctly"); 376 } else { 377 errln("FAIL: start greater than limit value returned" + gotResBuf); 378 } 379 380 callEverything(t, __LINE__); 381 delete t; 382 383 } 384 void TransliteratorAPITest::TestTransliterate3(){ 385 UnicodeString rs="This is the replaceable String"; 386 UnicodeString Data[] = { 387 "0", "0", "This is the replaceable String", 388 "2", "3", UnicodeString("Th\\u0069s is the replaceable String", ""), 389 "21", "23", UnicodeString("Th\\u0069s is the repl\\u0061\\u0063eable String", ""), 390 "14", "17", UnicodeString("Th\\u0069s is t\\u0068\\u0065\\u0020repl\\u0061\\u0063eable String", ""), 391 }; 392 int start, limit; 393 UnicodeString message; 394 UParseError parseError; 395 UErrorCode status = U_ZERO_ERROR; 396 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); 397 if(U_FAILURE(status)) { 398 errln("Error creating transliterator %s", u_errorName(status)); 399 delete t; 400 return; 401 } 402 403 if(t == 0) 404 errln("FAIL : construction"); 405 for(uint32_t i=0; i<UPRV_LENGTHOF(Data); i=i+3){ 406 start=getInt(Data[i+0]); 407 limit=getInt(Data[i+1]); 408 t->transliterate(rs, start, limit); 409 message=t->getID() + ".transliterate(ReplaceableString, start, limit):("+start+","+limit+"):"; 410 doTest(message, rs, Data[i+2]); 411 } 412 delete t; 413 } 414 415 void TransliteratorAPITest::TestSimpleKeyboardTransliterator(){ 416 logln("simple call to transliterate"); 417 UErrorCode status=U_ZERO_ERROR; 418 UParseError parseError; 419 Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); 420 if(t == 0) { 421 UnicodeString context; 422 423 if (parseError.preContext[0]) { 424 context += (UnicodeString)" at " + parseError.preContext; 425 } 426 if (parseError.postContext[0]) { 427 context += (UnicodeString)" | " + parseError.postContext; 428 } 429 errln((UnicodeString)"FAIL: can't create Any-Hex, " + 430 (UnicodeString)u_errorName(status) + context); 431 return; 432 } 433 UTransPosition index={19,20,20,20}; 434 UnicodeString rs= "Transliterate this-''"; 435 UnicodeString insertion="abc"; 436 UnicodeString expected=UnicodeString("Transliterate this-'\\u0061\\u0062\\u0063'", ""); 437 t->transliterate(rs, index, insertion, status); 438 if(U_FAILURE(status)) 439 errln("FAIL: " + t->getID()+ ".translitere(Replaceable, int[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status)); 440 t->finishTransliteration(rs, index); 441 UnicodeString message="transliterate"; 442 doTest(message, rs, expected); 443 444 logln("try calling transliterate with invalid index values"); 445 UTransPosition index1[]={ 446 //START, LIMIT, CURSOR 447 {10, 10, 12, 10}, //invalid since CURSOR>LIMIT valid:-START <= CURSOR <= LIMIT 448 {17, 16, 17, 17}, //invalid since START>LIMIT valid:-0<=START<=LIMIT 449 {-1, 16, 14, 16}, //invalid since START<0 450 {3, 50, 2, 50} //invalid since LIMIT>text.length() 451 }; 452 for(uint32_t i=0; i<UPRV_LENGTHOF(index1); i++){ 453 status=U_ZERO_ERROR; 454 t->transliterate(rs, index1[i], insertion, status); 455 if(status == U_ILLEGAL_ARGUMENT_ERROR) 456 logln("OK: invalid index values handled correctly"); 457 else 458 errln("FAIL: invalid index values didn't throw U_ILLEGAL_ARGUMENT_ERROR throw" + (UnicodeString)u_errorName(status)); 459 } 460 461 delete t; 462 } 463 void TransliteratorAPITest::TestKeyboardTransliterator1(){ 464 UnicodeString Data[]={ 465 //insertion, buffer 466 "a", UnicodeString("\\u0061", "") , 467 "bbb", UnicodeString("\\u0061\\u0062\\u0062\\u0062", "") , 468 "ca", UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061", "") , 469 " ", UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020", "") , 470 "", UnicodeString("\\u0061\\u0062\\u0062\\u0062\\u0063\\u0061\\u0020", "") , 471 472 "a", UnicodeString("\\u0061", "") , 473 "b", UnicodeString("\\u0061\\u0062", "") , 474 "z", UnicodeString("\\u0061\\u0062\\u007A", "") , 475 "", UnicodeString("\\u0061\\u0062\\u007A", "") 476 477 }; 478 UParseError parseError; 479 UErrorCode status = U_ZERO_ERROR; 480 Transliterator* t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); 481 if(U_FAILURE(status)) { 482 errln("Error creating transliterator %s", u_errorName(status)); 483 delete t; 484 return; 485 } 486 //keyboardAux(t, Data); 487 UTransPosition index={0, 0, 0, 0}; 488 UnicodeString s; 489 uint32_t i; 490 logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)"); 491 for (i=0; i<10; i=i+2) { 492 UnicodeString log; 493 if (Data[i+0] != "") { 494 log = s + " + " + Data[i+0] + " -> "; 495 t->transliterate(s, index, Data[i+0], status); 496 if(U_FAILURE(status)){ 497 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status)); 498 continue; 499 } 500 }else { 501 log = s + " => "; 502 t->finishTransliteration(s, index); 503 } 504 // Show the start index '{' and the cursor '|' 505 displayOutput(s, Data[i+1], log, index); 506 507 } 508 509 s=""; 510 status=U_ZERO_ERROR; 511 index.contextStart = index.contextLimit = index.start = index.limit = 0; 512 logln("Testing transliterate(Replaceable, int32_t, UChar, UErrorCode)"); 513 for(i=10; i<UPRV_LENGTHOF(Data); i=i+2){ 514 UnicodeString log; 515 if (Data[i+0] != "") { 516 log = s + " + " + Data[i+0] + " -> "; 517 UChar c=Data[i+0].charAt(0); 518 t->transliterate(s, index, c, status); 519 if(U_FAILURE(status)) 520 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UChar, UErrorCode)-->" + (UnicodeString)u_errorName(status)); 521 continue; 522 }else { 523 log = s + " => "; 524 t->finishTransliteration(s, index); 525 } 526 // Show the start index '{' and the cursor '|' 527 displayOutput(s, Data[i+1], log, index); 528 } 529 530 delete t; 531 } 532 533 void TransliteratorAPITest::TestKeyboardTransliterator2(){ 534 UnicodeString Data[]={ 535 //insertion, buffer, index[START], index[LIMIT], index[CURSOR] 536 //data for Any-Hex 537 "abc", UnicodeString("Initial String: add-\\u0061\\u0062\\u0063-", ""), "19", "20", "20", 538 "a", UnicodeString("In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "2", "3", "2" , 539 "b", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0", "0", "0" , 540 "", UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0", "0", "0" , 541 //data for Latin-Devanagiri 542 CharsToUnicodeString("a\\u0304"), CharsToUnicodeString("Hindi -\\u0906-"), "6", "7", "6", 543 CharsToUnicodeString("ma\\u0304"), CharsToUnicodeString("Hindi -\\u0906\\u092E\\u093E-"), "7", "8", "7", 544 CharsToUnicodeString("ra\\u0304"), CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2", 545 CharsToUnicodeString(""), CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2" 546 //data for contracted-Expanded 547 // CharsToUnicodeString("\\u00C1"), CharsToUnicodeString("Ad\\u0041\\u0301d here:"), "1", "2", "1" , 548 // CharsToUnicodeString("\\u00C0"), CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11", 549 // "", CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11", 550 }; 551 Transliterator *t; 552 UnicodeString rs; 553 UnicodeString dataStr; 554 logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)"); 555 UErrorCode status = U_ZERO_ERROR; 556 UParseError parseError; 557 rs="Initial String: add--"; 558 t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); 559 if(t == 0) 560 dataerrln("FAIL : construction - %s", u_errorName(status)); 561 else { 562 keyboardAux(t, Data, rs, 0, 20); 563 delete t; 564 } 565 566 rs="Hindi --"; 567 t=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status); 568 if(t == 0) 569 dataerrln("FAIL : construction - %s", u_errorName(status)); 570 else 571 keyboardAux(t, Data, rs, 20, 40); 572 573 574 // rs="Add here:"; 575 // t=Transliterator::createInstance("Contracted-Expanded"); 576 // keyboardAux(t, Data, rs, 35, 55); 577 578 579 delete t; 580 } 581 582 void TransliteratorAPITest::TestKeyboardTransliterator3(){ 583 UnicodeString s="This is the main string"; 584 UnicodeString Data[] = { 585 "0", "0", "0", "This is the main string", 586 "1", "3", "2", UnicodeString("Th\\u0069s is the main string", ""), 587 "20", "21", "20", UnicodeString("Th\\u0069s is the mai\\u006E string", "") 588 }; 589 590 UErrorCode status=U_ZERO_ERROR; 591 UParseError parseError; 592 UTransPosition index={0, 0, 0, 0}; 593 logln("Testing transliterate(Replaceable, int32_t, UErrorCode)"); 594 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); 595 if(t == 0 || U_FAILURE(status)) { 596 errln("Error creating transliterator %s", u_errorName(status)); 597 delete t; 598 return; 599 } 600 for(uint32_t i=0; i<UPRV_LENGTHOF(Data); i=i+4){ 601 UnicodeString log; 602 index.contextStart=getInt(Data[i+0]); 603 index.contextLimit=index.limit=getInt(Data[i+1]); 604 index.start=getInt(Data[i+2]); 605 t->transliterate(s, index, status); 606 if(U_FAILURE(status)){ 607 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UErrorCode)-->" + (UnicodeString)u_errorName(status)); 608 continue; 609 } 610 t->finishTransliteration(s, index); 611 log = s + " => "; 612 // Show the start index '{' and the cursor '|' 613 displayOutput(s, Data[i+3], log, index); 614 } 615 616 delete t; 617 } 618 void TransliteratorAPITest::TestNullTransliterator(){ 619 UErrorCode status=U_ZERO_ERROR; 620 UnicodeString s("Transliterate using null transliterator"); 621 Transliterator *nullTrans=Transliterator::createInstance("Any-Null", UTRANS_FORWARD, status); 622 int32_t transLimit; 623 int32_t start=0; 624 int32_t limit=s.length(); 625 UnicodeString replaceable=s; 626 transLimit=nullTrans->transliterate(replaceable, start, limit); 627 if(transLimit != limit){ 628 errln("ERROR: NullTransliterator->transliterate() failed"); 629 } 630 doTest((UnicodeString)"nulTrans->transliterate", replaceable, s); 631 replaceable.remove(); 632 replaceable.append(s); 633 UTransPosition index; 634 index.contextStart =start; 635 index.contextLimit = limit; 636 index.start = 0; 637 index.limit = limit; 638 nullTrans->finishTransliteration(replaceable, index); 639 if(index.start != limit){ 640 errln("ERROR: NullTransliterator->handleTransliterate() failed"); 641 } 642 doTest((UnicodeString)"NullTransliterator->handleTransliterate", replaceable, s); 643 callEverything(nullTrans, __LINE__); 644 delete nullTrans; 645 646 647 } 648 void TransliteratorAPITest::TestRegisterUnregister(){ 649 650 UErrorCode status=U_ZERO_ERROR; 651 /* Make sure it doesn't exist */ 652 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) { 653 errln("FAIL: TestA-TestB already registered\n"); 654 return; 655 } 656 /* Check inverse too 657 if (Transliterator::createInstance("TestA-TestB", 658 (UTransDirection)UTRANS_REVERSE) != NULL) { 659 errln("FAIL: TestA-TestB inverse already registered\n"); 660 return; 661 } 662 */ 663 status =U_ZERO_ERROR; 664 665 /* Create it */ 666 UParseError parseError; 667 Transliterator *t = Transliterator::createFromRules("TestA-TestB", 668 "a<>b", 669 UTRANS_FORWARD, parseError, 670 status); 671 /* Register it */ 672 Transliterator::registerInstance(t); 673 674 /* Now check again -- should exist now*/ 675 Transliterator *s = Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status); 676 if (s == NULL) { 677 errln("FAIL: TestA-TestB not registered\n"); 678 return; 679 } 680 callEverything(s, __LINE__); 681 callEverything(t, __LINE__); 682 delete s; 683 684 /* Check inverse too 685 s = Transliterator::createInstance("TestA-TestB", 686 (UTransDirection)UTRANS_REVERSE); 687 if (s == NULL) { 688 errln("FAIL: TestA-TestB inverse not registered\n"); 689 return; 690 } 691 delete s; 692 */ 693 694 /*unregister the instance*/ 695 Transliterator::unregister("TestA-TestB"); 696 /* now Make sure it doesn't exist */ 697 if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) { 698 errln("FAIL: TestA-TestB isn't unregistered\n"); 699 return; 700 } 701 702 } 703 704 705 int gTestFilter1ClassID = 0; 706 int gTestFilter2ClassID = 0; 707 int gTestFilter3ClassID = 0; 708 709 /** 710 * Used by TestFiltering(). 711 */ 712 class TestFilter1 : public UnicodeFilter { 713 UClassID getDynamicClassID()const { return &gTestFilter1ClassID; } 714 virtual UnicodeFunctor* clone() const { 715 return new TestFilter1(*this); 716 } 717 virtual UBool contains(UChar32 c) const { 718 if(c==0x63 || c==0x61 || c==0x43 || c==0x41) 719 return FALSE; 720 else 721 return TRUE; 722 } 723 // Stubs 724 virtual UnicodeString& toPattern(UnicodeString& result, 725 UBool /*escapeUnprintable*/) const { 726 return result; 727 } 728 virtual UBool matchesIndexValue(uint8_t /*v*/) const { 729 return FALSE; 730 } 731 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} 732 }; 733 class TestFilter2 : public UnicodeFilter { 734 UClassID getDynamicClassID()const { return &gTestFilter2ClassID; } 735 virtual UnicodeFunctor* clone() const { 736 return new TestFilter2(*this); 737 } 738 virtual UBool contains(UChar32 c) const { 739 if(c==0x65 || c==0x6c) 740 return FALSE; 741 else 742 return TRUE; 743 } 744 // Stubs 745 virtual UnicodeString& toPattern(UnicodeString& result, 746 UBool /*escapeUnprintable*/) const { 747 return result; 748 } 749 virtual UBool matchesIndexValue(uint8_t /*v*/) const { 750 return FALSE; 751 } 752 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} 753 }; 754 class TestFilter3 : public UnicodeFilter { 755 UClassID getDynamicClassID()const { return &gTestFilter3ClassID; } 756 virtual UnicodeFunctor* clone() const { 757 return new TestFilter3(*this); 758 } 759 virtual UBool contains(UChar32 c) const { 760 if(c==0x6f || c==0x77) 761 return FALSE; 762 else 763 return TRUE; 764 } 765 // Stubs 766 virtual UnicodeString& toPattern(UnicodeString& result, 767 UBool /*escapeUnprintable*/) const { 768 return result; 769 } 770 virtual UBool matchesIndexValue(uint8_t /*v*/) const { 771 return FALSE; 772 } 773 virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {} 774 }; 775 776 777 void TransliteratorAPITest::TestGetAdoptFilter(){ 778 UErrorCode status = U_ZERO_ERROR; 779 UParseError parseError; 780 Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status); 781 if(t == 0 || U_FAILURE(status)) { 782 errln("Error creating transliterator %s", u_errorName(status)); 783 delete t; 784 return; 785 } 786 const UnicodeFilter *u=t->getFilter(); 787 if(u != NULL){ 788 errln("FAIL: getFilter failed. Didn't return null when the transliterator used no filtering"); 789 delete t; 790 return; 791 } 792 793 UnicodeString got, temp, message; 794 UnicodeString data="ABCabcbbCBa"; 795 temp = data; 796 t->transliterate(temp); 797 t->adoptFilter(new TestFilter1); 798 799 got = data; 800 t->transliterate(got); 801 UnicodeString exp=UnicodeString("A\\u0042Ca\\u0062c\\u0062\\u0062C\\u0042a", ""); 802 message="transliteration after adoptFilter(a,A,c,C) "; 803 doTest(message, got, exp); 804 805 logln("Testing round trip"); 806 t->adoptFilter((UnicodeFilter*)u); 807 if(t->getFilter() == NULL) 808 logln("OK: adoptFilter and getFilter round trip worked"); 809 else 810 errln("FAIL: adoptFilter or getFilter round trip failed"); 811 812 got = data; 813 t->transliterate(got); 814 exp=UnicodeString("\\u0041\\u0042\\u0043\\u0061\\u0062\\u0063\\u0062\\u0062\\u0043\\u0042\\u0061", ""); 815 message="transliteration after adopting null filter"; 816 doTest(message, got, exp); 817 message="adoptFilter round trip"; 818 doTest("adoptFilter round trip", got, temp); 819 820 t->adoptFilter(new TestFilter2); 821 callEverything(t, __LINE__); 822 data="heelloe"; 823 exp=UnicodeString("\\u0068eell\\u006Fe", ""); 824 got = data; 825 t->transliterate(got); 826 message="transliteration using (e,l) filter"; 827 doTest("transliteration using (e,l) filter", got, exp); 828 829 data="are well"; 830 exp=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", ""); 831 got = data; 832 t->transliterate(got); 833 doTest(message, got, exp); 834 835 t->adoptFilter(new TestFilter3); 836 data="ho, wow!"; 837 exp=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", ""); 838 got = data; 839 t->transliterate(got); 840 message="transliteration using (o,w) filter"; 841 doTest("transliteration using (o,w) filter", got, exp); 842 843 data="owl"; 844 exp=UnicodeString("ow\\u006C", ""); 845 got = data; 846 t->transliterate(got); 847 doTest("transliteration using (o,w) filter", got, exp); 848 849 delete t; 850 851 } 852 853 854 855 void TransliteratorAPITest::keyboardAux(Transliterator *t, UnicodeString DATA[], UnicodeString& s, int32_t begin, int32_t end) { 856 UTransPosition index={0, 0, 0, 0}; 857 UErrorCode status=U_ZERO_ERROR; 858 for (int32_t i=begin; i<end; i=i+5) { 859 UnicodeString log; 860 if (DATA[i+0] != "") { 861 log = s + " + " + DATA[i] + " -> "; 862 index.contextStart=getInt(DATA[i+2]); 863 index.contextLimit=index.limit=getInt(DATA[i+3]); 864 index.start=getInt(DATA[i+4]); 865 t->transliterate(s, index, DATA[i+0], status); 866 if(U_FAILURE(status)){ 867 errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status)); 868 continue; 869 } 870 log = s + " => "; 871 t->finishTransliteration(s, index); 872 } 873 // Show the start index '{' and the cursor '|' 874 displayOutput(s, DATA[i+1], log, index); 875 876 } 877 } 878 879 void TransliteratorAPITest::displayOutput(const UnicodeString& got, const UnicodeString& expected, UnicodeString& log, UTransPosition& index){ 880 // Show the start index '{' and the cursor '|' 881 UnicodeString a, b, c, d, e; 882 got.extractBetween(0, index.contextStart, a); 883 got.extractBetween(index.contextStart, index.start, b); 884 got.extractBetween(index.start, index.limit, c); 885 got.extractBetween(index.limit, index.contextLimit, d); 886 got.extractBetween(index.contextLimit, got.length(), e); 887 log.append(a). 888 append((UChar)0x7b/*{*/). 889 append(b). 890 append((UChar)0x7c/*|*/). 891 append(c). 892 append((UChar)0x7c). 893 append(d). 894 append((UChar)0x7d/*}*/). 895 append(e); 896 if (got == expected) 897 logln("OK:" + prettify(log)); 898 else 899 errln("FAIL: " + prettify(log) + ", expected " + prettify(expected)); 900 } 901 902 903 /*Internal Functions used*/ 904 void TransliteratorAPITest::doTest(const UnicodeString& message, const UnicodeString& result, const UnicodeString& expected){ 905 if (prettify(result) == prettify(expected)) 906 logln((UnicodeString)"Ok: " + prettify(message) + " passed \"" + prettify(expected) + "\""); 907 else 908 dataerrln((UnicodeString)"FAIL:" + message + " failed Got-->" + prettify(result)+ ", Expected--> " + prettify(expected) ); 909 } 910 911 912 // 913 // callEverything call all of the const (non-destructive) methods on a 914 // transliterator, just to verify that they don't fail in some 915 // destructive way. 916 // 917 #define CEASSERT(a) {if (!(a)) { \ 918 errln("FAIL at line %d from line %d: %s", __LINE__, line, #a); return; }} 919 920 void TransliteratorAPITest::callEverything(const Transliterator *tr, int line) { 921 Transliterator *clonedTR = tr->clone(); 922 CEASSERT(clonedTR != NULL); 923 924 int32_t maxcl = tr->getMaximumContextLength(); 925 CEASSERT(clonedTR->getMaximumContextLength() == maxcl); 926 927 UnicodeString id; 928 UnicodeString clonedId; 929 id = tr->getID(); 930 clonedId = clonedTR->getID(); 931 CEASSERT(id == clonedId); 932 933 const UnicodeFilter *filter = tr->getFilter(); 934 const UnicodeFilter *clonedFilter = clonedTR->getFilter(); 935 if (filter == NULL || clonedFilter == NULL) { 936 // If one filter is NULL they better both be NULL. 937 CEASSERT(filter == clonedFilter); 938 } else { 939 CEASSERT(filter != clonedFilter); 940 } 941 942 UnicodeString rules; 943 UnicodeString clonedRules; 944 rules = tr->toRules(rules, FALSE); 945 clonedRules = clonedTR->toRules(clonedRules, FALSE); 946 CEASSERT(rules == clonedRules); 947 948 UnicodeSet sourceSet; 949 UnicodeSet clonedSourceSet; 950 tr->getSourceSet(sourceSet); 951 clonedTR->getSourceSet(clonedSourceSet); 952 CEASSERT(clonedSourceSet == sourceSet); 953 954 UnicodeSet targetSet; 955 UnicodeSet clonedTargetSet; 956 tr->getTargetSet(targetSet); 957 clonedTR->getTargetSet(clonedTargetSet); 958 CEASSERT(targetSet == clonedTargetSet); 959 960 UClassID classID = tr->getDynamicClassID(); 961 CEASSERT(classID == clonedTR->getDynamicClassID()); 962 CEASSERT(classID != 0); 963 964 delete clonedTR; 965 } 966 967 static const int MyUnicodeFunctorTestClassID = 0; 968 class MyUnicodeFunctorTestClass : public UnicodeFunctor { 969 public: 970 virtual UnicodeFunctor* clone() const {return NULL;} 971 static UClassID getStaticClassID(void) {return (UClassID)&MyUnicodeFunctorTestClassID;} 972 virtual UClassID getDynamicClassID(void) const {return getStaticClassID();}; 973 virtual void setData(const TransliterationRuleData*) {} 974 }; 975 976 void TransliteratorAPITest::TestUnicodeFunctor() { 977 MyUnicodeFunctorTestClass myClass; 978 if (myClass.toMatcher() != NULL) { 979 errln("FAIL: UnicodeFunctor::toMatcher did not return NULL"); 980 } 981 if (myClass.toReplacer() != NULL) { 982 errln("FAIL: UnicodeFunctor::toReplacer did not return NULL"); 983 } 984 } 985 986 987 #endif /* #if !UCONFIG_NO_TRANSLITERATION */ 988