1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_i18npool.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include "transliterationImpl.hxx"
32*cdf0e10cSrcweir #include "servicename.hxx"
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include <com/sun/star/i18n/TransliterationType.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/container/XContentEnumerationAccess.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/container/XEnumeration.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
42*cdf0e10cSrcweir #include <rtl/string.h>
43*cdf0e10cSrcweir #include <rtl/ustring.hxx>
44*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
45*cdf0e10cSrcweir 
46*cdf0e10cSrcweir #include <algorithm>
47*cdf0e10cSrcweir 
48*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
49*cdf0e10cSrcweir #include <stdio.h>
50*cdf0e10cSrcweir #endif
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir using namespace com::sun::star::uno;
53*cdf0e10cSrcweir using namespace com::sun::star::lang;
54*cdf0e10cSrcweir using namespace rtl;
55*cdf0e10cSrcweir using namespace com::sun::star::container;
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir namespace com { namespace sun { namespace star { namespace i18n {
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir #define ERROR RuntimeException()
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir #define TmItem1( name ) \
62*cdf0e10cSrcweir   {TransliterationModules_##name, TransliterationModulesNew_##name, #name}
63*cdf0e10cSrcweir 
64*cdf0e10cSrcweir #define TmItem2( name ) \
65*cdf0e10cSrcweir   {(TransliterationModules)0, TransliterationModulesNew_##name, #name}
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir // Ignore Module list
68*cdf0e10cSrcweir static struct TMlist {
69*cdf0e10cSrcweir   TransliterationModules        tm;
70*cdf0e10cSrcweir   TransliterationModulesNew     tmn;
71*cdf0e10cSrcweir   const sal_Char               *implName;
72*cdf0e10cSrcweir } TMlist[] = {                                  //      Modules      ModulesNew
73*cdf0e10cSrcweir   TmItem1 (IGNORE_CASE),                        // 0. (1<<8        256) (7)
74*cdf0e10cSrcweir   TmItem1 (IGNORE_WIDTH),                       // 1. (1<<9        512) (8)
75*cdf0e10cSrcweir   TmItem1 (IGNORE_KANA),                        // 2. (1<<10      1024) (9)
76*cdf0e10cSrcweir // No enum define for this trans. application has to use impl name to load it
77*cdf0e10cSrcweir //  TmItem1 (IGNORE_CASE_SIMPLE),                       // (1<<11      1024) (66)
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir   TmItem1 (ignoreTraditionalKanji_ja_JP),       // 3. (1<<12      4096) (10)
80*cdf0e10cSrcweir   TmItem1 (ignoreTraditionalKana_ja_JP),        // 4. (1<<13      8192) (11)
81*cdf0e10cSrcweir   TmItem1 (ignoreMinusSign_ja_JP),              // 5. (1<<13     16384) (12)
82*cdf0e10cSrcweir   TmItem1 (ignoreIterationMark_ja_JP),          // 6. (1<<14     32768) (13)
83*cdf0e10cSrcweir   TmItem1 (ignoreSeparator_ja_JP),              // 7. (1<<15     65536) (14)
84*cdf0e10cSrcweir   TmItem1 (ignoreSize_ja_JP),                   // 15. (1<<23  16777216) (22)
85*cdf0e10cSrcweir   TmItem1 (ignoreMiddleDot_ja_JP),              // 17. (1<<25  67108864) (24)
86*cdf0e10cSrcweir   TmItem1 (ignoreSpace_ja_JP),                  // 18. (1<<26 134217728) (25)
87*cdf0e10cSrcweir   TmItem1 (ignoreZiZu_ja_JP),                   // 8. (1<<16    131072) (15)
88*cdf0e10cSrcweir   TmItem1 (ignoreBaFa_ja_JP),                   // 9. (1<<17    262144) (16)
89*cdf0e10cSrcweir   TmItem1 (ignoreTiJi_ja_JP),                   // 10. (1<<18    524288) (17)
90*cdf0e10cSrcweir   TmItem1 (ignoreHyuByu_ja_JP),                 // 11. (1<<19   1048576) (18)
91*cdf0e10cSrcweir   TmItem1 (ignoreSeZe_ja_JP),                   // 12. (1<<20   2097152) (19)
92*cdf0e10cSrcweir   TmItem1 (ignoreIandEfollowedByYa_ja_JP),      // 13. (1<<21   4194304) (20)
93*cdf0e10cSrcweir   TmItem1 (ignoreKiKuFollowedBySa_ja_JP),       // 14. (1<<22   8388608) (21)
94*cdf0e10cSrcweir   TmItem1 (ignoreProlongedSoundMark_ja_JP),     // 16. (1<<24  33554432) (23)
95*cdf0e10cSrcweir 
96*cdf0e10cSrcweir   TmItem1 (UPPERCASE_LOWERCASE),        // 19. (1) (1)
97*cdf0e10cSrcweir   TmItem1 (LOWERCASE_UPPERCASE),        // 20. (2) (2)
98*cdf0e10cSrcweir   TmItem1 (HALFWIDTH_FULLWIDTH),        // 21. (3) (3)
99*cdf0e10cSrcweir   TmItem1 (FULLWIDTH_HALFWIDTH),        // 22. (4) (4)
100*cdf0e10cSrcweir   TmItem1 (KATAKANA_HIRAGANA),          // 23. (5) (5)
101*cdf0e10cSrcweir   TmItem1 (HIRAGANA_KATAKANA),          // 24. (6) (6)
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir   TmItem1 (smallToLarge_ja_JP),         // 25. (1<<27 268435456) (26)
104*cdf0e10cSrcweir   TmItem1 (largeToSmall_ja_JP),         // 26. (1<<28 536870912) (27)
105*cdf0e10cSrcweir   TmItem2 (NumToTextLower_zh_CN),       // 27. () (28)
106*cdf0e10cSrcweir   TmItem2 (NumToTextUpper_zh_CN),       // 28. () (29)
107*cdf0e10cSrcweir   TmItem2 (NumToTextLower_zh_TW),       // 29. () (30)
108*cdf0e10cSrcweir   TmItem2 (NumToTextUpper_zh_TW),       // 30. () (31)
109*cdf0e10cSrcweir   TmItem2 (NumToTextFormalHangul_ko),   // 31. () (32)
110*cdf0e10cSrcweir   TmItem2 (NumToTextFormalLower_ko),    // 32. () (33)
111*cdf0e10cSrcweir   TmItem2 (NumToTextFormalUpper_ko),    // 33. () (34)
112*cdf0e10cSrcweir   TmItem2 (NumToTextInformalHangul_ko), // 34. () (35)
113*cdf0e10cSrcweir   TmItem2 (NumToTextInformalLower_ko),  // 35. () (36)
114*cdf0e10cSrcweir   TmItem2 (NumToTextInformalUpper_ko),  // 36. () (37)
115*cdf0e10cSrcweir   TmItem2 (NumToCharLower_zh_CN),       // 37. () (38)
116*cdf0e10cSrcweir   TmItem2 (NumToCharUpper_zh_CN),       // 38. () (39)
117*cdf0e10cSrcweir   TmItem2 (NumToCharLower_zh_TW),       // 39. () (40)
118*cdf0e10cSrcweir   TmItem2 (NumToCharUpper_zh_TW),       // 40. () (41)
119*cdf0e10cSrcweir   TmItem2 (NumToCharHangul_ko),         // 41. () (42)
120*cdf0e10cSrcweir   TmItem2 (NumToCharLower_ko),          // 42. () (43)
121*cdf0e10cSrcweir   TmItem2 (NumToCharUpper_ko),          // 43. () (44)
122*cdf0e10cSrcweir   TmItem2 (NumToCharFullwidth),         // 44. () (45)
123*cdf0e10cSrcweir   TmItem2 (NumToCharKanjiShort_ja_JP),  // 45. () (46)
124*cdf0e10cSrcweir   TmItem2 (TextToNumLower_zh_CN),       // 46. () (47)
125*cdf0e10cSrcweir   TmItem2 (TextToNumUpper_zh_CN),       // 47. () (48)
126*cdf0e10cSrcweir   TmItem2 (TextToNumLower_zh_TW),       // 48. () (49)
127*cdf0e10cSrcweir   TmItem2 (TextToNumUpper_zh_TW),       // 49. () (50)
128*cdf0e10cSrcweir   TmItem2 (TextToNumFormalHangul_ko),   // 50. () (51)
129*cdf0e10cSrcweir   TmItem2 (TextToNumFormalLower_ko),    // 51. () (52)
130*cdf0e10cSrcweir   TmItem2 (TextToNumFormalUpper_ko),    // 52. () (53)
131*cdf0e10cSrcweir   TmItem2 (TextToNumInformalHangul_ko), // 53. () (54)
132*cdf0e10cSrcweir   TmItem2 (TextToNumInformalLower_ko),  // 54. () (55)
133*cdf0e10cSrcweir   TmItem2 (TextToNumInformalUpper_ko),  // 55. () (56)
134*cdf0e10cSrcweir 
135*cdf0e10cSrcweir   TmItem2 (CharToNumLower_zh_CN),       // 56. () (59)
136*cdf0e10cSrcweir   TmItem2 (CharToNumUpper_zh_CN),       // 57. () (60)
137*cdf0e10cSrcweir   TmItem2 (CharToNumLower_zh_TW),       // 58. () (61)
138*cdf0e10cSrcweir   TmItem2 (CharToNumUpper_zh_TW),       // 59. () (62)
139*cdf0e10cSrcweir   TmItem2 (CharToNumHangul_ko),         // 60. () (63)
140*cdf0e10cSrcweir   TmItem2 (CharToNumLower_ko),          // 61. () (64)
141*cdf0e10cSrcweir   TmItem2 (CharToNumUpper_ko),          // 62. () (65)
142*cdf0e10cSrcweir 
143*cdf0e10cSrcweir // no enum defined for these trans. application has to use impl name to load them
144*cdf0e10cSrcweir //  TmItem2 (NumToCharArabic_Indic),    // () (67)
145*cdf0e10cSrcweir //  TmItem2 (NumToCharEstern_Arabic_Indic),// () (68)
146*cdf0e10cSrcweir //  TmItem2 (NumToCharIndic),           // () (69)
147*cdf0e10cSrcweir //  TmItem2 (NumToCharThai),            // () (70)
148*cdf0e10cSrcweir   {(TransliterationModules)0, (TransliterationModulesNew)0,  NULL}
149*cdf0e10cSrcweir };
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir TransliterationImpl::TransBody TransliterationImpl::lastTransBody;
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir // Constructor/Destructor
154*cdf0e10cSrcweir TransliterationImpl::TransliterationImpl(const Reference <XMultiServiceFactory>& xMSF) : xSMgr(xMSF)
155*cdf0e10cSrcweir {
156*cdf0e10cSrcweir     numCascade = 0;
157*cdf0e10cSrcweir     caseignoreOnly = sal_True;
158*cdf0e10cSrcweir 
159*cdf0e10cSrcweir     if ( xMSF.is() )
160*cdf0e10cSrcweir     {
161*cdf0e10cSrcweir         Reference < XInterface > xI=
162*cdf0e10cSrcweir                 xMSF->createInstance(OUString::createFromAscii("com.sun.star.i18n.LocaleData"));
163*cdf0e10cSrcweir         if ( xI.is() ) {
164*cdf0e10cSrcweir             Any x = xI->queryInterface( ::getCppuType( (const uno::Reference< i18n::XLocaleData >*)0) );
165*cdf0e10cSrcweir             x >>= localedata;
166*cdf0e10cSrcweir         }
167*cdf0e10cSrcweir     }
168*cdf0e10cSrcweir }
169*cdf0e10cSrcweir 
170*cdf0e10cSrcweir TransliterationImpl::~TransliterationImpl()
171*cdf0e10cSrcweir {
172*cdf0e10cSrcweir     localedata.clear();
173*cdf0e10cSrcweir     clear();
174*cdf0e10cSrcweir }
175*cdf0e10cSrcweir 
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir // Methods
178*cdf0e10cSrcweir OUString SAL_CALL
179*cdf0e10cSrcweir TransliterationImpl::getName() throw(RuntimeException)
180*cdf0e10cSrcweir {
181*cdf0e10cSrcweir     if (numCascade == 1 && bodyCascade[0].is())
182*cdf0e10cSrcweir         return bodyCascade[0]->getName();
183*cdf0e10cSrcweir     if (numCascade < 1)
184*cdf0e10cSrcweir         return ( OUString::createFromAscii("Not Loaded"));
185*cdf0e10cSrcweir     throw ERROR;
186*cdf0e10cSrcweir }
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir sal_Int16 SAL_CALL
189*cdf0e10cSrcweir TransliterationImpl::getType() throw(RuntimeException)
190*cdf0e10cSrcweir {
191*cdf0e10cSrcweir     if (numCascade > 1)
192*cdf0e10cSrcweir         return (TransliterationType::CASCADE|TransliterationType::IGNORE);
193*cdf0e10cSrcweir     if (numCascade > 0 && bodyCascade[0].is())
194*cdf0e10cSrcweir         return(bodyCascade[0]->getType());
195*cdf0e10cSrcweir     throw ERROR;
196*cdf0e10cSrcweir }
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir void SAL_CALL
199*cdf0e10cSrcweir TransliterationImpl::loadModule( TransliterationModules modType, const Locale& rLocale )
200*cdf0e10cSrcweir         throw(RuntimeException)
201*cdf0e10cSrcweir {
202*cdf0e10cSrcweir         clear();
203*cdf0e10cSrcweir     if (modType&TransliterationModules_IGNORE_MASK && modType&TransliterationModules_NON_IGNORE_MASK) {
204*cdf0e10cSrcweir         throw ERROR;
205*cdf0e10cSrcweir     } else if (modType&TransliterationModules_IGNORE_MASK) {
206*cdf0e10cSrcweir #define TransliterationModules_IGNORE_CASE_MASK (TransliterationModules_IGNORE_CASE | \
207*cdf0e10cSrcweir                                                 TransliterationModules_IGNORE_WIDTH | \
208*cdf0e10cSrcweir                                                 TransliterationModules_IGNORE_KANA)
209*cdf0e10cSrcweir         sal_Int32 mask = ((modType&TransliterationModules_IGNORE_CASE_MASK) == modType) ?
210*cdf0e10cSrcweir                 TransliterationModules_IGNORE_CASE_MASK : TransliterationModules_IGNORE_MASK;
211*cdf0e10cSrcweir         for (sal_Int16 i = 0; TMlist[i].tm & mask; i++) {
212*cdf0e10cSrcweir             if (modType & TMlist[i].tm)
213*cdf0e10cSrcweir                 if (loadModuleByName(OUString::createFromAscii(TMlist[i].implName),
214*cdf0e10cSrcweir                                                 bodyCascade[numCascade], rLocale))
215*cdf0e10cSrcweir                     numCascade++;
216*cdf0e10cSrcweir         }
217*cdf0e10cSrcweir     } else if (modType&TransliterationModules_NON_IGNORE_MASK) {
218*cdf0e10cSrcweir         for (sal_Int16 i = 0; TMlist[i].tm; i++) {
219*cdf0e10cSrcweir             if (TMlist[i].tm == modType) {
220*cdf0e10cSrcweir                 if (loadModuleByName(OUString::createFromAscii(TMlist[i].implName), bodyCascade[numCascade], rLocale))
221*cdf0e10cSrcweir                     numCascade++;
222*cdf0e10cSrcweir                 break;
223*cdf0e10cSrcweir             }
224*cdf0e10cSrcweir         }
225*cdf0e10cSrcweir     }
226*cdf0e10cSrcweir }
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir void SAL_CALL
229*cdf0e10cSrcweir TransliterationImpl::loadModuleNew( const Sequence < TransliterationModulesNew > & modType, const Locale& rLocale )
230*cdf0e10cSrcweir   throw(RuntimeException)
231*cdf0e10cSrcweir {
232*cdf0e10cSrcweir     clear();
233*cdf0e10cSrcweir     sal_Int32 mask = 0, count = modType.getLength();
234*cdf0e10cSrcweir     if (count > maxCascade)
235*cdf0e10cSrcweir         throw ERROR; // could not handle more than maxCascade
236*cdf0e10cSrcweir     for (sal_Int16 i = 0; i < count; i++) {
237*cdf0e10cSrcweir         for (sal_Int16 j = 0; TMlist[j].tmn; j++) {
238*cdf0e10cSrcweir             if (TMlist[j].tmn == modType[i]) {
239*cdf0e10cSrcweir                 if (mask == 0)
240*cdf0e10cSrcweir                     mask = TMlist[i].tm && (TMlist[i].tm&TransliterationModules_IGNORE_MASK) ?
241*cdf0e10cSrcweir                         TransliterationModules_IGNORE_MASK : TransliterationModules_NON_IGNORE_MASK;
242*cdf0e10cSrcweir                 else if (mask == TransliterationModules_IGNORE_MASK &&
243*cdf0e10cSrcweir                         (TMlist[i].tm&TransliterationModules_IGNORE_MASK) == 0)
244*cdf0e10cSrcweir                     throw ERROR; // could not mess up ignore trans. with non_ignore trans.
245*cdf0e10cSrcweir                 if (loadModuleByName(OUString::createFromAscii(TMlist[j].implName), bodyCascade[numCascade], rLocale))
246*cdf0e10cSrcweir                     numCascade++;
247*cdf0e10cSrcweir                 break;
248*cdf0e10cSrcweir             }
249*cdf0e10cSrcweir         }
250*cdf0e10cSrcweir     }
251*cdf0e10cSrcweir }
252*cdf0e10cSrcweir 
253*cdf0e10cSrcweir void SAL_CALL
254*cdf0e10cSrcweir TransliterationImpl::loadModuleByImplName(const OUString& implName, const Locale& rLocale)
255*cdf0e10cSrcweir   throw(RuntimeException)
256*cdf0e10cSrcweir {
257*cdf0e10cSrcweir     clear();
258*cdf0e10cSrcweir     if (loadModuleByName(implName, bodyCascade[numCascade], rLocale))
259*cdf0e10cSrcweir         numCascade++;
260*cdf0e10cSrcweir }
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir void SAL_CALL
264*cdf0e10cSrcweir TransliterationImpl::loadModulesByImplNames(const Sequence< OUString >& implNameList, const Locale& rLocale ) throw(RuntimeException)
265*cdf0e10cSrcweir {
266*cdf0e10cSrcweir     if (implNameList.getLength() > maxCascade || implNameList.getLength() <= 0)
267*cdf0e10cSrcweir         throw ERROR;
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir     clear();
270*cdf0e10cSrcweir     for (sal_Int32 i = 0; i < implNameList.getLength(); i++)
271*cdf0e10cSrcweir         if (loadModuleByName(implNameList[i], bodyCascade[numCascade], rLocale))
272*cdf0e10cSrcweir             numCascade++;
273*cdf0e10cSrcweir }
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir Sequence<OUString> SAL_CALL
277*cdf0e10cSrcweir TransliterationImpl::getAvailableModules( const Locale& rLocale, sal_Int16 sType ) throw(RuntimeException)
278*cdf0e10cSrcweir {
279*cdf0e10cSrcweir     const Sequence<OUString> &translist = localedata->getTransliterations(rLocale);
280*cdf0e10cSrcweir     Sequence<OUString> r(translist.getLength());
281*cdf0e10cSrcweir     Reference<XExtendedTransliteration> body;
282*cdf0e10cSrcweir     sal_Int32 n = 0;
283*cdf0e10cSrcweir     for (sal_Int32 i = 0; i < translist.getLength(); i++)
284*cdf0e10cSrcweir     {
285*cdf0e10cSrcweir         if (loadModuleByName(translist[i], body, rLocale)) {
286*cdf0e10cSrcweir             if (body->getType() & sType)
287*cdf0e10cSrcweir                 r[n++] = translist[i];
288*cdf0e10cSrcweir             body.clear();
289*cdf0e10cSrcweir         }
290*cdf0e10cSrcweir     }
291*cdf0e10cSrcweir     r.realloc(n);
292*cdf0e10cSrcweir     return (r);
293*cdf0e10cSrcweir }
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir 
296*cdf0e10cSrcweir OUString SAL_CALL
297*cdf0e10cSrcweir TransliterationImpl::transliterate( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
298*cdf0e10cSrcweir                     Sequence< sal_Int32 >& offset ) throw(RuntimeException)
299*cdf0e10cSrcweir {
300*cdf0e10cSrcweir     if (numCascade == 0)
301*cdf0e10cSrcweir         return inStr;
302*cdf0e10cSrcweir 
303*cdf0e10cSrcweir     if (offset.getLength() != nCount)
304*cdf0e10cSrcweir         offset.realloc(nCount);
305*cdf0e10cSrcweir     if (numCascade == 1)
306*cdf0e10cSrcweir     {
307*cdf0e10cSrcweir         if ( startPos == 0 && nCount == inStr.getLength() )
308*cdf0e10cSrcweir             return bodyCascade[0]->transliterate( inStr, 0, nCount, offset);
309*cdf0e10cSrcweir         else
310*cdf0e10cSrcweir         {
311*cdf0e10cSrcweir             OUString tmpStr = inStr.copy(startPos, nCount);
312*cdf0e10cSrcweir             tmpStr = bodyCascade[0]->transliterate(tmpStr, 0, nCount, offset);
313*cdf0e10cSrcweir             if ( startPos )
314*cdf0e10cSrcweir             {
315*cdf0e10cSrcweir                 sal_Int32 * pArr = offset.getArray();
316*cdf0e10cSrcweir                 nCount = offset.getLength();
317*cdf0e10cSrcweir                 for (sal_Int32 j = 0; j < nCount; j++)
318*cdf0e10cSrcweir                     pArr[j] += startPos;
319*cdf0e10cSrcweir             }
320*cdf0e10cSrcweir             return tmpStr;
321*cdf0e10cSrcweir         }
322*cdf0e10cSrcweir     }
323*cdf0e10cSrcweir     else
324*cdf0e10cSrcweir     {
325*cdf0e10cSrcweir         OUString tmpStr = inStr.copy(startPos, nCount);
326*cdf0e10cSrcweir         sal_Int32 * pArr = offset.getArray();
327*cdf0e10cSrcweir         for (sal_Int32 j = 0; j < nCount; j++)
328*cdf0e10cSrcweir             pArr[j] = startPos + j;
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir         sal_Int16 from = 0, to = 1, tmp;
331*cdf0e10cSrcweir         Sequence<sal_Int32> off[2];
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir         off[to] = offset;
334*cdf0e10cSrcweir         off[from].realloc(nCount);
335*cdf0e10cSrcweir         for (sal_Int32 i = 0; i < numCascade; i++) {
336*cdf0e10cSrcweir             tmpStr = bodyCascade[i]->transliterate(tmpStr, 0, nCount, off[from]);
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir             nCount = tmpStr.getLength();
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir             tmp = from; from = to; to = tmp;
341*cdf0e10cSrcweir             for (sal_Int32 j = 0; j < nCount; j++)
342*cdf0e10cSrcweir                 off[to][j] = off[from][off[to][j]];
343*cdf0e10cSrcweir         }
344*cdf0e10cSrcweir         offset = off[to];
345*cdf0e10cSrcweir         return tmpStr;
346*cdf0e10cSrcweir     }
347*cdf0e10cSrcweir }
348*cdf0e10cSrcweir 
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir //
351*cdf0e10cSrcweir OUString SAL_CALL
352*cdf0e10cSrcweir TransliterationImpl::folding( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
353*cdf0e10cSrcweir         Sequence< sal_Int32 >& offset ) throw(RuntimeException)
354*cdf0e10cSrcweir {
355*cdf0e10cSrcweir     if (numCascade == 0)
356*cdf0e10cSrcweir         return inStr;
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir     if (offset.getLength() != nCount)
359*cdf0e10cSrcweir         offset.realloc(nCount);
360*cdf0e10cSrcweir     if (numCascade == 1)
361*cdf0e10cSrcweir     {
362*cdf0e10cSrcweir         if ( startPos == 0 && nCount == inStr.getLength() )
363*cdf0e10cSrcweir             return bodyCascade[0]->folding( inStr, 0, nCount, offset);
364*cdf0e10cSrcweir         else
365*cdf0e10cSrcweir         {
366*cdf0e10cSrcweir             OUString tmpStr = inStr.copy(startPos, nCount);
367*cdf0e10cSrcweir             tmpStr = bodyCascade[0]->folding(tmpStr, 0, nCount, offset);
368*cdf0e10cSrcweir             if ( startPos )
369*cdf0e10cSrcweir             {
370*cdf0e10cSrcweir                 sal_Int32 * pArr = offset.getArray();
371*cdf0e10cSrcweir                 nCount = offset.getLength();
372*cdf0e10cSrcweir                 for (sal_Int32 j = 0; j < nCount; j++)
373*cdf0e10cSrcweir                     pArr[j] += startPos;
374*cdf0e10cSrcweir             }
375*cdf0e10cSrcweir             return tmpStr;
376*cdf0e10cSrcweir         }
377*cdf0e10cSrcweir     }
378*cdf0e10cSrcweir     else
379*cdf0e10cSrcweir     {
380*cdf0e10cSrcweir         OUString tmpStr = inStr.copy(startPos, nCount);
381*cdf0e10cSrcweir         sal_Int32 * pArr = offset.getArray();
382*cdf0e10cSrcweir         for (sal_Int32 j = 0; j < nCount; j++)
383*cdf0e10cSrcweir             pArr[j] = startPos + j;
384*cdf0e10cSrcweir 
385*cdf0e10cSrcweir         sal_Int16 from = 0, to = 1, tmp;
386*cdf0e10cSrcweir         Sequence<sal_Int32> off[2];
387*cdf0e10cSrcweir 
388*cdf0e10cSrcweir         off[to] = offset;
389*cdf0e10cSrcweir         for (sal_Int32 i = 0; i < numCascade; i++) {
390*cdf0e10cSrcweir             tmpStr = bodyCascade[i]->folding(tmpStr, 0, nCount, off[from]);
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir             nCount = tmpStr.getLength();
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir             tmp = from; from = to; to = tmp;
395*cdf0e10cSrcweir             for (sal_Int32 j = 0; j < nCount; j++)
396*cdf0e10cSrcweir                 off[to][j] = off[from][off[to][j]];
397*cdf0e10cSrcweir         }
398*cdf0e10cSrcweir         offset = off[to];
399*cdf0e10cSrcweir         return tmpStr;
400*cdf0e10cSrcweir     }
401*cdf0e10cSrcweir }
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir OUString SAL_CALL
404*cdf0e10cSrcweir TransliterationImpl::transliterateString2String( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount ) throw(RuntimeException)
405*cdf0e10cSrcweir {
406*cdf0e10cSrcweir     if (numCascade == 0)
407*cdf0e10cSrcweir         return inStr;
408*cdf0e10cSrcweir     else if (numCascade == 1)
409*cdf0e10cSrcweir         return bodyCascade[0]->transliterateString2String( inStr, startPos, nCount);
410*cdf0e10cSrcweir     else {
411*cdf0e10cSrcweir         OUString tmpStr = bodyCascade[0]->transliterateString2String(inStr, startPos, nCount);
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir         for (sal_Int32 i = 1; i < numCascade; i++)
414*cdf0e10cSrcweir             tmpStr = bodyCascade[i]->transliterateString2String(tmpStr, 0, tmpStr.getLength());
415*cdf0e10cSrcweir         return tmpStr;
416*cdf0e10cSrcweir     }
417*cdf0e10cSrcweir }
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir OUString SAL_CALL
420*cdf0e10cSrcweir TransliterationImpl::transliterateChar2String( sal_Unicode inChar ) throw(RuntimeException)
421*cdf0e10cSrcweir {
422*cdf0e10cSrcweir     if (numCascade == 0)
423*cdf0e10cSrcweir         return OUString(&inChar, 1);
424*cdf0e10cSrcweir     else if (numCascade == 1)
425*cdf0e10cSrcweir         return bodyCascade[0]->transliterateChar2String( inChar);
426*cdf0e10cSrcweir     else {
427*cdf0e10cSrcweir         OUString tmpStr = bodyCascade[0]->transliterateChar2String(inChar);
428*cdf0e10cSrcweir 
429*cdf0e10cSrcweir         for (sal_Int32 i = 1; i < numCascade; i++)
430*cdf0e10cSrcweir             tmpStr = bodyCascade[i]->transliterateString2String(tmpStr, 0, tmpStr.getLength());
431*cdf0e10cSrcweir         return tmpStr;
432*cdf0e10cSrcweir     }
433*cdf0e10cSrcweir }
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir sal_Unicode SAL_CALL
436*cdf0e10cSrcweir TransliterationImpl::transliterateChar2Char( sal_Unicode inChar ) throw(MultipleCharsOutputException, RuntimeException)
437*cdf0e10cSrcweir {
438*cdf0e10cSrcweir     sal_Unicode tmpChar = inChar;
439*cdf0e10cSrcweir     for (sal_Int32 i = 0; i < numCascade; i++)
440*cdf0e10cSrcweir         tmpChar = bodyCascade[i]->transliterateChar2Char(tmpChar);
441*cdf0e10cSrcweir     return tmpChar;
442*cdf0e10cSrcweir }
443*cdf0e10cSrcweir 
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir sal_Bool SAL_CALL
446*cdf0e10cSrcweir TransliterationImpl::equals(
447*cdf0e10cSrcweir     const OUString& str1, sal_Int32 pos1, sal_Int32 nCount1, sal_Int32& nMatch1,
448*cdf0e10cSrcweir     const OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2)
449*cdf0e10cSrcweir     throw(RuntimeException)
450*cdf0e10cSrcweir {
451*cdf0e10cSrcweir     // since this is an API function make it user fail safe
452*cdf0e10cSrcweir     if ( nCount1 < 0 ) {
453*cdf0e10cSrcweir         pos1 += nCount1;
454*cdf0e10cSrcweir         nCount1 = -nCount1;
455*cdf0e10cSrcweir     }
456*cdf0e10cSrcweir     if ( nCount2 < 0 ) {
457*cdf0e10cSrcweir         pos2 += nCount2;
458*cdf0e10cSrcweir         nCount2 = -nCount2;
459*cdf0e10cSrcweir     }
460*cdf0e10cSrcweir     if ( !nCount1 || !nCount2 ||
461*cdf0e10cSrcweir             pos1 >= str1.getLength() || pos2 >= str2.getLength() ||
462*cdf0e10cSrcweir             pos1 < 0 || pos2 < 0 ) {
463*cdf0e10cSrcweir         nMatch1 = nMatch2 = 0;
464*cdf0e10cSrcweir         // two empty strings return true, else false
465*cdf0e10cSrcweir         return !nCount1 && !nCount2 && pos1 == str1.getLength() && pos2 == str2.getLength();
466*cdf0e10cSrcweir     }
467*cdf0e10cSrcweir     if ( pos1 + nCount1 > str1.getLength() )
468*cdf0e10cSrcweir         nCount1 = str1.getLength() - pos1;
469*cdf0e10cSrcweir     if ( pos2 + nCount2 > str2.getLength() )
470*cdf0e10cSrcweir         nCount2 = str2.getLength() - pos2;
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir     if (caseignoreOnly && caseignore.is())
473*cdf0e10cSrcweir         return caseignore->equals(str1, pos1, nCount1, nMatch1, str2, pos2, nCount2, nMatch2);
474*cdf0e10cSrcweir 
475*cdf0e10cSrcweir     Sequence<sal_Int32> offset1, offset2;
476*cdf0e10cSrcweir 
477*cdf0e10cSrcweir     OUString tmpStr1 = folding(str1, pos1, nCount1, offset1);
478*cdf0e10cSrcweir     OUString tmpStr2 = folding(str2, pos2, nCount2, offset2);
479*cdf0e10cSrcweir     // Length of offset1 and offset2 may still be 0 if there was no folding
480*cdf0e10cSrcweir     // necessary!
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir     const sal_Unicode *p1 = tmpStr1.getStr();
483*cdf0e10cSrcweir     const sal_Unicode *p2 = tmpStr2.getStr();
484*cdf0e10cSrcweir     sal_Int32 i, nLen = ::std::min( tmpStr1.getLength(), tmpStr2.getLength());
485*cdf0e10cSrcweir     for (i = 0; i < nLen; ++i, ++p1, ++p2 ) {
486*cdf0e10cSrcweir         if (*p1 != *p2) {
487*cdf0e10cSrcweir             // return number of matched code points so far
488*cdf0e10cSrcweir             nMatch1 = (i < offset1.getLength()) ? offset1[i] : i;
489*cdf0e10cSrcweir             nMatch2 = (i < offset2.getLength()) ? offset2[i] : i;
490*cdf0e10cSrcweir             return sal_False;
491*cdf0e10cSrcweir         }
492*cdf0e10cSrcweir     }
493*cdf0e10cSrcweir     // i==nLen
494*cdf0e10cSrcweir     if ( tmpStr1.getLength() != tmpStr2.getLength() ) {
495*cdf0e10cSrcweir         // return number of matched code points so far
496*cdf0e10cSrcweir         nMatch1 = (i <= offset1.getLength()) ? offset1[i-1] + 1 : i;
497*cdf0e10cSrcweir         nMatch2 = (i <= offset2.getLength()) ? offset2[i-1] + 1 : i;
498*cdf0e10cSrcweir         return sal_False;
499*cdf0e10cSrcweir     } else {
500*cdf0e10cSrcweir         nMatch1 = nCount1;
501*cdf0e10cSrcweir         nMatch2 = nCount2;
502*cdf0e10cSrcweir         return sal_True;
503*cdf0e10cSrcweir     }
504*cdf0e10cSrcweir }
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir #define MaxOutput 2
507*cdf0e10cSrcweir 
508*cdf0e10cSrcweir Sequence< OUString > SAL_CALL
509*cdf0e10cSrcweir TransliterationImpl::getRange(const Sequence< OUString > &inStrs,
510*cdf0e10cSrcweir                 const sal_Int32 length, sal_Int16 _numCascade) throw(RuntimeException)
511*cdf0e10cSrcweir {
512*cdf0e10cSrcweir     if (_numCascade >= numCascade || ! bodyCascade[_numCascade].is())
513*cdf0e10cSrcweir         return inStrs;
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir     sal_Int32 j_tmp = 0;
516*cdf0e10cSrcweir     Sequence< OUString > ostr(MaxOutput*length);
517*cdf0e10cSrcweir     for (sal_Int32 j = 0; j < length; j+=2) {
518*cdf0e10cSrcweir         const Sequence< OUString >& temp = bodyCascade[_numCascade]->transliterateRange(inStrs[j], inStrs[j+1]);
519*cdf0e10cSrcweir 
520*cdf0e10cSrcweir         for ( sal_Int32 k = 0; k < temp.getLength(); k++) {
521*cdf0e10cSrcweir             if ( j_tmp >= MaxOutput*length ) throw ERROR;
522*cdf0e10cSrcweir             ostr[j_tmp++]  = temp[k];
523*cdf0e10cSrcweir         }
524*cdf0e10cSrcweir     }
525*cdf0e10cSrcweir     ostr.realloc(j_tmp);
526*cdf0e10cSrcweir 
527*cdf0e10cSrcweir     return this->getRange(ostr, j_tmp, ++_numCascade);
528*cdf0e10cSrcweir }
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir 
531*cdf0e10cSrcweir Sequence< OUString > SAL_CALL
532*cdf0e10cSrcweir TransliterationImpl::transliterateRange( const OUString& str1, const OUString& str2 )
533*cdf0e10cSrcweir throw(RuntimeException)
534*cdf0e10cSrcweir {
535*cdf0e10cSrcweir     if (numCascade == 1)
536*cdf0e10cSrcweir         return bodyCascade[0]->transliterateRange(str1, str2);
537*cdf0e10cSrcweir 
538*cdf0e10cSrcweir     Sequence< OUString > ostr(2);
539*cdf0e10cSrcweir     ostr[0] = str1;
540*cdf0e10cSrcweir     ostr[1] = str2;
541*cdf0e10cSrcweir 
542*cdf0e10cSrcweir     return this->getRange(ostr, 2, 0);
543*cdf0e10cSrcweir }
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir 
546*cdf0e10cSrcweir sal_Int32 SAL_CALL
547*cdf0e10cSrcweir TransliterationImpl::compareSubstring(
548*cdf0e10cSrcweir     const OUString& str1, sal_Int32 off1, sal_Int32 len1,
549*cdf0e10cSrcweir     const OUString& str2, sal_Int32 off2, sal_Int32 len2)
550*cdf0e10cSrcweir     throw(RuntimeException)
551*cdf0e10cSrcweir {
552*cdf0e10cSrcweir     if (caseignoreOnly && caseignore.is())
553*cdf0e10cSrcweir         return caseignore->compareSubstring(str1, off1, len1, str2, off2, len2);
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir     Sequence <sal_Int32> offset;
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir     OUString in_str1 = this->transliterate(str1, off1, len1, offset);
558*cdf0e10cSrcweir     OUString in_str2 = this->transliterate(str2, off2, len2, offset);
559*cdf0e10cSrcweir     const sal_Unicode* unistr1 = in_str1.getStr();
560*cdf0e10cSrcweir     const sal_Unicode* unistr2 = in_str2.getStr();
561*cdf0e10cSrcweir     sal_Int32 strlen1 = in_str1.getLength();
562*cdf0e10cSrcweir     sal_Int32 strlen2 = in_str2.getLength();
563*cdf0e10cSrcweir 
564*cdf0e10cSrcweir     while (strlen1 && strlen2) {
565*cdf0e10cSrcweir         if (*unistr1 != *unistr2)
566*cdf0e10cSrcweir            return *unistr1 > *unistr2 ? 1 : -1;
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir         unistr1++; unistr2++; strlen1--; strlen2--;
569*cdf0e10cSrcweir     }
570*cdf0e10cSrcweir     return strlen1 == strlen2 ? 0 : (strlen1 > strlen2 ? 1 : -1);
571*cdf0e10cSrcweir }
572*cdf0e10cSrcweir 
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir sal_Int32 SAL_CALL
575*cdf0e10cSrcweir TransliterationImpl::compareString(const OUString& str1, const OUString& str2 ) throw (RuntimeException)
576*cdf0e10cSrcweir {
577*cdf0e10cSrcweir     if (caseignoreOnly && caseignore.is())
578*cdf0e10cSrcweir         return caseignore->compareString(str1, str2);
579*cdf0e10cSrcweir     else
580*cdf0e10cSrcweir         return this->compareSubstring(str1, 0, str1.getLength(), str2, 0, str2.getLength());
581*cdf0e10cSrcweir }
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir void
585*cdf0e10cSrcweir TransliterationImpl::clear()
586*cdf0e10cSrcweir {
587*cdf0e10cSrcweir     for (sal_Int32 i = 0; i < numCascade; i++)
588*cdf0e10cSrcweir         if (bodyCascade[i].is())
589*cdf0e10cSrcweir             bodyCascade[i].clear();
590*cdf0e10cSrcweir     numCascade = 0;
591*cdf0e10cSrcweir     caseignore.clear();
592*cdf0e10cSrcweir     caseignoreOnly = sal_True;
593*cdf0e10cSrcweir }
594*cdf0e10cSrcweir 
595*cdf0e10cSrcweir void TransliterationImpl::loadBody( OUString &implName, Reference<XExtendedTransliteration>& body )
596*cdf0e10cSrcweir     throw (RuntimeException)
597*cdf0e10cSrcweir {
598*cdf0e10cSrcweir     ::osl::MutexGuard guard(lastTransBody.mutex);
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir     if (implName.equals(lastTransBody.Name))
601*cdf0e10cSrcweir     {
602*cdf0e10cSrcweir         // Use the cached body instead of going through the expensive looping again.
603*cdf0e10cSrcweir         body = lastTransBody.Body;
604*cdf0e10cSrcweir         return;
605*cdf0e10cSrcweir     }
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir     Reference< XContentEnumerationAccess > xEnumAccess( xSMgr, UNO_QUERY );
608*cdf0e10cSrcweir     Reference< XEnumeration > xEnum(xEnumAccess->createContentEnumeration(
609*cdf0e10cSrcweir                                     OUString::createFromAscii(TRLT_SERVICELNAME_L10N)));
610*cdf0e10cSrcweir     if (xEnum.is()) {
611*cdf0e10cSrcweir         while (xEnum->hasMoreElements()) {
612*cdf0e10cSrcweir             Any a = xEnum->nextElement();
613*cdf0e10cSrcweir             Reference< XServiceInfo > xsInfo;
614*cdf0e10cSrcweir             if (a >>= xsInfo) {
615*cdf0e10cSrcweir                 if (implName.equals(xsInfo->getImplementationName())) {
616*cdf0e10cSrcweir                     Reference< XSingleServiceFactory > xFactory;
617*cdf0e10cSrcweir                     if (a >>= xFactory) {
618*cdf0e10cSrcweir                         Reference< XInterface > xI = xFactory->createInstance();
619*cdf0e10cSrcweir                         if (xI.is()) {
620*cdf0e10cSrcweir                             a = xI->queryInterface(::getCppuType((
621*cdf0e10cSrcweir                                         const Reference<XExtendedTransliteration>*)0));
622*cdf0e10cSrcweir                             a >>= body;
623*cdf0e10cSrcweir                             lastTransBody.Name = implName;
624*cdf0e10cSrcweir                             lastTransBody.Body = body;
625*cdf0e10cSrcweir                             return;
626*cdf0e10cSrcweir                         }
627*cdf0e10cSrcweir                     }
628*cdf0e10cSrcweir                 }
629*cdf0e10cSrcweir             }
630*cdf0e10cSrcweir         }
631*cdf0e10cSrcweir     }
632*cdf0e10cSrcweir     throw ERROR;
633*cdf0e10cSrcweir }
634*cdf0e10cSrcweir 
635*cdf0e10cSrcweir sal_Bool SAL_CALL
636*cdf0e10cSrcweir TransliterationImpl::loadModuleByName( const OUString& implName,
637*cdf0e10cSrcweir         Reference<XExtendedTransliteration>& body, const Locale& rLocale) throw(RuntimeException)
638*cdf0e10cSrcweir {
639*cdf0e10cSrcweir     OUString cname = OUString::createFromAscii(TRLT_IMPLNAME_PREFIX) + implName;
640*cdf0e10cSrcweir     loadBody(cname, body);
641*cdf0e10cSrcweir     if (body.is()) {
642*cdf0e10cSrcweir         body->loadModule((TransliterationModules)0, rLocale); // toUpper/toLoad need rLocale
643*cdf0e10cSrcweir 
644*cdf0e10cSrcweir         // if the module is ignore case/kana/width, load caseignore for equals/compareString mothed
645*cdf0e10cSrcweir         for (sal_Int16 i = 0; i < 3; i++) {
646*cdf0e10cSrcweir             if (implName.compareToAscii(TMlist[i].implName) == 0) {
647*cdf0e10cSrcweir                 if (i == 0) // current module is caseignore
648*cdf0e10cSrcweir                     body->loadModule(TMlist[0].tm, rLocale); // caseingore need to setup module name
649*cdf0e10cSrcweir                 if (! caseignore.is()) {
650*cdf0e10cSrcweir                     OUString bname = OUString::createFromAscii(TRLT_IMPLNAME_PREFIX) +
651*cdf0e10cSrcweir                                 OUString::createFromAscii(TMlist[0].implName);
652*cdf0e10cSrcweir                     loadBody(bname, caseignore);
653*cdf0e10cSrcweir                 }
654*cdf0e10cSrcweir                 if (caseignore.is())
655*cdf0e10cSrcweir                     caseignore->loadModule(TMlist[i].tm, rLocale);
656*cdf0e10cSrcweir                 return sal_True;
657*cdf0e10cSrcweir             }
658*cdf0e10cSrcweir         }
659*cdf0e10cSrcweir         caseignoreOnly = sal_False; // has other module than just ignore case/kana/width
660*cdf0e10cSrcweir     }
661*cdf0e10cSrcweir     return body.is();
662*cdf0e10cSrcweir }
663*cdf0e10cSrcweir 
664*cdf0e10cSrcweir const sal_Char cTrans[] = "com.sun.star.i18n.Transliteration";
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir OUString SAL_CALL
667*cdf0e10cSrcweir TransliterationImpl::getImplementationName() throw( RuntimeException )
668*cdf0e10cSrcweir {
669*cdf0e10cSrcweir     return OUString::createFromAscii(cTrans);
670*cdf0e10cSrcweir }
671*cdf0e10cSrcweir 
672*cdf0e10cSrcweir 
673*cdf0e10cSrcweir sal_Bool SAL_CALL
674*cdf0e10cSrcweir TransliterationImpl::supportsService(const OUString& rServiceName) throw( RuntimeException )
675*cdf0e10cSrcweir {
676*cdf0e10cSrcweir     return !rServiceName.compareToAscii(cTrans);
677*cdf0e10cSrcweir }
678*cdf0e10cSrcweir 
679*cdf0e10cSrcweir Sequence< OUString > SAL_CALL
680*cdf0e10cSrcweir TransliterationImpl::getSupportedServiceNames(void) throw( RuntimeException )
681*cdf0e10cSrcweir {
682*cdf0e10cSrcweir     Sequence< OUString > aRet(1);
683*cdf0e10cSrcweir     aRet[0] = OUString::createFromAscii(cTrans);
684*cdf0e10cSrcweir     return aRet;
685*cdf0e10cSrcweir }
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir } } } }
688