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

Generated by: LCOV version 1.10