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