• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getInt(UnicodeString str)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
runIndexedTest(int32_t index,UBool exec,const char * & name,char *)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 
TestgetID()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 
TestgetInverse()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 
TestClone()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 
TestGetDisplayName()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 
TestTransliterate1()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 
TestTransliterate2()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 }
TestTransliterate3()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 
TestSimpleKeyboardTransliterator()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 }
TestKeyboardTransliterator1()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             }
523         } else {
524            log = s + " => ";
525            t->finishTransliteration(s, index);
526         }
527         // Show the start index '{' and the cursor '|'
528         displayOutput(s, Data[i+1], log, index);
529     }
530 
531     delete t;
532 }
533 
TestKeyboardTransliterator2()534 void TransliteratorAPITest::TestKeyboardTransliterator2(){
535     UnicodeString Data[]={
536         //insertion, buffer, index[START], index[LIMIT], index[CURSOR]
537         //data for Any-Hex
538         "abc",    UnicodeString("Initial String: add-\\u0061\\u0062\\u0063-", ""),                     "19", "20", "20",
539         "a",      UnicodeString("In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""),        "2",  "3",  "2" ,
540         "b",      UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0",  "0",  "0" ,
541         "",       UnicodeString("\\u0062In\\u0069\\u0061tial String: add-\\u0061\\u0062\\u0063-", ""), "0",  "0",  "0" ,
542         //data for Latin-Devanagiri
543         CharsToUnicodeString("a\\u0304"),     CharsToUnicodeString("Hindi -\\u0906-"),                            "6", "7", "6",
544         CharsToUnicodeString("ma\\u0304"),    CharsToUnicodeString("Hindi -\\u0906\\u092E\\u093E-"),              "7", "8", "7",
545         CharsToUnicodeString("ra\\u0304"),    CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2",
546         CharsToUnicodeString(""),       CharsToUnicodeString("Hi\\u0930\\u093Endi -\\u0906\\u092E\\u093E-"),"1", "2", "2"
547         //data for contracted-Expanded
548      //   CharsToUnicodeString("\\u00C1"), CharsToUnicodeString("Ad\\u0041\\u0301d here:"),             "1",  "2",  "1" ,
549      //   CharsToUnicodeString("\\u00C0"), CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
550      //   "",     CharsToUnicodeString("Ad\\u0041\\u0301d here:\\u0041\\u0300"), "11", "11", "11",
551     };
552     Transliterator *t;
553     UnicodeString rs;
554     UnicodeString dataStr;
555     logln("Testing transliterate(Replaceable, int32_t, UnicodeString, UErrorCode)");
556     UErrorCode status = U_ZERO_ERROR;
557     UParseError parseError;
558     rs="Initial String: add--";
559     t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
560     if(t == 0)
561         dataerrln("FAIL : construction - %s", u_errorName(status));
562     else {
563         keyboardAux(t, Data, rs, 0, 20);
564         delete t;
565     }
566 
567     rs="Hindi --";
568     t=Transliterator::createInstance("Latin-Devanagari", UTRANS_FORWARD, parseError, status);
569     if(t == 0)
570         dataerrln("FAIL : construction - %s", u_errorName(status));
571     else
572         keyboardAux(t, Data, rs, 20, 40);
573 
574 
575   //  rs="Add here:";
576  //   t=Transliterator::createInstance("Contracted-Expanded");
577  //   keyboardAux(t, Data, rs, 35, 55);
578 
579 
580     delete t;
581 }
582 
TestKeyboardTransliterator3()583 void TransliteratorAPITest::TestKeyboardTransliterator3(){
584     UnicodeString s="This is the main string";
585     UnicodeString Data[] = {
586         "0", "0", "0",  "This is the main string",
587         "1", "3", "2",  UnicodeString("Th\\u0069s is the main string", ""),
588         "20", "21", "20",  UnicodeString("Th\\u0069s is the mai\\u006E string", "")
589     };
590 
591     UErrorCode status=U_ZERO_ERROR;
592     UParseError parseError;
593     UTransPosition index={0, 0, 0, 0};
594     logln("Testing transliterate(Replaceable, int32_t, UErrorCode)");
595     Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
596     if(t == 0 || U_FAILURE(status)) {
597       errln("Error creating transliterator %s", u_errorName(status));
598       delete t;
599       return;
600     }
601     for(uint32_t i=0; i<UPRV_LENGTHOF(Data); i=i+4){
602         UnicodeString log;
603         index.contextStart=getInt(Data[i+0]);
604         index.contextLimit=index.limit=getInt(Data[i+1]);
605         index.start=getInt(Data[i+2]);
606         t->transliterate(s, index, status);
607         if(U_FAILURE(status)){
608            errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UErrorCode)-->" + (UnicodeString)u_errorName(status));
609            continue;
610         }
611         t->finishTransliteration(s, index);
612         log = s + " => ";
613         // Show the start index '{' and the cursor '|'
614         displayOutput(s, Data[i+3], log, index);
615     }
616 
617     delete t;
618 }
TestNullTransliterator()619 void TransliteratorAPITest::TestNullTransliterator(){
620     UErrorCode status=U_ZERO_ERROR;
621     UnicodeString s("Transliterate using null transliterator");
622     Transliterator *nullTrans=Transliterator::createInstance("Any-Null", UTRANS_FORWARD, status);
623     int32_t transLimit;
624     int32_t start=0;
625     int32_t limit=s.length();
626     UnicodeString replaceable=s;
627     transLimit=nullTrans->transliterate(replaceable, start, limit);
628     if(transLimit != limit){
629         errln("ERROR: NullTransliterator->transliterate() failed");
630     }
631     doTest((UnicodeString)"nulTrans->transliterate", replaceable, s);
632     replaceable.remove();
633     replaceable.append(s);
634     UTransPosition index;
635     index.contextStart =start;
636     index.contextLimit = limit;
637     index.start = 0;
638     index.limit = limit;
639     nullTrans->finishTransliteration(replaceable, index);
640     if(index.start != limit){
641         errln("ERROR: NullTransliterator->handleTransliterate() failed");
642     }
643     doTest((UnicodeString)"NullTransliterator->handleTransliterate", replaceable, s);
644     callEverything(nullTrans, __LINE__);
645     delete nullTrans;
646 
647 
648 }
TestRegisterUnregister()649 void TransliteratorAPITest::TestRegisterUnregister(){
650 
651    UErrorCode status=U_ZERO_ERROR;
652     /* Make sure it doesn't exist */
653    if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) {
654       errln("FAIL: TestA-TestB already registered\n");
655       return;
656    }
657    /* Check inverse too
658    if (Transliterator::createInstance("TestA-TestB",
659                                       (UTransDirection)UTRANS_REVERSE) != NULL) {
660       errln("FAIL: TestA-TestB inverse already registered\n");
661       return;
662    }
663    */
664    status =U_ZERO_ERROR;
665 
666    /* Create it */
667    UParseError parseError;
668    Transliterator *t = Transliterator::createFromRules("TestA-TestB",
669                                                    "a<>b",
670                                                    UTRANS_FORWARD, parseError,
671                                                    status);
672    /* Register it */
673    Transliterator::registerInstance(t);
674 
675    /* Now check again -- should exist now*/
676    Transliterator *s = Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status);
677    if (s == NULL) {
678       errln("FAIL: TestA-TestB not registered\n");
679       return;
680    }
681    callEverything(s, __LINE__);
682    callEverything(t, __LINE__);
683    delete s;
684 
685    /* Check inverse too
686    s = Transliterator::createInstance("TestA-TestB",
687                                       (UTransDirection)UTRANS_REVERSE);
688    if (s == NULL) {
689       errln("FAIL: TestA-TestB inverse not registered\n");
690       return;
691    }
692    delete s;
693    */
694 
695    /*unregister the instance*/
696    Transliterator::unregister("TestA-TestB");
697    /* now Make sure it doesn't exist */
698    if (Transliterator::createInstance("TestA-TestB", UTRANS_FORWARD, status) != NULL) {
699       errln("FAIL: TestA-TestB isn't unregistered\n");
700       return;
701    }
702 
703 }
704 
705 
706 int gTestFilter1ClassID = 0;
707 int gTestFilter2ClassID = 0;
708 int gTestFilter3ClassID = 0;
709 
710 /**
711  * Used by TestFiltering().
712  */
713 class TestFilter1 : public UnicodeFilter {
getDynamicClassID() const714     UClassID getDynamicClassID()const { return &gTestFilter1ClassID; }
clone() const715     virtual TestFilter1* clone() const {
716         return new TestFilter1(*this);
717     }
contains(UChar32 c) const718     virtual UBool contains(UChar32 c) const {
719        if(c==0x63 || c==0x61 || c==0x43 || c==0x41)
720           return FALSE;
721        else
722           return TRUE;
723     }
724     // Stubs
toPattern(UnicodeString & result,UBool) const725     virtual UnicodeString& toPattern(UnicodeString& result,
726                                      UBool /*escapeUnprintable*/) const {
727         return result;
728     }
matchesIndexValue(uint8_t) const729     virtual UBool matchesIndexValue(uint8_t /*v*/) const {
730         return FALSE;
731     }
addMatchSetTo(UnicodeSet &) const732     virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
733 };
734 class TestFilter2 : public UnicodeFilter {
getDynamicClassID() const735     UClassID getDynamicClassID()const { return &gTestFilter2ClassID; }
clone() const736     virtual TestFilter2* clone() const {
737         return new TestFilter2(*this);
738     }
contains(UChar32 c) const739     virtual UBool contains(UChar32 c) const {
740         if(c==0x65 || c==0x6c)
741            return FALSE;
742         else
743            return TRUE;
744     }
745     // Stubs
toPattern(UnicodeString & result,UBool) const746     virtual UnicodeString& toPattern(UnicodeString& result,
747                                      UBool /*escapeUnprintable*/) const {
748         return result;
749     }
matchesIndexValue(uint8_t) const750     virtual UBool matchesIndexValue(uint8_t /*v*/) const {
751         return FALSE;
752     }
addMatchSetTo(UnicodeSet &) const753     virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
754 };
755 class TestFilter3 : public UnicodeFilter {
getDynamicClassID() const756     UClassID getDynamicClassID()const { return &gTestFilter3ClassID; }
clone() const757     virtual TestFilter3* clone() const {
758         return new TestFilter3(*this);
759     }
contains(UChar32 c) const760     virtual UBool contains(UChar32 c) const {
761         if(c==0x6f || c==0x77)
762            return FALSE;
763         else
764            return TRUE;
765     }
766     // Stubs
toPattern(UnicodeString & result,UBool) const767     virtual UnicodeString& toPattern(UnicodeString& result,
768                                      UBool /*escapeUnprintable*/) const {
769         return result;
770     }
matchesIndexValue(uint8_t) const771     virtual UBool matchesIndexValue(uint8_t /*v*/) const {
772         return FALSE;
773     }
addMatchSetTo(UnicodeSet &) const774     virtual void addMatchSetTo(UnicodeSet& /*toUnionTo*/) const {}
775 };
776 
777 
TestGetAdoptFilter()778 void TransliteratorAPITest::TestGetAdoptFilter(){
779     UErrorCode status = U_ZERO_ERROR;
780     UParseError parseError;
781     Transliterator *t=Transliterator::createInstance("Any-Hex", UTRANS_FORWARD, parseError, status);
782     if(t == 0 || U_FAILURE(status)) {
783         errln("Error creating transliterator %s", u_errorName(status));
784         delete t;
785         return;
786     }
787     const UnicodeFilter *u=t->getFilter();
788     if(u != NULL){
789         errln("FAIL: getFilter failed. Didn't return null when the transliterator used no filtering");
790         delete t;
791         return;
792     }
793 
794     UnicodeString got, temp, message;
795     UnicodeString data="ABCabcbbCBa";
796     temp = data;
797     t->transliterate(temp);
798     t->adoptFilter(new TestFilter1);
799 
800     got = data;
801     t->transliterate(got);
802     UnicodeString exp=UnicodeString("A\\u0042Ca\\u0062c\\u0062\\u0062C\\u0042a", "");
803     message="transliteration after adoptFilter(a,A,c,C) ";
804     doTest(message, got, exp);
805 
806     logln("Testing round trip");
807     t->adoptFilter((UnicodeFilter*)u);
808     if(t->getFilter() == NULL)
809        logln("OK: adoptFilter and getFilter round trip worked");
810     else
811        errln("FAIL: adoptFilter or getFilter round trip failed");
812 
813     got = data;
814     t->transliterate(got);
815     exp=UnicodeString("\\u0041\\u0042\\u0043\\u0061\\u0062\\u0063\\u0062\\u0062\\u0043\\u0042\\u0061", "");
816     message="transliteration after adopting null filter";
817     doTest(message, got, exp);
818     message="adoptFilter round trip";
819     doTest("adoptFilter round trip", got, temp);
820 
821     t->adoptFilter(new TestFilter2);
822     callEverything(t, __LINE__);
823     data="heelloe";
824     exp=UnicodeString("\\u0068eell\\u006Fe", "");
825     got = data;
826     t->transliterate(got);
827     message="transliteration using (e,l) filter";
828     doTest("transliteration using (e,l) filter", got, exp);
829 
830     data="are well";
831     exp=UnicodeString("\\u0061\\u0072e\\u0020\\u0077ell", "");
832     got = data;
833     t->transliterate(got);
834     doTest(message, got, exp);
835 
836     t->adoptFilter(new TestFilter3);
837     data="ho, wow!";
838     exp=UnicodeString("\\u0068o\\u002C\\u0020wow\\u0021", "");
839     got = data;
840     t->transliterate(got);
841     message="transliteration using (o,w) filter";
842     doTest("transliteration using (o,w) filter", got, exp);
843 
844     data="owl";
845     exp=UnicodeString("ow\\u006C", "");
846     got = data;
847     t->transliterate(got);
848     doTest("transliteration using (o,w) filter", got, exp);
849 
850     delete t;
851 
852 }
853 
854 
855 
keyboardAux(Transliterator * t,UnicodeString DATA[],UnicodeString & s,int32_t begin,int32_t end)856 void TransliteratorAPITest::keyboardAux(Transliterator *t, UnicodeString DATA[], UnicodeString& s, int32_t begin, int32_t end) {
857     UTransPosition index={0, 0, 0, 0};
858     UErrorCode status=U_ZERO_ERROR;
859     for (int32_t i=begin; i<end; i=i+5) {
860         UnicodeString log;
861         if (DATA[i+0] != "") {
862              log = s + " + " + DATA[i] + " -> ";
863              index.contextStart=getInt(DATA[i+2]);
864              index.contextLimit=index.limit=getInt(DATA[i+3]);
865              index.start=getInt(DATA[i+4]);
866              t->transliterate(s, index, DATA[i+0], status);
867              if(U_FAILURE(status)){
868                  errln("FAIL: " + t->getID()+ ".transliterate(Replaceable, int32_t[], UnicodeString, UErrorCode)-->" + (UnicodeString)u_errorName(status));
869              continue;
870              }
871            log = s + " => ";
872            t->finishTransliteration(s, index);
873         }
874          // Show the start index '{' and the cursor '|'
875       displayOutput(s, DATA[i+1], log, index);
876 
877     }
878 }
879 
displayOutput(const UnicodeString & got,const UnicodeString & expected,UnicodeString & log,UTransPosition & index)880 void TransliteratorAPITest::displayOutput(const UnicodeString& got, const UnicodeString& expected, UnicodeString& log, UTransPosition& index){
881  // Show the start index '{' and the cursor '|'
882     UnicodeString a, b, c, d, e;
883     got.extractBetween(0, index.contextStart, a);
884     got.extractBetween(index.contextStart, index.start, b);
885     got.extractBetween(index.start, index.limit, c);
886     got.extractBetween(index.limit, index.contextLimit, d);
887     got.extractBetween(index.contextLimit, got.length(), e);
888     log.append(a).
889         append((UChar)0x7b/*{*/).
890         append(b).
891         append((UChar)0x7c/*|*/).
892         append(c).
893         append((UChar)0x7c).
894         append(d).
895         append((UChar)0x7d/*}*/).
896         append(e);
897     if (got == expected)
898         logln("OK:" + prettify(log));
899     else
900         errln("FAIL: " + prettify(log)  + ", expected " + prettify(expected));
901 }
902 
903 
904 /*Internal Functions used*/
doTest(const UnicodeString & message,const UnicodeString & result,const UnicodeString & expected)905 void TransliteratorAPITest::doTest(const UnicodeString& message, const UnicodeString& result, const UnicodeString& expected){
906     if (prettify(result) == prettify(expected))
907         logln((UnicodeString)"Ok: " + prettify(message) + " passed \"" + prettify(expected) + "\"");
908     else
909         dataerrln((UnicodeString)"FAIL:" + message + " failed  Got-->" + prettify(result)+ ", Expected--> " + prettify(expected) );
910 }
911 
912 
913 //
914 //  callEverything    call all of the const (non-destructive) methods on a
915 //                    transliterator, just to verify that they don't fail in some
916 //                    destructive way.
917 //
918 #define CEASSERT(a) UPRV_BLOCK_MACRO_BEGIN { \
919     if (!(a)) { \
920         errln("FAIL at line %d from line %d: %s", __LINE__, line, #a); \
921         return; \
922     } \
923 } UPRV_BLOCK_MACRO_END
924 
callEverything(const Transliterator * tr,int line)925 void TransliteratorAPITest::callEverything(const Transliterator *tr, int line) {
926     Transliterator *clonedTR = tr->clone();
927     CEASSERT(clonedTR != NULL);
928 
929     int32_t  maxcl = tr->getMaximumContextLength();
930     CEASSERT(clonedTR->getMaximumContextLength() == maxcl);
931 
932     UnicodeString id;
933     UnicodeString clonedId;
934     id = tr->getID();
935     clonedId = clonedTR->getID();
936     CEASSERT(id == clonedId);
937 
938     const UnicodeFilter *filter = tr->getFilter();
939     const UnicodeFilter *clonedFilter = clonedTR->getFilter();
940     if (filter == NULL || clonedFilter == NULL) {
941         // If one filter is NULL they better both be NULL.
942         CEASSERT(filter == clonedFilter);
943     } else {
944         CEASSERT(filter != clonedFilter);
945     }
946 
947     UnicodeString rules;
948     UnicodeString clonedRules;
949     rules = tr->toRules(rules, FALSE);
950     clonedRules = clonedTR->toRules(clonedRules, FALSE);
951     CEASSERT(rules == clonedRules);
952 
953     UnicodeSet sourceSet;
954     UnicodeSet clonedSourceSet;
955     tr->getSourceSet(sourceSet);
956     clonedTR->getSourceSet(clonedSourceSet);
957     CEASSERT(clonedSourceSet == sourceSet);
958 
959     UnicodeSet targetSet;
960     UnicodeSet clonedTargetSet;
961     tr->getTargetSet(targetSet);
962     clonedTR->getTargetSet(clonedTargetSet);
963     CEASSERT(targetSet == clonedTargetSet);
964 
965     UClassID classID = tr->getDynamicClassID();
966     CEASSERT(classID == clonedTR->getDynamicClassID());
967     CEASSERT(classID != 0);
968 
969     delete clonedTR;
970 }
971 
972 static const int MyUnicodeFunctorTestClassID = 0;
973 class MyUnicodeFunctorTestClass : public UnicodeFunctor {
974 public:
clone() const975     virtual UnicodeFunctor* clone() const {return NULL;}
getStaticClassID(void)976     static UClassID getStaticClassID(void) {return (UClassID)&MyUnicodeFunctorTestClassID;}
getDynamicClassID(void) const977     virtual UClassID getDynamicClassID(void) const {return getStaticClassID();}
setData(const TransliterationRuleData *)978     virtual void setData(const TransliterationRuleData*) {}
979 };
980 
TestUnicodeFunctor()981 void TransliteratorAPITest::TestUnicodeFunctor() {
982     MyUnicodeFunctorTestClass myClass;
983     if (myClass.toMatcher() != NULL) {
984         errln("FAIL: UnicodeFunctor::toMatcher did not return NULL");
985     }
986     if (myClass.toReplacer() != NULL) {
987         errln("FAIL: UnicodeFunctor::toReplacer did not return NULL");
988     }
989 }
990 
991 
992 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
993