LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/i18npool/source/transliteration - transliterationImpl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 114 291 39.2 %
Date: 2013-07-09 Functions: 14 28 50.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : 
      21             : #include "transliterationImpl.hxx"
      22             : #include "servicename.hxx"
      23             : 
      24             : #include <com/sun/star/i18n/LocaleData.hpp>
      25             : #include <com/sun/star/i18n/TransliterationType.hpp>
      26             : #include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
      27             : #include <com/sun/star/lang/XComponent.hpp>
      28             : 
      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>
      34             : 
      35             : #include <algorithm>
      36             : 
      37             : #if OSL_DEBUG_LEVEL > 1
      38             : #include <stdio.h>
      39             : #endif
      40             : 
      41             : using namespace com::sun::star::uno;
      42             : using namespace com::sun::star::lang;
      43             : 
      44             : 
      45             : namespace com { namespace sun { namespace star { namespace i18n {
      46             : 
      47             : #define ERROR RuntimeException()
      48             : 
      49             : #define TmItem1( name ) \
      50             :   {TransliterationModules_##name, TransliterationModulesNew_##name, #name}
      51             : 
      52             : #define TmItem2( name ) \
      53             :   {(TransliterationModules)0, TransliterationModulesNew_##name, #name}
      54             : 
      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)
      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)
      83             : 
      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)
      90             : 
      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)
     122             : 
     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)
     130             : 
     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}
     137             : };
     138             : 
     139             : // Constructor/Destructor
     140         256 : TransliterationImpl::TransliterationImpl(const Reference <XComponentContext>& xContext) : mxContext(xContext)
     141             : {
     142         256 :     numCascade = 0;
     143         256 :     caseignoreOnly = sal_True;
     144             : 
     145         256 :     mxLocaledata.set(LocaleData::create(xContext));
     146         256 : }
     147             : 
     148         600 : TransliterationImpl::~TransliterationImpl()
     149             : {
     150         200 :     mxLocaledata.clear();
     151         200 :     clear();
     152         400 : }
     153             : 
     154             : 
     155             : // Methods
     156             : OUString SAL_CALL
     157           0 : TransliterationImpl::getName() throw(RuntimeException)
     158             : {
     159           0 :     if (numCascade == 1 && bodyCascade[0].is())
     160           0 :         return bodyCascade[0]->getName();
     161           0 :     if (numCascade < 1)
     162           0 :         return ( OUString("Not Loaded"));
     163           0 :     throw ERROR;
     164             : }
     165             : 
     166             : sal_Int16 SAL_CALL
     167           0 : TransliterationImpl::getType() throw(RuntimeException)
     168             : {
     169           0 :     if (numCascade > 1)
     170           0 :         return (TransliterationType::CASCADE|TransliterationType::IGNORE);
     171           0 :     if (numCascade > 0 && bodyCascade[0].is())
     172           0 :         return(bodyCascade[0]->getType());
     173           0 :     throw ERROR;
     174             : }
     175             : 
     176             : void SAL_CALL
     177         514 : TransliterationImpl::loadModule( TransliterationModules modType, const Locale& rLocale )
     178             :         throw(RuntimeException)
     179             : {
     180         514 :         clear();
     181         514 :     if (modType&TransliterationModules_IGNORE_MASK && modType&TransliterationModules_NON_IGNORE_MASK) {
     182           0 :         throw ERROR;
     183         514 :     } else if (modType&TransliterationModules_IGNORE_MASK) {
     184             : #define TransliterationModules_IGNORE_CASE_MASK (TransliterationModules_IGNORE_CASE | \
     185             :                                                 TransliterationModules_IGNORE_WIDTH | \
     186             :                                                 TransliterationModules_IGNORE_KANA)
     187         505 :         sal_Int32 mask = ((modType&TransliterationModules_IGNORE_CASE_MASK) == modType) ?
     188         505 :                 TransliterationModules_IGNORE_CASE_MASK : TransliterationModules_IGNORE_MASK;
     189        2020 :         for (sal_Int16 i = 0; TMlist[i].tm & mask; i++) {
     190        1515 :             if (modType & TMlist[i].tm)
     191        1210 :                 if (loadModuleByName(OUString::createFromAscii(TMlist[i].implName),
     192        1210 :                                                 bodyCascade[numCascade], rLocale))
     193         605 :                     numCascade++;
     194             :         }
     195             :         // additional transliterations from TranslationModuleExtra (we cannot extend TransliterationModule)
     196         505 :         if (modType & TransliterationModulesExtra::ignoreDiacritics_CTL)
     197             :         {
     198           0 :             if (loadModuleByName(OUString("ignoreDiacritics_CTL"), bodyCascade[numCascade], rLocale))
     199           0 :                 numCascade++;
     200             :         }
     201           9 :     } else if (modType&TransliterationModules_NON_IGNORE_MASK) {
     202         190 :         for (sal_Int16 i = 0; TMlist[i].tm; i++) {
     203         190 :             if (TMlist[i].tm == modType) {
     204           9 :                 if (loadModuleByName(OUString::createFromAscii(TMlist[i].implName), bodyCascade[numCascade], rLocale))
     205           9 :                     numCascade++;
     206           9 :                 break;
     207             :             }
     208             :         }
     209             :     }
     210         514 : }
     211             : 
     212             : void SAL_CALL
     213           0 : TransliterationImpl::loadModuleNew( const Sequence < TransliterationModulesNew > & modType, const Locale& rLocale )
     214             :   throw(RuntimeException)
     215             : {
     216           0 :     clear();
     217           0 :     sal_Int32 mask = 0, count = modType.getLength();
     218           0 :     if (count > maxCascade)
     219           0 :         throw ERROR; // could not handle more than maxCascade
     220           0 :     for (sal_Int16 i = 0; i < count; i++) {
     221           0 :         for (sal_Int16 j = 0; TMlist[j].tmn; j++) {
     222           0 :             if (TMlist[j].tmn == modType[i]) {
     223           0 :                 if (mask == 0)
     224           0 :                     mask = TMlist[i].tm && (TMlist[i].tm&TransliterationModules_IGNORE_MASK) ?
     225           0 :                         TransliterationModules_IGNORE_MASK : TransliterationModules_NON_IGNORE_MASK;
     226           0 :                 else if (mask == TransliterationModules_IGNORE_MASK &&
     227           0 :                         (TMlist[i].tm&TransliterationModules_IGNORE_MASK) == 0)
     228           0 :                     throw ERROR; // could not mess up ignore trans. with non_ignore trans.
     229           0 :                 if (loadModuleByName(OUString::createFromAscii(TMlist[j].implName), bodyCascade[numCascade], rLocale))
     230           0 :                     numCascade++;
     231           0 :                 break;
     232             :             }
     233             :         }
     234             :     }
     235           0 : }
     236             : 
     237             : void SAL_CALL
     238           3 : TransliterationImpl::loadModuleByImplName(const OUString& implName, const Locale& rLocale)
     239             :   throw(RuntimeException)
     240             : {
     241           3 :     clear();
     242           3 :     if (loadModuleByName(implName, bodyCascade[numCascade], rLocale))
     243           3 :         numCascade++;
     244           3 : }
     245             : 
     246             : 
     247             : void SAL_CALL
     248           0 : TransliterationImpl::loadModulesByImplNames(const Sequence< OUString >& implNameList, const Locale& rLocale ) throw(RuntimeException)
     249             : {
     250           0 :     if (implNameList.getLength() > maxCascade || implNameList.getLength() <= 0)
     251           0 :         throw ERROR;
     252             : 
     253           0 :     clear();
     254           0 :     for (sal_Int32 i = 0; i < implNameList.getLength(); i++)
     255           0 :         if (loadModuleByName(implNameList[i], bodyCascade[numCascade], rLocale))
     256           0 :             numCascade++;
     257           0 : }
     258             : 
     259             : 
     260             : Sequence<OUString> SAL_CALL
     261           0 : TransliterationImpl::getAvailableModules( const Locale& rLocale, sal_Int16 sType ) throw(RuntimeException)
     262             : {
     263           0 :     const Sequence<OUString> &translist = mxLocaledata->getTransliterations(rLocale);
     264           0 :     Sequence<OUString> r(translist.getLength());
     265           0 :     Reference<XExtendedTransliteration> body;
     266           0 :     sal_Int32 n = 0;
     267           0 :     for (sal_Int32 i = 0; i < translist.getLength(); i++)
     268             :     {
     269           0 :         if (loadModuleByName(translist[i], body, rLocale)) {
     270           0 :             if (body->getType() & sType)
     271           0 :                 r[n++] = translist[i];
     272           0 :             body.clear();
     273             :         }
     274             :     }
     275           0 :     r.realloc(n);
     276           0 :     return (r);
     277             : }
     278             : 
     279             : 
     280             : OUString SAL_CALL
     281         477 : TransliterationImpl::transliterate( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
     282             :                     Sequence< sal_Int32 >& offset ) throw(RuntimeException)
     283             : {
     284         477 :     if (numCascade == 0)
     285           0 :         return inStr;
     286             : 
     287         477 :     if (offset.getLength() != nCount)
     288          36 :         offset.realloc(nCount);
     289         477 :     if (numCascade == 1)
     290             :     {
     291         471 :         if ( startPos == 0 && nCount == inStr.getLength() )
     292         471 :             return bodyCascade[0]->transliterate( inStr, 0, nCount, offset);
     293             :         else
     294             :         {
     295           0 :             OUString tmpStr = inStr.copy(startPos, nCount);
     296           0 :             tmpStr = bodyCascade[0]->transliterate(tmpStr, 0, nCount, offset);
     297           0 :             if ( startPos )
     298             :             {
     299           0 :                 sal_Int32 * pArr = offset.getArray();
     300           0 :                 nCount = offset.getLength();
     301           0 :                 for (sal_Int32 j = 0; j < nCount; j++)
     302           0 :                     pArr[j] += startPos;
     303             :             }
     304           0 :             return tmpStr;
     305             :         }
     306             :     }
     307             :     else
     308             :     {
     309           6 :         OUString tmpStr = inStr.copy(startPos, nCount);
     310           6 :         sal_Int32 * pArr = offset.getArray();
     311          12 :         for (sal_Int32 j = 0; j < nCount; j++)
     312           6 :             pArr[j] = startPos + j;
     313             : 
     314           6 :         sal_Int16 from = 0, to = 1, tmp;
     315          12 :         Sequence<sal_Int32> off[2];
     316             : 
     317           6 :         off[to] = offset;
     318           6 :         off[from].realloc(nCount);
     319          18 :         for (sal_Int32 i = 0; i < numCascade; i++) {
     320          12 :             tmpStr = bodyCascade[i]->transliterate(tmpStr, 0, nCount, off[from]);
     321             : 
     322          12 :             nCount = tmpStr.getLength();
     323             : 
     324          12 :             tmp = from; from = to; to = tmp;
     325          24 :             for (sal_Int32 j = 0; j < nCount; j++)
     326          12 :                 off[to][j] = off[from][off[to][j]];
     327             :         }
     328           6 :         offset = off[to];
     329          12 :         return tmpStr;
     330             :     }
     331             : }
     332             : 
     333             : 
     334             : //
     335             : OUString SAL_CALL
     336           0 : TransliterationImpl::folding( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
     337             :         Sequence< sal_Int32 >& offset ) throw(RuntimeException)
     338             : {
     339           0 :     if (numCascade == 0)
     340           0 :         return inStr;
     341             : 
     342           0 :     if (offset.getLength() != nCount)
     343           0 :         offset.realloc(nCount);
     344           0 :     if (numCascade == 1)
     345             :     {
     346           0 :         if ( startPos == 0 && nCount == inStr.getLength() )
     347           0 :             return bodyCascade[0]->folding( inStr, 0, nCount, offset);
     348             :         else
     349             :         {
     350           0 :             OUString tmpStr = inStr.copy(startPos, nCount);
     351           0 :             tmpStr = bodyCascade[0]->folding(tmpStr, 0, nCount, offset);
     352           0 :             if ( startPos )
     353             :             {
     354           0 :                 sal_Int32 * pArr = offset.getArray();
     355           0 :                 nCount = offset.getLength();
     356           0 :                 for (sal_Int32 j = 0; j < nCount; j++)
     357           0 :                     pArr[j] += startPos;
     358             :             }
     359           0 :             return tmpStr;
     360             :         }
     361             :     }
     362             :     else
     363             :     {
     364           0 :         OUString tmpStr = inStr.copy(startPos, nCount);
     365           0 :         sal_Int32 * pArr = offset.getArray();
     366           0 :         for (sal_Int32 j = 0; j < nCount; j++)
     367           0 :             pArr[j] = startPos + j;
     368             : 
     369           0 :         sal_Int16 from = 0, to = 1, tmp;
     370           0 :         Sequence<sal_Int32> off[2];
     371             : 
     372           0 :         off[to] = offset;
     373           0 :         for (sal_Int32 i = 0; i < numCascade; i++) {
     374           0 :             tmpStr = bodyCascade[i]->folding(tmpStr, 0, nCount, off[from]);
     375             : 
     376           0 :             nCount = tmpStr.getLength();
     377             : 
     378           0 :             tmp = from; from = to; to = tmp;
     379           0 :             for (sal_Int32 j = 0; j < nCount; j++)
     380           0 :                 off[to][j] = off[from][off[to][j]];
     381             :         }
     382           0 :         offset = off[to];
     383           0 :         return tmpStr;
     384             :     }
     385             : }
     386             : 
     387             : OUString SAL_CALL
     388          34 : TransliterationImpl::transliterateString2String( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount ) throw(RuntimeException)
     389             : {
     390          34 :     if (numCascade == 0)
     391           0 :         return inStr;
     392          34 :     else if (numCascade == 1)
     393          33 :         return bodyCascade[0]->transliterateString2String( inStr, startPos, nCount);
     394             :     else {
     395           1 :         OUString tmpStr = bodyCascade[0]->transliterateString2String(inStr, startPos, nCount);
     396             : 
     397           2 :         for (sal_Int32 i = 1; i < numCascade; i++)
     398           1 :             tmpStr = bodyCascade[i]->transliterateString2String(tmpStr, 0, tmpStr.getLength());
     399           1 :         return tmpStr;
     400             :     }
     401             : }
     402             : 
     403             : OUString SAL_CALL
     404           0 : TransliterationImpl::transliterateChar2String( sal_Unicode inChar ) throw(RuntimeException)
     405             : {
     406           0 :     if (numCascade == 0)
     407           0 :         return OUString(&inChar, 1);
     408           0 :     else if (numCascade == 1)
     409           0 :         return bodyCascade[0]->transliterateChar2String( inChar);
     410             :     else {
     411           0 :         OUString tmpStr = bodyCascade[0]->transliterateChar2String(inChar);
     412             : 
     413           0 :         for (sal_Int32 i = 1; i < numCascade; i++)
     414           0 :             tmpStr = bodyCascade[i]->transliterateString2String(tmpStr, 0, tmpStr.getLength());
     415           0 :         return tmpStr;
     416             :     }
     417             : }
     418             : 
     419             : sal_Unicode SAL_CALL
     420           0 : TransliterationImpl::transliterateChar2Char( sal_Unicode inChar ) throw(MultipleCharsOutputException, RuntimeException)
     421             : {
     422           0 :     sal_Unicode tmpChar = inChar;
     423           0 :     for (sal_Int32 i = 0; i < numCascade; i++)
     424           0 :         tmpChar = bodyCascade[i]->transliterateChar2Char(tmpChar);
     425           0 :     return tmpChar;
     426             : }
     427             : 
     428             : 
     429             : sal_Bool SAL_CALL
     430        5886 : TransliterationImpl::equals(
     431             :     const OUString& str1, sal_Int32 pos1, sal_Int32 nCount1, sal_Int32& nMatch1,
     432             :     const OUString& str2, sal_Int32 pos2, sal_Int32 nCount2, sal_Int32& nMatch2)
     433             :     throw(RuntimeException)
     434             : {
     435             :     // since this is an API function make it user fail safe
     436        5886 :     if ( nCount1 < 0 ) {
     437           0 :         pos1 += nCount1;
     438           0 :         nCount1 = -nCount1;
     439             :     }
     440        5886 :     if ( nCount2 < 0 ) {
     441           0 :         pos2 += nCount2;
     442           0 :         nCount2 = -nCount2;
     443             :     }
     444       15933 :     if ( !nCount1 || !nCount2 ||
     445       10026 :             pos1 >= str1.getLength() || pos2 >= str2.getLength() ||
     446       10899 :             pos1 < 0 || pos2 < 0 ) {
     447         873 :         nMatch1 = nMatch2 = 0;
     448             :         // two empty strings return true, else false
     449         873 :         return !nCount1 && !nCount2 && pos1 == str1.getLength() && pos2 == str2.getLength();
     450             :     }
     451        5013 :     if ( pos1 + nCount1 > str1.getLength() )
     452           0 :         nCount1 = str1.getLength() - pos1;
     453        5013 :     if ( pos2 + nCount2 > str2.getLength() )
     454           0 :         nCount2 = str2.getLength() - pos2;
     455             : 
     456        5013 :     if (caseignoreOnly && caseignore.is())
     457        5013 :         return caseignore->equals(str1, pos1, nCount1, nMatch1, str2, pos2, nCount2, nMatch2);
     458             : 
     459           0 :     Sequence<sal_Int32> offset1, offset2;
     460             : 
     461           0 :     OUString tmpStr1 = folding(str1, pos1, nCount1, offset1);
     462           0 :     OUString tmpStr2 = folding(str2, pos2, nCount2, offset2);
     463             :     // Length of offset1 and offset2 may still be 0 if there was no folding
     464             :     // necessary!
     465             : 
     466           0 :     const sal_Unicode *p1 = tmpStr1.getStr();
     467           0 :     const sal_Unicode *p2 = tmpStr2.getStr();
     468           0 :     sal_Int32 i, nLen = ::std::min( tmpStr1.getLength(), tmpStr2.getLength());
     469           0 :     for (i = 0; i < nLen; ++i, ++p1, ++p2 ) {
     470           0 :         if (*p1 != *p2) {
     471             :             // return number of matched code points so far
     472           0 :             nMatch1 = (i < offset1.getLength()) ? offset1[i] : i;
     473           0 :             nMatch2 = (i < offset2.getLength()) ? offset2[i] : i;
     474           0 :             return sal_False;
     475             :         }
     476             :     }
     477             :     // i==nLen
     478           0 :     if ( tmpStr1.getLength() != tmpStr2.getLength() ) {
     479             :         // return number of matched code points so far
     480           0 :         nMatch1 = (i <= offset1.getLength()) ? offset1[i-1] + 1 : i;
     481           0 :         nMatch2 = (i <= offset2.getLength()) ? offset2[i-1] + 1 : i;
     482           0 :         return sal_False;
     483             :     } else {
     484           0 :         nMatch1 = nCount1;
     485           0 :         nMatch2 = nCount2;
     486           0 :         return sal_True;
     487           0 :     }
     488             : }
     489             : 
     490             : #define MaxOutput 2
     491             : 
     492             : Sequence< OUString > SAL_CALL
     493           0 : TransliterationImpl::getRange(const Sequence< OUString > &inStrs,
     494             :                 const sal_Int32 length, sal_Int16 _numCascade) throw(RuntimeException)
     495             : {
     496           0 :     if (_numCascade >= numCascade || ! bodyCascade[_numCascade].is())
     497           0 :         return inStrs;
     498             : 
     499           0 :     sal_Int32 j_tmp = 0;
     500           0 :     Sequence< OUString > ostr(MaxOutput*length);
     501           0 :     for (sal_Int32 j = 0; j < length; j+=2) {
     502           0 :         const Sequence< OUString >& temp = bodyCascade[_numCascade]->transliterateRange(inStrs[j], inStrs[j+1]);
     503             : 
     504           0 :         for ( sal_Int32 k = 0; k < temp.getLength(); k++) {
     505           0 :             if ( j_tmp >= MaxOutput*length ) throw ERROR;
     506           0 :             ostr[j_tmp++]  = temp[k];
     507             :         }
     508           0 :     }
     509           0 :     ostr.realloc(j_tmp);
     510             : 
     511           0 :     return this->getRange(ostr, j_tmp, ++_numCascade);
     512             : }
     513             : 
     514             : 
     515             : Sequence< OUString > SAL_CALL
     516           0 : TransliterationImpl::transliterateRange( const OUString& str1, const OUString& str2 )
     517             : throw(RuntimeException)
     518             : {
     519           0 :     if (numCascade == 1)
     520           0 :         return bodyCascade[0]->transliterateRange(str1, str2);
     521             : 
     522           0 :     Sequence< OUString > ostr(2);
     523           0 :     ostr[0] = str1;
     524           0 :     ostr[1] = str2;
     525             : 
     526           0 :     return this->getRange(ostr, 2, 0);
     527             : }
     528             : 
     529             : 
     530             : sal_Int32 SAL_CALL
     531           0 : TransliterationImpl::compareSubstring(
     532             :     const OUString& str1, sal_Int32 off1, sal_Int32 len1,
     533             :     const OUString& str2, sal_Int32 off2, sal_Int32 len2)
     534             :     throw(RuntimeException)
     535             : {
     536           0 :     if (caseignoreOnly && caseignore.is())
     537           0 :         return caseignore->compareSubstring(str1, off1, len1, str2, off2, len2);
     538             : 
     539           0 :     Sequence <sal_Int32> offset;
     540             : 
     541           0 :     OUString in_str1 = this->transliterate(str1, off1, len1, offset);
     542           0 :     OUString in_str2 = this->transliterate(str2, off2, len2, offset);
     543           0 :     const sal_Unicode* unistr1 = in_str1.getStr();
     544           0 :     const sal_Unicode* unistr2 = in_str2.getStr();
     545           0 :     sal_Int32 strlen1 = in_str1.getLength();
     546           0 :     sal_Int32 strlen2 = in_str2.getLength();
     547             : 
     548           0 :     while (strlen1 && strlen2) {
     549           0 :         if (*unistr1 != *unistr2)
     550           0 :            return *unistr1 > *unistr2 ? 1 : -1;
     551             : 
     552           0 :         unistr1++; unistr2++; strlen1--; strlen2--;
     553             :     }
     554           0 :     return strlen1 == strlen2 ? 0 : (strlen1 > strlen2 ? 1 : -1);
     555             : }
     556             : 
     557             : 
     558             : sal_Int32 SAL_CALL
     559          74 : TransliterationImpl::compareString(const OUString& str1, const OUString& str2 ) throw (RuntimeException)
     560             : {
     561          74 :     if (caseignoreOnly && caseignore.is())
     562          74 :         return caseignore->compareString(str1, str2);
     563             :     else
     564           0 :         return this->compareSubstring(str1, 0, str1.getLength(), str2, 0, str2.getLength());
     565             : }
     566             : 
     567             : 
     568             : void
     569         717 : TransliterationImpl::clear()
     570             : {
     571        1259 :     for (sal_Int32 i = 0; i < numCascade; i++)
     572         542 :         if (bodyCascade[i].is())
     573         542 :             bodyCascade[i].clear();
     574         717 :     numCascade = 0;
     575         717 :     caseignore.clear();
     576         717 :     caseignoreOnly = sal_True;
     577         717 : }
     578             : 
     579             : namespace
     580             : {
     581             :     /** structure to cache the last transliteration body used. */
     582         124 :     struct TransBody
     583             :     {
     584             :         OUString Name;
     585             :         ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XExtendedTransliteration > Body;
     586             :     };
     587             :     class theTransBodyMutex : public rtl::Static<osl::Mutex, theTransBodyMutex> {};
     588             : }
     589             : 
     590        1122 : void TransliterationImpl::loadBody( OUString &implName, Reference<XExtendedTransliteration>& body )
     591             :     throw (RuntimeException)
     592             : {
     593             :     assert(!implName.isEmpty());
     594        1122 :     ::osl::MutexGuard guard(theTransBodyMutex::get());
     595        1122 :     static TransBody lastTransBody;
     596        1122 :     if (implName != lastTransBody.Name)
     597             :     {
     598             :         lastTransBody.Body.set(
     599         199 :             mxContext->getServiceManager()->createInstanceWithContext(implName, mxContext), UNO_QUERY_THROW);
     600         199 :         lastTransBody.Name = implName;
     601             :     }
     602        1122 :     body = lastTransBody.Body;
     603        1122 : }
     604             : 
     605             : sal_Bool SAL_CALL
     606         617 : TransliterationImpl::loadModuleByName( const OUString& implName,
     607             :         Reference<XExtendedTransliteration>& body, const Locale& rLocale) throw(RuntimeException)
     608             : {
     609         617 :     OUString cname = OUString(TRLT_IMPLNAME_PREFIX) + implName;
     610         617 :     loadBody(cname, body);
     611         617 :     if (body.is()) {
     612         617 :         body->loadModule((TransliterationModules)0, rLocale); // toUpper/toLoad need rLocale
     613             : 
     614             :         // if the module is ignore case/kana/width, load caseignore for equals/compareString mothed
     615         785 :         for (sal_Int16 i = 0; i < 3; i++) {
     616         773 :             if (implName.compareToAscii(TMlist[i].implName) == 0) {
     617         605 :                 if (i == 0) // current module is caseignore
     618         505 :                     body->loadModule(TMlist[0].tm, rLocale); // caseingore need to setup module name
     619         605 :                 if (! caseignore.is()) {
     620        1010 :                     OUString bname = OUString(TRLT_IMPLNAME_PREFIX) +
     621        1515 :                                 OUString::createFromAscii(TMlist[0].implName);
     622         505 :                     loadBody(bname, caseignore);
     623             :                 }
     624         605 :                 if (caseignore.is())
     625         605 :                     caseignore->loadModule(TMlist[i].tm, rLocale);
     626         605 :                 return sal_True;
     627             :             }
     628             :         }
     629          12 :         caseignoreOnly = sal_False; // has other module than just ignore case/kana/width
     630             :     }
     631          12 :     return body.is();
     632             : }
     633             : 
     634             : const sal_Char cTrans[] = "com.sun.star.i18n.Transliteration";
     635             : 
     636             : OUString SAL_CALL
     637           0 : TransliterationImpl::getImplementationName() throw( RuntimeException )
     638             : {
     639           0 :     return OUString::createFromAscii(cTrans);
     640             : }
     641             : 
     642             : 
     643             : sal_Bool SAL_CALL
     644           0 : TransliterationImpl::supportsService(const OUString& rServiceName) throw( RuntimeException )
     645             : {
     646           0 :     return !rServiceName.compareToAscii(cTrans);
     647             : }
     648             : 
     649             : Sequence< OUString > SAL_CALL
     650           0 : TransliterationImpl::getSupportedServiceNames(void) throw( RuntimeException )
     651             : {
     652           0 :     Sequence< OUString > aRet(1);
     653           0 :     aRet[0] = OUString::createFromAscii(cTrans);
     654           0 :     return aRet;
     655             : }
     656             : 
     657             : } } } }
     658             : 
     659             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10