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