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 TransliterationImpl::TransBody TransliterationImpl::lastTransBody; 148cdf0e10cSrcweir 149cdf0e10cSrcweir // Constructor/Destructor 150cdf0e10cSrcweir TransliterationImpl::TransliterationImpl(const Reference <XMultiServiceFactory>& xMSF) : xSMgr(xMSF) 151cdf0e10cSrcweir { 152cdf0e10cSrcweir numCascade = 0; 153cdf0e10cSrcweir caseignoreOnly = sal_True; 154cdf0e10cSrcweir 155cdf0e10cSrcweir if ( xMSF.is() ) 156cdf0e10cSrcweir { 157cdf0e10cSrcweir Reference < XInterface > xI= 158cdf0e10cSrcweir xMSF->createInstance(OUString::createFromAscii("com.sun.star.i18n.LocaleData")); 159cdf0e10cSrcweir if ( xI.is() ) { 160cdf0e10cSrcweir Any x = xI->queryInterface( ::getCppuType( (const uno::Reference< i18n::XLocaleData >*)0) ); 161cdf0e10cSrcweir x >>= localedata; 162cdf0e10cSrcweir } 163cdf0e10cSrcweir } 164cdf0e10cSrcweir } 165cdf0e10cSrcweir 166cdf0e10cSrcweir TransliterationImpl::~TransliterationImpl() 167cdf0e10cSrcweir { 168cdf0e10cSrcweir localedata.clear(); 169cdf0e10cSrcweir clear(); 170cdf0e10cSrcweir } 171cdf0e10cSrcweir 172cdf0e10cSrcweir 173cdf0e10cSrcweir // Methods 174cdf0e10cSrcweir OUString SAL_CALL 175cdf0e10cSrcweir TransliterationImpl::getName() throw(RuntimeException) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir if (numCascade == 1 && bodyCascade[0].is()) 178cdf0e10cSrcweir return bodyCascade[0]->getName(); 179cdf0e10cSrcweir if (numCascade < 1) 180cdf0e10cSrcweir return ( OUString::createFromAscii("Not Loaded")); 181cdf0e10cSrcweir throw ERROR; 182cdf0e10cSrcweir } 183cdf0e10cSrcweir 184cdf0e10cSrcweir sal_Int16 SAL_CALL 185cdf0e10cSrcweir TransliterationImpl::getType() throw(RuntimeException) 186cdf0e10cSrcweir { 187cdf0e10cSrcweir if (numCascade > 1) 188cdf0e10cSrcweir return (TransliterationType::CASCADE|TransliterationType::IGNORE); 189cdf0e10cSrcweir if (numCascade > 0 && bodyCascade[0].is()) 190cdf0e10cSrcweir return(bodyCascade[0]->getType()); 191cdf0e10cSrcweir throw ERROR; 192cdf0e10cSrcweir } 193cdf0e10cSrcweir 194cdf0e10cSrcweir void SAL_CALL 195cdf0e10cSrcweir TransliterationImpl::loadModule( TransliterationModules modType, const Locale& rLocale ) 196cdf0e10cSrcweir throw(RuntimeException) 197cdf0e10cSrcweir { 198cdf0e10cSrcweir clear(); 199cdf0e10cSrcweir if (modType&TransliterationModules_IGNORE_MASK && modType&TransliterationModules_NON_IGNORE_MASK) { 200cdf0e10cSrcweir throw ERROR; 201cdf0e10cSrcweir } else if (modType&TransliterationModules_IGNORE_MASK) { 202cdf0e10cSrcweir #define TransliterationModules_IGNORE_CASE_MASK (TransliterationModules_IGNORE_CASE | \ 203cdf0e10cSrcweir TransliterationModules_IGNORE_WIDTH | \ 204cdf0e10cSrcweir TransliterationModules_IGNORE_KANA) 205cdf0e10cSrcweir sal_Int32 mask = ((modType&TransliterationModules_IGNORE_CASE_MASK) == modType) ? 206cdf0e10cSrcweir TransliterationModules_IGNORE_CASE_MASK : TransliterationModules_IGNORE_MASK; 207cdf0e10cSrcweir for (sal_Int16 i = 0; TMlist[i].tm & mask; i++) { 208cdf0e10cSrcweir if (modType & TMlist[i].tm) 209cdf0e10cSrcweir if (loadModuleByName(OUString::createFromAscii(TMlist[i].implName), 210cdf0e10cSrcweir bodyCascade[numCascade], rLocale)) 211cdf0e10cSrcweir numCascade++; 212cdf0e10cSrcweir } 213cdf0e10cSrcweir } else if (modType&TransliterationModules_NON_IGNORE_MASK) { 214cdf0e10cSrcweir for (sal_Int16 i = 0; TMlist[i].tm; i++) { 215cdf0e10cSrcweir if (TMlist[i].tm == modType) { 216cdf0e10cSrcweir if (loadModuleByName(OUString::createFromAscii(TMlist[i].implName), bodyCascade[numCascade], rLocale)) 217cdf0e10cSrcweir numCascade++; 218cdf0e10cSrcweir break; 219cdf0e10cSrcweir } 220cdf0e10cSrcweir } 221cdf0e10cSrcweir } 222cdf0e10cSrcweir } 223cdf0e10cSrcweir 224cdf0e10cSrcweir void SAL_CALL 225cdf0e10cSrcweir TransliterationImpl::loadModuleNew( const Sequence < TransliterationModulesNew > & modType, const Locale& rLocale ) 226cdf0e10cSrcweir throw(RuntimeException) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir clear(); 229cdf0e10cSrcweir sal_Int32 mask = 0, count = modType.getLength(); 230cdf0e10cSrcweir if (count > maxCascade) 231cdf0e10cSrcweir throw ERROR; // could not handle more than maxCascade 232cdf0e10cSrcweir for (sal_Int16 i = 0; i < count; i++) { 233cdf0e10cSrcweir for (sal_Int16 j = 0; TMlist[j].tmn; j++) { 234cdf0e10cSrcweir if (TMlist[j].tmn == modType[i]) { 235cdf0e10cSrcweir if (mask == 0) 236cdf0e10cSrcweir mask = TMlist[i].tm && (TMlist[i].tm&TransliterationModules_IGNORE_MASK) ? 237cdf0e10cSrcweir TransliterationModules_IGNORE_MASK : TransliterationModules_NON_IGNORE_MASK; 238cdf0e10cSrcweir else if (mask == TransliterationModules_IGNORE_MASK && 239cdf0e10cSrcweir (TMlist[i].tm&TransliterationModules_IGNORE_MASK) == 0) 240cdf0e10cSrcweir throw ERROR; // could not mess up ignore trans. with non_ignore trans. 241cdf0e10cSrcweir if (loadModuleByName(OUString::createFromAscii(TMlist[j].implName), bodyCascade[numCascade], rLocale)) 242cdf0e10cSrcweir numCascade++; 243cdf0e10cSrcweir break; 244cdf0e10cSrcweir } 245cdf0e10cSrcweir } 246cdf0e10cSrcweir } 247cdf0e10cSrcweir } 248cdf0e10cSrcweir 249cdf0e10cSrcweir void SAL_CALL 250cdf0e10cSrcweir TransliterationImpl::loadModuleByImplName(const OUString& implName, const Locale& rLocale) 251cdf0e10cSrcweir throw(RuntimeException) 252cdf0e10cSrcweir { 253cdf0e10cSrcweir clear(); 254cdf0e10cSrcweir if (loadModuleByName(implName, bodyCascade[numCascade], rLocale)) 255cdf0e10cSrcweir numCascade++; 256cdf0e10cSrcweir } 257cdf0e10cSrcweir 258cdf0e10cSrcweir 259cdf0e10cSrcweir void SAL_CALL 260cdf0e10cSrcweir TransliterationImpl::loadModulesByImplNames(const Sequence< OUString >& implNameList, const Locale& rLocale ) throw(RuntimeException) 261cdf0e10cSrcweir { 262cdf0e10cSrcweir if (implNameList.getLength() > maxCascade || implNameList.getLength() <= 0) 263cdf0e10cSrcweir throw ERROR; 264cdf0e10cSrcweir 265cdf0e10cSrcweir clear(); 266cdf0e10cSrcweir for (sal_Int32 i = 0; i < implNameList.getLength(); i++) 267cdf0e10cSrcweir if (loadModuleByName(implNameList[i], bodyCascade[numCascade], rLocale)) 268cdf0e10cSrcweir numCascade++; 269cdf0e10cSrcweir } 270cdf0e10cSrcweir 271cdf0e10cSrcweir 272cdf0e10cSrcweir Sequence<OUString> SAL_CALL 273cdf0e10cSrcweir TransliterationImpl::getAvailableModules( const Locale& rLocale, sal_Int16 sType ) throw(RuntimeException) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir const Sequence<OUString> &translist = localedata->getTransliterations(rLocale); 276cdf0e10cSrcweir Sequence<OUString> r(translist.getLength()); 277cdf0e10cSrcweir Reference<XExtendedTransliteration> body; 278cdf0e10cSrcweir sal_Int32 n = 0; 279cdf0e10cSrcweir for (sal_Int32 i = 0; i < translist.getLength(); i++) 280cdf0e10cSrcweir { 281cdf0e10cSrcweir if (loadModuleByName(translist[i], body, rLocale)) { 282cdf0e10cSrcweir if (body->getType() & sType) 283cdf0e10cSrcweir r[n++] = translist[i]; 284cdf0e10cSrcweir body.clear(); 285cdf0e10cSrcweir } 286cdf0e10cSrcweir } 287cdf0e10cSrcweir r.realloc(n); 288cdf0e10cSrcweir return (r); 289cdf0e10cSrcweir } 290cdf0e10cSrcweir 291cdf0e10cSrcweir 292cdf0e10cSrcweir OUString SAL_CALL 293cdf0e10cSrcweir TransliterationImpl::transliterate( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, 294cdf0e10cSrcweir Sequence< sal_Int32 >& offset ) throw(RuntimeException) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir if (numCascade == 0) 297cdf0e10cSrcweir return inStr; 298cdf0e10cSrcweir 299cdf0e10cSrcweir if (offset.getLength() != nCount) 300cdf0e10cSrcweir offset.realloc(nCount); 301cdf0e10cSrcweir if (numCascade == 1) 302cdf0e10cSrcweir { 303cdf0e10cSrcweir if ( startPos == 0 && nCount == inStr.getLength() ) 304cdf0e10cSrcweir return bodyCascade[0]->transliterate( inStr, 0, nCount, offset); 305cdf0e10cSrcweir else 306cdf0e10cSrcweir { 307cdf0e10cSrcweir OUString tmpStr = inStr.copy(startPos, nCount); 308cdf0e10cSrcweir tmpStr = bodyCascade[0]->transliterate(tmpStr, 0, nCount, offset); 309cdf0e10cSrcweir if ( startPos ) 310cdf0e10cSrcweir { 311cdf0e10cSrcweir sal_Int32 * pArr = offset.getArray(); 312cdf0e10cSrcweir nCount = offset.getLength(); 313cdf0e10cSrcweir for (sal_Int32 j = 0; j < nCount; j++) 314cdf0e10cSrcweir pArr[j] += startPos; 315cdf0e10cSrcweir } 316cdf0e10cSrcweir return tmpStr; 317cdf0e10cSrcweir } 318cdf0e10cSrcweir } 319cdf0e10cSrcweir else 320cdf0e10cSrcweir { 321cdf0e10cSrcweir OUString tmpStr = inStr.copy(startPos, nCount); 322cdf0e10cSrcweir sal_Int32 * pArr = offset.getArray(); 323cdf0e10cSrcweir for (sal_Int32 j = 0; j < nCount; j++) 324cdf0e10cSrcweir pArr[j] = startPos + j; 325cdf0e10cSrcweir 326cdf0e10cSrcweir sal_Int16 from = 0, to = 1, tmp; 327cdf0e10cSrcweir Sequence<sal_Int32> off[2]; 328cdf0e10cSrcweir 329cdf0e10cSrcweir off[to] = offset; 330cdf0e10cSrcweir off[from].realloc(nCount); 331cdf0e10cSrcweir for (sal_Int32 i = 0; i < numCascade; i++) { 332cdf0e10cSrcweir tmpStr = bodyCascade[i]->transliterate(tmpStr, 0, nCount, off[from]); 333cdf0e10cSrcweir 334cdf0e10cSrcweir nCount = tmpStr.getLength(); 335cdf0e10cSrcweir 336cdf0e10cSrcweir tmp = from; from = to; to = tmp; 337cdf0e10cSrcweir for (sal_Int32 j = 0; j < nCount; j++) 338cdf0e10cSrcweir off[to][j] = off[from][off[to][j]]; 339cdf0e10cSrcweir } 340cdf0e10cSrcweir offset = off[to]; 341cdf0e10cSrcweir return tmpStr; 342cdf0e10cSrcweir } 343cdf0e10cSrcweir } 344cdf0e10cSrcweir 345cdf0e10cSrcweir 346cdf0e10cSrcweir // 347cdf0e10cSrcweir OUString SAL_CALL 348cdf0e10cSrcweir TransliterationImpl::folding( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount, 349cdf0e10cSrcweir Sequence< sal_Int32 >& offset ) throw(RuntimeException) 350cdf0e10cSrcweir { 351cdf0e10cSrcweir if (numCascade == 0) 352cdf0e10cSrcweir return inStr; 353cdf0e10cSrcweir 354cdf0e10cSrcweir if (offset.getLength() != nCount) 355cdf0e10cSrcweir offset.realloc(nCount); 356cdf0e10cSrcweir if (numCascade == 1) 357cdf0e10cSrcweir { 358cdf0e10cSrcweir if ( startPos == 0 && nCount == inStr.getLength() ) 359cdf0e10cSrcweir return bodyCascade[0]->folding( inStr, 0, nCount, offset); 360cdf0e10cSrcweir else 361cdf0e10cSrcweir { 362cdf0e10cSrcweir OUString tmpStr = inStr.copy(startPos, nCount); 363cdf0e10cSrcweir tmpStr = bodyCascade[0]->folding(tmpStr, 0, nCount, offset); 364cdf0e10cSrcweir if ( startPos ) 365cdf0e10cSrcweir { 366cdf0e10cSrcweir sal_Int32 * pArr = offset.getArray(); 367cdf0e10cSrcweir nCount = offset.getLength(); 368cdf0e10cSrcweir for (sal_Int32 j = 0; j < nCount; j++) 369cdf0e10cSrcweir pArr[j] += startPos; 370cdf0e10cSrcweir } 371cdf0e10cSrcweir return tmpStr; 372cdf0e10cSrcweir } 373cdf0e10cSrcweir } 374cdf0e10cSrcweir else 375cdf0e10cSrcweir { 376cdf0e10cSrcweir OUString tmpStr = inStr.copy(startPos, nCount); 377cdf0e10cSrcweir sal_Int32 * pArr = offset.getArray(); 378cdf0e10cSrcweir for (sal_Int32 j = 0; j < nCount; j++) 379cdf0e10cSrcweir pArr[j] = startPos + j; 380cdf0e10cSrcweir 381cdf0e10cSrcweir sal_Int16 from = 0, to = 1, tmp; 382cdf0e10cSrcweir Sequence<sal_Int32> off[2]; 383cdf0e10cSrcweir 384cdf0e10cSrcweir off[to] = offset; 385cdf0e10cSrcweir for (sal_Int32 i = 0; i < numCascade; i++) { 386cdf0e10cSrcweir tmpStr = bodyCascade[i]->folding(tmpStr, 0, nCount, off[from]); 387cdf0e10cSrcweir 388cdf0e10cSrcweir nCount = tmpStr.getLength(); 389cdf0e10cSrcweir 390cdf0e10cSrcweir tmp = from; from = to; to = tmp; 391cdf0e10cSrcweir for (sal_Int32 j = 0; j < nCount; j++) 392cdf0e10cSrcweir off[to][j] = off[from][off[to][j]]; 393cdf0e10cSrcweir } 394cdf0e10cSrcweir offset = off[to]; 395cdf0e10cSrcweir return tmpStr; 396cdf0e10cSrcweir } 397cdf0e10cSrcweir } 398cdf0e10cSrcweir 399cdf0e10cSrcweir OUString SAL_CALL 400cdf0e10cSrcweir TransliterationImpl::transliterateString2String( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount ) throw(RuntimeException) 401cdf0e10cSrcweir { 402cdf0e10cSrcweir if (numCascade == 0) 403cdf0e10cSrcweir return inStr; 404cdf0e10cSrcweir else if (numCascade == 1) 405cdf0e10cSrcweir return bodyCascade[0]->transliterateString2String( inStr, startPos, nCount); 406cdf0e10cSrcweir else { 407cdf0e10cSrcweir OUString tmpStr = bodyCascade[0]->transliterateString2String(inStr, startPos, nCount); 408cdf0e10cSrcweir 409cdf0e10cSrcweir for (sal_Int32 i = 1; i < numCascade; i++) 410cdf0e10cSrcweir tmpStr = bodyCascade[i]->transliterateString2String(tmpStr, 0, tmpStr.getLength()); 411cdf0e10cSrcweir return tmpStr; 412cdf0e10cSrcweir } 413cdf0e10cSrcweir } 414cdf0e10cSrcweir 415cdf0e10cSrcweir OUString SAL_CALL 416cdf0e10cSrcweir TransliterationImpl::transliterateChar2String( sal_Unicode inChar ) throw(RuntimeException) 417cdf0e10cSrcweir { 418cdf0e10cSrcweir if (numCascade == 0) 419cdf0e10cSrcweir return OUString(&inChar, 1); 420cdf0e10cSrcweir else if (numCascade == 1) 421cdf0e10cSrcweir return bodyCascade[0]->transliterateChar2String( inChar); 422cdf0e10cSrcweir else { 423cdf0e10cSrcweir OUString tmpStr = bodyCascade[0]->transliterateChar2String(inChar); 424cdf0e10cSrcweir 425cdf0e10cSrcweir for (sal_Int32 i = 1; i < numCascade; i++) 426cdf0e10cSrcweir tmpStr = bodyCascade[i]->transliterateString2String(tmpStr, 0, tmpStr.getLength()); 427cdf0e10cSrcweir return tmpStr; 428cdf0e10cSrcweir } 429cdf0e10cSrcweir } 430cdf0e10cSrcweir 431cdf0e10cSrcweir sal_Unicode SAL_CALL 432cdf0e10cSrcweir TransliterationImpl::transliterateChar2Char( sal_Unicode inChar ) throw(MultipleCharsOutputException, RuntimeException) 433cdf0e10cSrcweir { 434cdf0e10cSrcweir sal_Unicode tmpChar = inChar; 435cdf0e10cSrcweir for (sal_Int32 i = 0; i < numCascade; i++) 436cdf0e10cSrcweir tmpChar = bodyCascade[i]->transliterateChar2Char(tmpChar); 437cdf0e10cSrcweir return tmpChar; 438cdf0e10cSrcweir } 439cdf0e10cSrcweir 440cdf0e10cSrcweir 441cdf0e10cSrcweir sal_Bool SAL_CALL 442cdf0e10cSrcweir TransliterationImpl::equals( 443cdf0e10cSrcweir const OUString& str1, sal_Int32 pos1, sal_Int32 nCount1, sal_Int32& nMatch1, 444cdf0e10cSrcweir const OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2) 445cdf0e10cSrcweir throw(RuntimeException) 446cdf0e10cSrcweir { 447cdf0e10cSrcweir // since this is an API function make it user fail safe 448cdf0e10cSrcweir if ( nCount1 < 0 ) { 449cdf0e10cSrcweir pos1 += nCount1; 450cdf0e10cSrcweir nCount1 = -nCount1; 451cdf0e10cSrcweir } 452cdf0e10cSrcweir if ( nCount2 < 0 ) { 453cdf0e10cSrcweir pos2 += nCount2; 454cdf0e10cSrcweir nCount2 = -nCount2; 455cdf0e10cSrcweir } 456cdf0e10cSrcweir if ( !nCount1 || !nCount2 || 457cdf0e10cSrcweir pos1 >= str1.getLength() || pos2 >= str2.getLength() || 458cdf0e10cSrcweir pos1 < 0 || pos2 < 0 ) { 459cdf0e10cSrcweir nMatch1 = nMatch2 = 0; 460cdf0e10cSrcweir // two empty strings return true, else false 461cdf0e10cSrcweir return !nCount1 && !nCount2 && pos1 == str1.getLength() && pos2 == str2.getLength(); 462cdf0e10cSrcweir } 463cdf0e10cSrcweir if ( pos1 + nCount1 > str1.getLength() ) 464cdf0e10cSrcweir nCount1 = str1.getLength() - pos1; 465cdf0e10cSrcweir if ( pos2 + nCount2 > str2.getLength() ) 466cdf0e10cSrcweir nCount2 = str2.getLength() - pos2; 467cdf0e10cSrcweir 468cdf0e10cSrcweir if (caseignoreOnly && caseignore.is()) 469cdf0e10cSrcweir return caseignore->equals(str1, pos1, nCount1, nMatch1, str2, pos2, nCount2, nMatch2); 470cdf0e10cSrcweir 471cdf0e10cSrcweir Sequence<sal_Int32> offset1, offset2; 472cdf0e10cSrcweir 473cdf0e10cSrcweir OUString tmpStr1 = folding(str1, pos1, nCount1, offset1); 474cdf0e10cSrcweir OUString tmpStr2 = folding(str2, pos2, nCount2, offset2); 475cdf0e10cSrcweir // Length of offset1 and offset2 may still be 0 if there was no folding 476cdf0e10cSrcweir // necessary! 477cdf0e10cSrcweir 478cdf0e10cSrcweir const sal_Unicode *p1 = tmpStr1.getStr(); 479cdf0e10cSrcweir const sal_Unicode *p2 = tmpStr2.getStr(); 480cdf0e10cSrcweir sal_Int32 i, nLen = ::std::min( tmpStr1.getLength(), tmpStr2.getLength()); 481cdf0e10cSrcweir for (i = 0; i < nLen; ++i, ++p1, ++p2 ) { 482cdf0e10cSrcweir if (*p1 != *p2) { 483cdf0e10cSrcweir // return number of matched code points so far 484cdf0e10cSrcweir nMatch1 = (i < offset1.getLength()) ? offset1[i] : i; 485cdf0e10cSrcweir nMatch2 = (i < offset2.getLength()) ? offset2[i] : i; 486cdf0e10cSrcweir return sal_False; 487cdf0e10cSrcweir } 488cdf0e10cSrcweir } 489cdf0e10cSrcweir // i==nLen 490cdf0e10cSrcweir if ( tmpStr1.getLength() != tmpStr2.getLength() ) { 491cdf0e10cSrcweir // return number of matched code points so far 492cdf0e10cSrcweir nMatch1 = (i <= offset1.getLength()) ? offset1[i-1] + 1 : i; 493cdf0e10cSrcweir nMatch2 = (i <= offset2.getLength()) ? offset2[i-1] + 1 : i; 494cdf0e10cSrcweir return sal_False; 495cdf0e10cSrcweir } else { 496cdf0e10cSrcweir nMatch1 = nCount1; 497cdf0e10cSrcweir nMatch2 = nCount2; 498cdf0e10cSrcweir return sal_True; 499cdf0e10cSrcweir } 500cdf0e10cSrcweir } 501cdf0e10cSrcweir 502cdf0e10cSrcweir #define MaxOutput 2 503cdf0e10cSrcweir 504cdf0e10cSrcweir Sequence< OUString > SAL_CALL 505cdf0e10cSrcweir TransliterationImpl::getRange(const Sequence< OUString > &inStrs, 506cdf0e10cSrcweir const sal_Int32 length, sal_Int16 _numCascade) throw(RuntimeException) 507cdf0e10cSrcweir { 508cdf0e10cSrcweir if (_numCascade >= numCascade || ! bodyCascade[_numCascade].is()) 509cdf0e10cSrcweir return inStrs; 510cdf0e10cSrcweir 511cdf0e10cSrcweir sal_Int32 j_tmp = 0; 512cdf0e10cSrcweir Sequence< OUString > ostr(MaxOutput*length); 513cdf0e10cSrcweir for (sal_Int32 j = 0; j < length; j+=2) { 514cdf0e10cSrcweir const Sequence< OUString >& temp = bodyCascade[_numCascade]->transliterateRange(inStrs[j], inStrs[j+1]); 515cdf0e10cSrcweir 516cdf0e10cSrcweir for ( sal_Int32 k = 0; k < temp.getLength(); k++) { 517cdf0e10cSrcweir if ( j_tmp >= MaxOutput*length ) throw ERROR; 518cdf0e10cSrcweir ostr[j_tmp++] = temp[k]; 519cdf0e10cSrcweir } 520cdf0e10cSrcweir } 521cdf0e10cSrcweir ostr.realloc(j_tmp); 522cdf0e10cSrcweir 523cdf0e10cSrcweir return this->getRange(ostr, j_tmp, ++_numCascade); 524cdf0e10cSrcweir } 525cdf0e10cSrcweir 526cdf0e10cSrcweir 527cdf0e10cSrcweir Sequence< OUString > SAL_CALL 528cdf0e10cSrcweir TransliterationImpl::transliterateRange( const OUString& str1, const OUString& str2 ) 529cdf0e10cSrcweir throw(RuntimeException) 530cdf0e10cSrcweir { 531cdf0e10cSrcweir if (numCascade == 1) 532cdf0e10cSrcweir return bodyCascade[0]->transliterateRange(str1, str2); 533cdf0e10cSrcweir 534cdf0e10cSrcweir Sequence< OUString > ostr(2); 535cdf0e10cSrcweir ostr[0] = str1; 536cdf0e10cSrcweir ostr[1] = str2; 537cdf0e10cSrcweir 538cdf0e10cSrcweir return this->getRange(ostr, 2, 0); 539cdf0e10cSrcweir } 540cdf0e10cSrcweir 541cdf0e10cSrcweir 542cdf0e10cSrcweir sal_Int32 SAL_CALL 543cdf0e10cSrcweir TransliterationImpl::compareSubstring( 544cdf0e10cSrcweir const OUString& str1, sal_Int32 off1, sal_Int32 len1, 545cdf0e10cSrcweir const OUString& str2, sal_Int32 off2, sal_Int32 len2) 546cdf0e10cSrcweir throw(RuntimeException) 547cdf0e10cSrcweir { 548cdf0e10cSrcweir if (caseignoreOnly && caseignore.is()) 549cdf0e10cSrcweir return caseignore->compareSubstring(str1, off1, len1, str2, off2, len2); 550cdf0e10cSrcweir 551cdf0e10cSrcweir Sequence <sal_Int32> offset; 552cdf0e10cSrcweir 553cdf0e10cSrcweir OUString in_str1 = this->transliterate(str1, off1, len1, offset); 554cdf0e10cSrcweir OUString in_str2 = this->transliterate(str2, off2, len2, offset); 555cdf0e10cSrcweir const sal_Unicode* unistr1 = in_str1.getStr(); 556cdf0e10cSrcweir const sal_Unicode* unistr2 = in_str2.getStr(); 557cdf0e10cSrcweir sal_Int32 strlen1 = in_str1.getLength(); 558cdf0e10cSrcweir sal_Int32 strlen2 = in_str2.getLength(); 559cdf0e10cSrcweir 560cdf0e10cSrcweir while (strlen1 && strlen2) { 561cdf0e10cSrcweir if (*unistr1 != *unistr2) 562cdf0e10cSrcweir return *unistr1 > *unistr2 ? 1 : -1; 563cdf0e10cSrcweir 564cdf0e10cSrcweir unistr1++; unistr2++; strlen1--; strlen2--; 565cdf0e10cSrcweir } 566cdf0e10cSrcweir return strlen1 == strlen2 ? 0 : (strlen1 > strlen2 ? 1 : -1); 567cdf0e10cSrcweir } 568cdf0e10cSrcweir 569cdf0e10cSrcweir 570cdf0e10cSrcweir sal_Int32 SAL_CALL 571cdf0e10cSrcweir TransliterationImpl::compareString(const OUString& str1, const OUString& str2 ) throw (RuntimeException) 572cdf0e10cSrcweir { 573cdf0e10cSrcweir if (caseignoreOnly && caseignore.is()) 574cdf0e10cSrcweir return caseignore->compareString(str1, str2); 575cdf0e10cSrcweir else 576cdf0e10cSrcweir return this->compareSubstring(str1, 0, str1.getLength(), str2, 0, str2.getLength()); 577cdf0e10cSrcweir } 578cdf0e10cSrcweir 579cdf0e10cSrcweir 580cdf0e10cSrcweir void 581cdf0e10cSrcweir TransliterationImpl::clear() 582cdf0e10cSrcweir { 583cdf0e10cSrcweir for (sal_Int32 i = 0; i < numCascade; i++) 584cdf0e10cSrcweir if (bodyCascade[i].is()) 585cdf0e10cSrcweir bodyCascade[i].clear(); 586cdf0e10cSrcweir numCascade = 0; 587cdf0e10cSrcweir caseignore.clear(); 588cdf0e10cSrcweir caseignoreOnly = sal_True; 589cdf0e10cSrcweir } 590cdf0e10cSrcweir 591cdf0e10cSrcweir void TransliterationImpl::loadBody( OUString &implName, Reference<XExtendedTransliteration>& body ) 592cdf0e10cSrcweir throw (RuntimeException) 593cdf0e10cSrcweir { 594cdf0e10cSrcweir ::osl::MutexGuard guard(lastTransBody.mutex); 595cdf0e10cSrcweir 596cdf0e10cSrcweir if (implName.equals(lastTransBody.Name)) 597cdf0e10cSrcweir { 598cdf0e10cSrcweir // Use the cached body instead of going through the expensive looping again. 599cdf0e10cSrcweir body = lastTransBody.Body; 600cdf0e10cSrcweir return; 601cdf0e10cSrcweir } 602cdf0e10cSrcweir 603cdf0e10cSrcweir Reference< XContentEnumerationAccess > xEnumAccess( xSMgr, UNO_QUERY ); 604cdf0e10cSrcweir Reference< XEnumeration > xEnum(xEnumAccess->createContentEnumeration( 605cdf0e10cSrcweir OUString::createFromAscii(TRLT_SERVICELNAME_L10N))); 606cdf0e10cSrcweir if (xEnum.is()) { 607cdf0e10cSrcweir while (xEnum->hasMoreElements()) { 608cdf0e10cSrcweir Any a = xEnum->nextElement(); 609cdf0e10cSrcweir Reference< XServiceInfo > xsInfo; 610cdf0e10cSrcweir if (a >>= xsInfo) { 611cdf0e10cSrcweir if (implName.equals(xsInfo->getImplementationName())) { 612cdf0e10cSrcweir Reference< XSingleServiceFactory > xFactory; 613cdf0e10cSrcweir if (a >>= xFactory) { 614cdf0e10cSrcweir Reference< XInterface > xI = xFactory->createInstance(); 615cdf0e10cSrcweir if (xI.is()) { 616cdf0e10cSrcweir a = xI->queryInterface(::getCppuType(( 617cdf0e10cSrcweir const Reference<XExtendedTransliteration>*)0)); 618cdf0e10cSrcweir a >>= body; 619cdf0e10cSrcweir lastTransBody.Name = implName; 620cdf0e10cSrcweir lastTransBody.Body = body; 621cdf0e10cSrcweir return; 622cdf0e10cSrcweir } 623cdf0e10cSrcweir } 624cdf0e10cSrcweir } 625cdf0e10cSrcweir } 626cdf0e10cSrcweir } 627cdf0e10cSrcweir } 628cdf0e10cSrcweir throw ERROR; 629cdf0e10cSrcweir } 630cdf0e10cSrcweir 631cdf0e10cSrcweir sal_Bool SAL_CALL 632cdf0e10cSrcweir TransliterationImpl::loadModuleByName( const OUString& implName, 633cdf0e10cSrcweir Reference<XExtendedTransliteration>& body, const Locale& rLocale) throw(RuntimeException) 634cdf0e10cSrcweir { 635cdf0e10cSrcweir OUString cname = OUString::createFromAscii(TRLT_IMPLNAME_PREFIX) + implName; 636cdf0e10cSrcweir loadBody(cname, body); 637cdf0e10cSrcweir if (body.is()) { 638cdf0e10cSrcweir body->loadModule((TransliterationModules)0, rLocale); // toUpper/toLoad need rLocale 639cdf0e10cSrcweir 640cdf0e10cSrcweir // if the module is ignore case/kana/width, load caseignore for equals/compareString mothed 641cdf0e10cSrcweir for (sal_Int16 i = 0; i < 3; i++) { 642cdf0e10cSrcweir if (implName.compareToAscii(TMlist[i].implName) == 0) { 643cdf0e10cSrcweir if (i == 0) // current module is caseignore 644cdf0e10cSrcweir body->loadModule(TMlist[0].tm, rLocale); // caseingore need to setup module name 645cdf0e10cSrcweir if (! caseignore.is()) { 646cdf0e10cSrcweir OUString bname = OUString::createFromAscii(TRLT_IMPLNAME_PREFIX) + 647cdf0e10cSrcweir OUString::createFromAscii(TMlist[0].implName); 648cdf0e10cSrcweir loadBody(bname, caseignore); 649cdf0e10cSrcweir } 650cdf0e10cSrcweir if (caseignore.is()) 651cdf0e10cSrcweir caseignore->loadModule(TMlist[i].tm, rLocale); 652cdf0e10cSrcweir return sal_True; 653cdf0e10cSrcweir } 654cdf0e10cSrcweir } 655cdf0e10cSrcweir caseignoreOnly = sal_False; // has other module than just ignore case/kana/width 656cdf0e10cSrcweir } 657cdf0e10cSrcweir return body.is(); 658cdf0e10cSrcweir } 659cdf0e10cSrcweir 660cdf0e10cSrcweir const sal_Char cTrans[] = "com.sun.star.i18n.Transliteration"; 661cdf0e10cSrcweir 662cdf0e10cSrcweir OUString SAL_CALL 663cdf0e10cSrcweir TransliterationImpl::getImplementationName() throw( RuntimeException ) 664cdf0e10cSrcweir { 665cdf0e10cSrcweir return OUString::createFromAscii(cTrans); 666cdf0e10cSrcweir } 667cdf0e10cSrcweir 668cdf0e10cSrcweir 669cdf0e10cSrcweir sal_Bool SAL_CALL 670cdf0e10cSrcweir TransliterationImpl::supportsService(const OUString& rServiceName) throw( RuntimeException ) 671cdf0e10cSrcweir { 672cdf0e10cSrcweir return !rServiceName.compareToAscii(cTrans); 673cdf0e10cSrcweir } 674cdf0e10cSrcweir 675cdf0e10cSrcweir Sequence< OUString > SAL_CALL 676cdf0e10cSrcweir TransliterationImpl::getSupportedServiceNames(void) throw( RuntimeException ) 677cdf0e10cSrcweir { 678cdf0e10cSrcweir Sequence< OUString > aRet(1); 679cdf0e10cSrcweir aRet[0] = OUString::createFromAscii(cTrans); 680cdf0e10cSrcweir return aRet; 681cdf0e10cSrcweir } 682cdf0e10cSrcweir 683cdf0e10cSrcweir } } } } 684