LCOV - code coverage report
Current view: top level - i18npool/source/transliteration - transliterationImpl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 94 288 32.6 %
Date: 2012-08-25 Functions: 13 28 46.4 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 104 514 20.2 %

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

Generated by: LCOV version 1.10