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