bump product version to 4.1.6.2
[LibreOffice.git] / i18npool / source / transliteration / transliterationImpl.cxx
blob918461b5dad9560308b684d25265d823e979d3ad
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "transliterationImpl.hxx"
22 #include "servicename.hxx"
24 #include <com/sun/star/i18n/LocaleData.hpp>
25 #include <com/sun/star/i18n/TransliterationType.hpp>
26 #include <com/sun/star/lang/XComponent.hpp>
28 #include <comphelper/componentcontext.hxx>
29 #include <comphelper/processfactory.hxx>
30 #include <rtl/instance.hxx>
31 #include <rtl/string.h>
32 #include <rtl/ustring.hxx>
33 #include <rtl/ustrbuf.hxx>
35 #include <algorithm>
37 #if OSL_DEBUG_LEVEL > 1
38 #include <stdio.h>
39 #endif
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::lang;
45 namespace com { namespace sun { namespace star { namespace i18n {
47 #define ERROR RuntimeException()
49 #define TmItem1( name ) \
50 {TransliterationModules_##name, TransliterationModulesNew_##name, #name}
52 #define TmItem2( name ) \
53 {(TransliterationModules)0, TransliterationModulesNew_##name, #name}
55 // Ignore Module list
56 static struct TMlist {
57 TransliterationModules tm;
58 TransliterationModulesNew tmn;
59 const sal_Char *implName;
60 } TMlist[] = { // Modules ModulesNew
61 TmItem1 (IGNORE_CASE), // 0. (1<<8 256) (7)
62 TmItem1 (IGNORE_WIDTH), // 1. (1<<9 512) (8)
63 TmItem1 (IGNORE_KANA), // 2. (1<<10 1024) (9)
64 // No enum define for this trans. application has to use impl name to load it
65 // TmItem1 (IGNORE_CASE_SIMPLE), // (1<<11 1024) (66)
67 TmItem1 (ignoreTraditionalKanji_ja_JP), // 3. (1<<12 4096) (10)
68 TmItem1 (ignoreTraditionalKana_ja_JP), // 4. (1<<13 8192) (11)
69 TmItem1 (ignoreMinusSign_ja_JP), // 5. (1<<13 16384) (12)
70 TmItem1 (ignoreIterationMark_ja_JP), // 6. (1<<14 32768) (13)
71 TmItem1 (ignoreSeparator_ja_JP), // 7. (1<<15 65536) (14)
72 TmItem1 (ignoreSize_ja_JP), // 15. (1<<23 16777216) (22)
73 TmItem1 (ignoreMiddleDot_ja_JP), // 17. (1<<25 67108864) (24)
74 TmItem1 (ignoreSpace_ja_JP), // 18. (1<<26 134217728) (25)
75 TmItem1 (ignoreZiZu_ja_JP), // 8. (1<<16 131072) (15)
76 TmItem1 (ignoreBaFa_ja_JP), // 9. (1<<17 262144) (16)
77 TmItem1 (ignoreTiJi_ja_JP), // 10. (1<<18 524288) (17)
78 TmItem1 (ignoreHyuByu_ja_JP), // 11. (1<<19 1048576) (18)
79 TmItem1 (ignoreSeZe_ja_JP), // 12. (1<<20 2097152) (19)
80 TmItem1 (ignoreIandEfollowedByYa_ja_JP), // 13. (1<<21 4194304) (20)
81 TmItem1 (ignoreKiKuFollowedBySa_ja_JP), // 14. (1<<22 8388608) (21)
82 TmItem1 (ignoreProlongedSoundMark_ja_JP), // 16. (1<<24 33554432) (23)
84 TmItem1 (UPPERCASE_LOWERCASE), // 19. (1) (1)
85 TmItem1 (LOWERCASE_UPPERCASE), // 20. (2) (2)
86 TmItem1 (HALFWIDTH_FULLWIDTH), // 21. (3) (3)
87 TmItem1 (FULLWIDTH_HALFWIDTH), // 22. (4) (4)
88 TmItem1 (KATAKANA_HIRAGANA), // 23. (5) (5)
89 TmItem1 (HIRAGANA_KATAKANA), // 24. (6) (6)
91 TmItem1 (smallToLarge_ja_JP), // 25. (1<<27 268435456) (26)
92 TmItem1 (largeToSmall_ja_JP), // 26. (1<<28 536870912) (27)
93 TmItem2 (NumToTextLower_zh_CN), // 27. () (28)
94 TmItem2 (NumToTextUpper_zh_CN), // 28. () (29)
95 TmItem2 (NumToTextLower_zh_TW), // 29. () (30)
96 TmItem2 (NumToTextUpper_zh_TW), // 30. () (31)
97 TmItem2 (NumToTextFormalHangul_ko), // 31. () (32)
98 TmItem2 (NumToTextFormalLower_ko), // 32. () (33)
99 TmItem2 (NumToTextFormalUpper_ko), // 33. () (34)
100 TmItem2 (NumToTextInformalHangul_ko), // 34. () (35)
101 TmItem2 (NumToTextInformalLower_ko), // 35. () (36)
102 TmItem2 (NumToTextInformalUpper_ko), // 36. () (37)
103 TmItem2 (NumToCharLower_zh_CN), // 37. () (38)
104 TmItem2 (NumToCharUpper_zh_CN), // 38. () (39)
105 TmItem2 (NumToCharLower_zh_TW), // 39. () (40)
106 TmItem2 (NumToCharUpper_zh_TW), // 40. () (41)
107 TmItem2 (NumToCharHangul_ko), // 41. () (42)
108 TmItem2 (NumToCharLower_ko), // 42. () (43)
109 TmItem2 (NumToCharUpper_ko), // 43. () (44)
110 TmItem2 (NumToCharFullwidth), // 44. () (45)
111 TmItem2 (NumToCharKanjiShort_ja_JP), // 45. () (46)
112 TmItem2 (TextToNumLower_zh_CN), // 46. () (47)
113 TmItem2 (TextToNumUpper_zh_CN), // 47. () (48)
114 TmItem2 (TextToNumLower_zh_TW), // 48. () (49)
115 TmItem2 (TextToNumUpper_zh_TW), // 49. () (50)
116 TmItem2 (TextToNumFormalHangul_ko), // 50. () (51)
117 TmItem2 (TextToNumFormalLower_ko), // 51. () (52)
118 TmItem2 (TextToNumFormalUpper_ko), // 52. () (53)
119 TmItem2 (TextToNumInformalHangul_ko), // 53. () (54)
120 TmItem2 (TextToNumInformalLower_ko), // 54. () (55)
121 TmItem2 (TextToNumInformalUpper_ko), // 55. () (56)
123 TmItem2 (CharToNumLower_zh_CN), // 56. () (59)
124 TmItem2 (CharToNumUpper_zh_CN), // 57. () (60)
125 TmItem2 (CharToNumLower_zh_TW), // 58. () (61)
126 TmItem2 (CharToNumUpper_zh_TW), // 59. () (62)
127 TmItem2 (CharToNumHangul_ko), // 60. () (63)
128 TmItem2 (CharToNumLower_ko), // 61. () (64)
129 TmItem2 (CharToNumUpper_ko), // 62. () (65)
131 // no enum defined for these trans. application has to use impl name to load them
132 // TmItem2 (NumToCharArabic_Indic), // () (67)
133 // TmItem2 (NumToCharEstern_Arabic_Indic),// () (68)
134 // TmItem2 (NumToCharIndic), // () (69)
135 // TmItem2 (NumToCharThai), // () (70)
136 {(TransliterationModules)0, (TransliterationModulesNew)0, NULL}
139 // Constructor/Destructor
140 TransliterationImpl::TransliterationImpl(const Reference <XComponentContext>& xContext) : mxContext(xContext)
142 numCascade = 0;
143 caseignoreOnly = sal_True;
145 mxLocaledata.set(LocaleData::create(xContext));
148 TransliterationImpl::~TransliterationImpl()
150 mxLocaledata.clear();
151 clear();
155 // Methods
156 OUString SAL_CALL
157 TransliterationImpl::getName() throw(RuntimeException)
159 if (numCascade == 1 && bodyCascade[0].is())
160 return bodyCascade[0]->getName();
161 if (numCascade < 1)
162 return ( OUString("Not Loaded"));
163 throw ERROR;
166 sal_Int16 SAL_CALL
167 TransliterationImpl::getType() throw(RuntimeException)
169 if (numCascade > 1)
170 return (TransliterationType::CASCADE|TransliterationType::IGNORE);
171 if (numCascade > 0 && bodyCascade[0].is())
172 return(bodyCascade[0]->getType());
173 throw ERROR;
176 void SAL_CALL
177 TransliterationImpl::loadModule( TransliterationModules modType, const Locale& rLocale )
178 throw(RuntimeException)
180 clear();
181 if (modType&TransliterationModules_IGNORE_MASK && modType&TransliterationModules_NON_IGNORE_MASK) {
182 throw ERROR;
183 } else if (modType&TransliterationModules_IGNORE_MASK) {
184 #define TransliterationModules_IGNORE_CASE_MASK (TransliterationModules_IGNORE_CASE | \
185 TransliterationModules_IGNORE_WIDTH | \
186 TransliterationModules_IGNORE_KANA)
187 sal_Int32 mask = ((modType&TransliterationModules_IGNORE_CASE_MASK) == modType) ?
188 TransliterationModules_IGNORE_CASE_MASK : TransliterationModules_IGNORE_MASK;
189 for (sal_Int16 i = 0; TMlist[i].tm & mask; i++) {
190 if (modType & TMlist[i].tm)
191 if (loadModuleByName(OUString::createFromAscii(TMlist[i].implName),
192 bodyCascade[numCascade], rLocale))
193 numCascade++;
195 } else if (modType&TransliterationModules_NON_IGNORE_MASK) {
196 for (sal_Int16 i = 0; TMlist[i].tm; i++) {
197 if (TMlist[i].tm == modType) {
198 if (loadModuleByName(OUString::createFromAscii(TMlist[i].implName), bodyCascade[numCascade], rLocale))
199 numCascade++;
200 break;
206 void SAL_CALL
207 TransliterationImpl::loadModuleNew( const Sequence < TransliterationModulesNew > & modType, const Locale& rLocale )
208 throw(RuntimeException)
210 clear();
211 sal_Int32 mask = 0, count = modType.getLength();
212 if (count > maxCascade)
213 throw ERROR; // could not handle more than maxCascade
214 for (sal_Int16 i = 0; i < count; i++) {
215 for (sal_Int16 j = 0; TMlist[j].tmn; j++) {
216 if (TMlist[j].tmn == modType[i]) {
217 if (mask == 0)
218 mask = TMlist[i].tm && (TMlist[i].tm&TransliterationModules_IGNORE_MASK) ?
219 TransliterationModules_IGNORE_MASK : TransliterationModules_NON_IGNORE_MASK;
220 else if (mask == TransliterationModules_IGNORE_MASK &&
221 (TMlist[i].tm&TransliterationModules_IGNORE_MASK) == 0)
222 throw ERROR; // could not mess up ignore trans. with non_ignore trans.
223 if (loadModuleByName(OUString::createFromAscii(TMlist[j].implName), bodyCascade[numCascade], rLocale))
224 numCascade++;
225 break;
231 void SAL_CALL
232 TransliterationImpl::loadModuleByImplName(const OUString& implName, const Locale& rLocale)
233 throw(RuntimeException)
235 clear();
236 if (loadModuleByName(implName, bodyCascade[numCascade], rLocale))
237 numCascade++;
241 void SAL_CALL
242 TransliterationImpl::loadModulesByImplNames(const Sequence< OUString >& implNameList, const Locale& rLocale ) throw(RuntimeException)
244 if (implNameList.getLength() > maxCascade || implNameList.getLength() <= 0)
245 throw ERROR;
247 clear();
248 for (sal_Int32 i = 0; i < implNameList.getLength(); i++)
249 if (loadModuleByName(implNameList[i], bodyCascade[numCascade], rLocale))
250 numCascade++;
254 Sequence<OUString> SAL_CALL
255 TransliterationImpl::getAvailableModules( const Locale& rLocale, sal_Int16 sType ) throw(RuntimeException)
257 const Sequence<OUString> &translist = mxLocaledata->getTransliterations(rLocale);
258 Sequence<OUString> r(translist.getLength());
259 Reference<XExtendedTransliteration> body;
260 sal_Int32 n = 0;
261 for (sal_Int32 i = 0; i < translist.getLength(); i++)
263 if (loadModuleByName(translist[i], body, rLocale)) {
264 if (body->getType() & sType)
265 r[n++] = translist[i];
266 body.clear();
269 r.realloc(n);
270 return (r);
274 OUString SAL_CALL
275 TransliterationImpl::transliterate( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
276 Sequence< sal_Int32 >& offset ) throw(RuntimeException)
278 if (numCascade == 0)
279 return inStr;
281 if (offset.getLength() != nCount)
282 offset.realloc(nCount);
283 if (numCascade == 1)
285 if ( startPos == 0 && nCount == inStr.getLength() )
286 return bodyCascade[0]->transliterate( inStr, 0, nCount, offset);
287 else
289 OUString tmpStr = inStr.copy(startPos, nCount);
290 tmpStr = bodyCascade[0]->transliterate(tmpStr, 0, nCount, offset);
291 if ( startPos )
293 sal_Int32 * pArr = offset.getArray();
294 nCount = offset.getLength();
295 for (sal_Int32 j = 0; j < nCount; j++)
296 pArr[j] += startPos;
298 return tmpStr;
301 else
303 OUString tmpStr = inStr.copy(startPos, nCount);
304 sal_Int32 * pArr = offset.getArray();
305 for (sal_Int32 j = 0; j < nCount; j++)
306 pArr[j] = startPos + j;
308 sal_Int16 from = 0, to = 1, tmp;
309 Sequence<sal_Int32> off[2];
311 off[to] = offset;
312 off[from].realloc(nCount);
313 for (sal_Int32 i = 0; i < numCascade; i++) {
314 tmpStr = bodyCascade[i]->transliterate(tmpStr, 0, nCount, off[from]);
316 nCount = tmpStr.getLength();
318 tmp = from; from = to; to = tmp;
319 for (sal_Int32 j = 0; j < nCount; j++)
320 off[to][j] = off[from][off[to][j]];
322 offset = off[to];
323 return tmpStr;
329 OUString SAL_CALL
330 TransliterationImpl::folding( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
331 Sequence< sal_Int32 >& offset ) throw(RuntimeException)
333 if (numCascade == 0)
334 return inStr;
336 if (offset.getLength() != nCount)
337 offset.realloc(nCount);
338 if (numCascade == 1)
340 if ( startPos == 0 && nCount == inStr.getLength() )
341 return bodyCascade[0]->folding( inStr, 0, nCount, offset);
342 else
344 OUString tmpStr = inStr.copy(startPos, nCount);
345 tmpStr = bodyCascade[0]->folding(tmpStr, 0, nCount, offset);
346 if ( startPos )
348 sal_Int32 * pArr = offset.getArray();
349 nCount = offset.getLength();
350 for (sal_Int32 j = 0; j < nCount; j++)
351 pArr[j] += startPos;
353 return tmpStr;
356 else
358 OUString tmpStr = inStr.copy(startPos, nCount);
359 sal_Int32 * pArr = offset.getArray();
360 for (sal_Int32 j = 0; j < nCount; j++)
361 pArr[j] = startPos + j;
363 sal_Int16 from = 0, to = 1, tmp;
364 Sequence<sal_Int32> off[2];
366 off[to] = offset;
367 for (sal_Int32 i = 0; i < numCascade; i++) {
368 tmpStr = bodyCascade[i]->folding(tmpStr, 0, nCount, off[from]);
370 nCount = tmpStr.getLength();
372 tmp = from; from = to; to = tmp;
373 for (sal_Int32 j = 0; j < nCount; j++)
374 off[to][j] = off[from][off[to][j]];
376 offset = off[to];
377 return tmpStr;
381 OUString SAL_CALL
382 TransliterationImpl::transliterateString2String( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount ) throw(RuntimeException)
384 if (numCascade == 0)
385 return inStr;
386 else if (numCascade == 1)
387 return bodyCascade[0]->transliterateString2String( inStr, startPos, nCount);
388 else {
389 OUString tmpStr = bodyCascade[0]->transliterateString2String(inStr, startPos, nCount);
391 for (sal_Int32 i = 1; i < numCascade; i++)
392 tmpStr = bodyCascade[i]->transliterateString2String(tmpStr, 0, tmpStr.getLength());
393 return tmpStr;
397 OUString SAL_CALL
398 TransliterationImpl::transliterateChar2String( sal_Unicode inChar ) throw(RuntimeException)
400 if (numCascade == 0)
401 return OUString(&inChar, 1);
402 else if (numCascade == 1)
403 return bodyCascade[0]->transliterateChar2String( inChar);
404 else {
405 OUString tmpStr = bodyCascade[0]->transliterateChar2String(inChar);
407 for (sal_Int32 i = 1; i < numCascade; i++)
408 tmpStr = bodyCascade[i]->transliterateString2String(tmpStr, 0, tmpStr.getLength());
409 return tmpStr;
413 sal_Unicode SAL_CALL
414 TransliterationImpl::transliterateChar2Char( sal_Unicode inChar ) throw(MultipleCharsOutputException, RuntimeException)
416 sal_Unicode tmpChar = inChar;
417 for (sal_Int32 i = 0; i < numCascade; i++)
418 tmpChar = bodyCascade[i]->transliterateChar2Char(tmpChar);
419 return tmpChar;
423 sal_Bool SAL_CALL
424 TransliterationImpl::equals(
425 const OUString& str1, sal_Int32 pos1, sal_Int32 nCount1, sal_Int32& nMatch1,
426 const OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2)
427 throw(RuntimeException)
429 // since this is an API function make it user fail safe
430 if ( nCount1 < 0 ) {
431 pos1 += nCount1;
432 nCount1 = -nCount1;
434 if ( nCount2 < 0 ) {
435 pos2 += nCount2;
436 nCount2 = -nCount2;
438 if ( !nCount1 || !nCount2 ||
439 pos1 >= str1.getLength() || pos2 >= str2.getLength() ||
440 pos1 < 0 || pos2 < 0 ) {
441 nMatch1 = nMatch2 = 0;
442 // two empty strings return true, else false
443 return !nCount1 && !nCount2 && pos1 == str1.getLength() && pos2 == str2.getLength();
445 if ( pos1 + nCount1 > str1.getLength() )
446 nCount1 = str1.getLength() - pos1;
447 if ( pos2 + nCount2 > str2.getLength() )
448 nCount2 = str2.getLength() - pos2;
450 if (caseignoreOnly && caseignore.is())
451 return caseignore->equals(str1, pos1, nCount1, nMatch1, str2, pos2, nCount2, nMatch2);
453 Sequence<sal_Int32> offset1, offset2;
455 OUString tmpStr1 = folding(str1, pos1, nCount1, offset1);
456 OUString tmpStr2 = folding(str2, pos2, nCount2, offset2);
457 // Length of offset1 and offset2 may still be 0 if there was no folding
458 // necessary!
460 const sal_Unicode *p1 = tmpStr1.getStr();
461 const sal_Unicode *p2 = tmpStr2.getStr();
462 sal_Int32 i, nLen = ::std::min( tmpStr1.getLength(), tmpStr2.getLength());
463 for (i = 0; i < nLen; ++i, ++p1, ++p2 ) {
464 if (*p1 != *p2) {
465 // return number of matched code points so far
466 nMatch1 = (i < offset1.getLength()) ? offset1[i] : i;
467 nMatch2 = (i < offset2.getLength()) ? offset2[i] : i;
468 return sal_False;
471 // i==nLen
472 if ( tmpStr1.getLength() != tmpStr2.getLength() ) {
473 // return number of matched code points so far
474 nMatch1 = (i <= offset1.getLength()) ? offset1[i-1] + 1 : i;
475 nMatch2 = (i <= offset2.getLength()) ? offset2[i-1] + 1 : i;
476 return sal_False;
477 } else {
478 nMatch1 = nCount1;
479 nMatch2 = nCount2;
480 return sal_True;
484 #define MaxOutput 2
486 Sequence< OUString > SAL_CALL
487 TransliterationImpl::getRange(const Sequence< OUString > &inStrs,
488 const sal_Int32 length, sal_Int16 _numCascade) throw(RuntimeException)
490 if (_numCascade >= numCascade || ! bodyCascade[_numCascade].is())
491 return inStrs;
493 sal_Int32 j_tmp = 0;
494 Sequence< OUString > ostr(MaxOutput*length);
495 for (sal_Int32 j = 0; j < length; j+=2) {
496 const Sequence< OUString >& temp = bodyCascade[_numCascade]->transliterateRange(inStrs[j], inStrs[j+1]);
498 for ( sal_Int32 k = 0; k < temp.getLength(); k++) {
499 if ( j_tmp >= MaxOutput*length ) throw ERROR;
500 ostr[j_tmp++] = temp[k];
503 ostr.realloc(j_tmp);
505 return this->getRange(ostr, j_tmp, ++_numCascade);
509 Sequence< OUString > SAL_CALL
510 TransliterationImpl::transliterateRange( const OUString& str1, const OUString& str2 )
511 throw(RuntimeException)
513 if (numCascade == 1)
514 return bodyCascade[0]->transliterateRange(str1, str2);
516 Sequence< OUString > ostr(2);
517 ostr[0] = str1;
518 ostr[1] = str2;
520 return this->getRange(ostr, 2, 0);
524 sal_Int32 SAL_CALL
525 TransliterationImpl::compareSubstring(
526 const OUString& str1, sal_Int32 off1, sal_Int32 len1,
527 const OUString& str2, sal_Int32 off2, sal_Int32 len2)
528 throw(RuntimeException)
530 if (caseignoreOnly && caseignore.is())
531 return caseignore->compareSubstring(str1, off1, len1, str2, off2, len2);
533 Sequence <sal_Int32> offset;
535 OUString in_str1 = this->transliterate(str1, off1, len1, offset);
536 OUString in_str2 = this->transliterate(str2, off2, len2, offset);
537 const sal_Unicode* unistr1 = in_str1.getStr();
538 const sal_Unicode* unistr2 = in_str2.getStr();
539 sal_Int32 strlen1 = in_str1.getLength();
540 sal_Int32 strlen2 = in_str2.getLength();
542 while (strlen1 && strlen2) {
543 if (*unistr1 != *unistr2)
544 return *unistr1 > *unistr2 ? 1 : -1;
546 unistr1++; unistr2++; strlen1--; strlen2--;
548 return strlen1 == strlen2 ? 0 : (strlen1 > strlen2 ? 1 : -1);
552 sal_Int32 SAL_CALL
553 TransliterationImpl::compareString(const OUString& str1, const OUString& str2 ) throw (RuntimeException)
555 if (caseignoreOnly && caseignore.is())
556 return caseignore->compareString(str1, str2);
557 else
558 return this->compareSubstring(str1, 0, str1.getLength(), str2, 0, str2.getLength());
562 void
563 TransliterationImpl::clear()
565 for (sal_Int32 i = 0; i < numCascade; i++)
566 if (bodyCascade[i].is())
567 bodyCascade[i].clear();
568 numCascade = 0;
569 caseignore.clear();
570 caseignoreOnly = sal_True;
573 namespace
575 /** structure to cache the last transliteration body used. */
576 struct TransBody
578 OUString Name;
579 ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XExtendedTransliteration > Body;
581 class theTransBodyMutex : public rtl::Static<osl::Mutex, theTransBodyMutex> {};
584 void TransliterationImpl::loadBody( OUString &implName, Reference<XExtendedTransliteration>& body )
585 throw (RuntimeException)
587 assert(!implName.isEmpty());
588 ::osl::MutexGuard guard(theTransBodyMutex::get());
589 static TransBody lastTransBody;
590 if (implName != lastTransBody.Name)
592 lastTransBody.Body.set(
593 mxContext->getServiceManager()->createInstanceWithContext(implName, mxContext), UNO_QUERY_THROW);
594 lastTransBody.Name = implName;
596 body = lastTransBody.Body;
599 sal_Bool SAL_CALL
600 TransliterationImpl::loadModuleByName( const OUString& implName,
601 Reference<XExtendedTransliteration>& body, const Locale& rLocale) throw(RuntimeException)
603 OUString cname = OUString(TRLT_IMPLNAME_PREFIX) + implName;
604 loadBody(cname, body);
605 if (body.is()) {
606 body->loadModule((TransliterationModules)0, rLocale); // toUpper/toLoad need rLocale
608 // if the module is ignore case/kana/width, load caseignore for equals/compareString mothed
609 for (sal_Int16 i = 0; i < 3; i++) {
610 if (implName.compareToAscii(TMlist[i].implName) == 0) {
611 if (i == 0) // current module is caseignore
612 body->loadModule(TMlist[0].tm, rLocale); // caseingore need to setup module name
613 if (! caseignore.is()) {
614 OUString bname = OUString(TRLT_IMPLNAME_PREFIX) +
615 OUString::createFromAscii(TMlist[0].implName);
616 loadBody(bname, caseignore);
618 if (caseignore.is())
619 caseignore->loadModule(TMlist[i].tm, rLocale);
620 return sal_True;
623 caseignoreOnly = sal_False; // has other module than just ignore case/kana/width
625 return body.is();
628 const sal_Char cTrans[] = "com.sun.star.i18n.Transliteration";
630 OUString SAL_CALL
631 TransliterationImpl::getImplementationName() throw( RuntimeException )
633 return OUString::createFromAscii(cTrans);
637 sal_Bool SAL_CALL
638 TransliterationImpl::supportsService(const OUString& rServiceName) throw( RuntimeException )
640 return !rServiceName.compareToAscii(cTrans);
643 Sequence< OUString > SAL_CALL
644 TransliterationImpl::getSupportedServiceNames(void) throw( RuntimeException )
646 Sequence< OUString > aRet(1);
647 aRet[0] = OUString::createFromAscii(cTrans);
648 return aRet;
651 } } } }
653 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */