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