LCOV - code coverage report
Current view: top level - i18npool/source/nativenumber - nativenumbersupplier.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 438 0.0 %
Date: 2012-08-25 Functions: 0 18 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 519 0.0 %

           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                 :            : #include <i18npool/mslangid.hxx>
      21                 :            : #include <rtl/ustrbuf.hxx>
      22                 :            : #include <sal/macros.h>
      23                 :            : #include <nativenumbersupplier.hxx>
      24                 :            : #include <localedata.hxx>
      25                 :            : #include <data/numberchar.h>
      26                 :            : #include <comphelper/string.hxx>
      27                 :            : 
      28                 :            : using namespace ::com::sun::star::uno;
      29                 :            : using namespace ::com::sun::star::lang;
      30                 :            : using namespace ::com::sun::star::lang;
      31                 :            : using namespace ::rtl;
      32                 :            : 
      33                 :            : 
      34                 :            : typedef struct {
      35                 :            :     sal_Int16 number;
      36                 :            :     sal_Unicode *multiplierChar;
      37                 :            :     sal_Int16 numberFlag;
      38                 :            :     sal_Int16 exponentCount;
      39                 :            :     sal_Int16 *multiplierExponent;
      40                 :            : } Number;
      41                 :            : 
      42                 :            : 
      43                 :            : #define NUMBER_OMIT_ZERO (1 << 0)
      44                 :            : #define NUMBER_OMIT_ONLY_ZERO  (1 << 1)
      45                 :            : #define NUMBER_OMIT_ONE_1  (1 << 2)
      46                 :            : #define NUMBER_OMIT_ONE_2  (1 << 3)
      47                 :            : #define NUMBER_OMIT_ONE_3  (1 << 4)
      48                 :            : #define NUMBER_OMIT_ONE_4  (1 << 5)
      49                 :            : #define NUMBER_OMIT_ONE_5  (1 << 6)
      50                 :            : #define NUMBER_OMIT_ONE_6  (1 << 7)
      51                 :            : #define NUMBER_OMIT_ONE_7  (1 << 8)
      52                 :            : #define NUMBER_OMIT_ONE  (NUMBER_OMIT_ONE_1|NUMBER_OMIT_ONE_2|NUMBER_OMIT_ONE_3|NUMBER_OMIT_ONE_4|NUMBER_OMIT_ONE_5|NUMBER_OMIT_ONE_6|NUMBER_OMIT_ONE_7)
      53                 :            : #define NUMBER_OMIT_ONE_CHECK(bit)  (1 << (2 + bit))
      54                 :            : #define NUMBER_OMIT_ALL ( NUMBER_OMIT_ZERO|NUMBER_OMIT_ONE|NUMBER_OMIT_ONLY_ZERO )
      55                 :            : #define NUMBER_OMIT_ZERO_ONE ( NUMBER_OMIT_ZERO|NUMBER_OMIT_ONE )
      56                 :            : #define NUMBER_OMIT_ONE_67 (NUMBER_OMIT_ONE_6|NUMBER_OMIT_ONE_7)
      57                 :            : #define NUMBER_OMIT_ZERO_ONE_67 ( NUMBER_OMIT_ZERO|NUMBER_OMIT_ONE_67 )
      58                 :            : 
      59                 :            : 
      60                 :            : #define MAX_SAL_UINT32  0xFFFFFFFF
      61                 :            : #define MAX_VALUE       (MAX_SAL_UINT32 - 9) / 10
      62                 :            : 
      63                 :            : namespace com { namespace sun { namespace star { namespace i18n {
      64                 :            : 
      65                 :            : OUString SAL_CALL getHebrewNativeNumberString(const OUString& aNumberString, sal_Bool useGeresh);
      66                 :            : 
      67                 :          0 : OUString SAL_CALL AsciiToNativeChar( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
      68                 :            :         Sequence< sal_Int32 >& offset, sal_Bool useOffset, sal_Int16 number ) throw(RuntimeException)
      69                 :            : {
      70                 :          0 :         const sal_Unicode *src = inStr.getStr() + startPos;
      71                 :          0 :         rtl_uString *newStr = comphelper::string::rtl_uString_alloc(nCount);
      72         [ #  # ]:          0 :         if (useOffset)
      73                 :          0 :             offset.realloc(nCount);
      74                 :            : 
      75         [ #  # ]:          0 :         for (sal_Int32 i = 0; i < nCount; i++)
      76                 :            :         {
      77                 :          0 :             sal_Unicode ch = src[i];
      78 [ #  # ][ #  # ]:          0 :             if (isNumber(ch))
      79                 :          0 :                 newStr->buffer[i] = NumberChar[number][ ch - NUMBER_ZERO ];
      80 [ #  # ][ #  # ]:          0 :             else if (i+1 < nCount && isNumber(src[i+1])) {
                 [ #  # ]
      81 [ #  # ][ #  # ]:          0 :                 if (i > 0 && isNumber(src[i-1]) && isSeparator(ch))
         [ #  # ][ #  # ]
      82         [ #  # ]:          0 :                     newStr->buffer[i] = SeparatorChar[number] ? SeparatorChar[number] : ch;
      83                 :            :                 else
      84                 :          0 :                     newStr->buffer[i] = isDecimal(ch) ? (DecimalChar[number] ? DecimalChar[number] : ch) :
      85 [ #  # ][ #  # ]:          0 :                             isMinus(ch) ? (MinusChar[number] ? MinusChar[number] : ch) : ch;
         [ #  # ][ #  # ]
      86                 :            :             }
      87                 :            :             else
      88                 :          0 :                 newStr->buffer[i] = ch;
      89         [ #  # ]:          0 :             if (useOffset)
      90                 :          0 :                 offset[i] = startPos + i;
      91                 :            :         }
      92                 :          0 :         return OUString(newStr, SAL_NO_ACQUIRE); // take ownership
      93                 :            : }
      94                 :            : 
      95                 :          0 : sal_Bool SAL_CALL AsciiToNative_numberMaker(const sal_Unicode *str, sal_Int32 begin, sal_Int32 len,
      96                 :            :         sal_Unicode *dst, sal_Int32& count, sal_Int16 multiChar_index, Sequence< sal_Int32 >& offset, sal_Bool useOffset, sal_Int32 startPos,
      97                 :            :  Number *number, sal_Unicode* numberChar)
      98                 :            : {
      99         [ #  # ]:          0 :         sal_Unicode multiChar = (multiChar_index == -1 ? 0 : number->multiplierChar[multiChar_index]);
     100         [ #  # ]:          0 :         if ( len <= number->multiplierExponent[number->exponentCount-1] ) {
     101         [ #  # ]:          0 :             if (number->multiplierExponent[number->exponentCount-1] > 1) {
     102                 :            :                 sal_Int16 i;
     103                 :          0 :                 sal_Bool notZero = false;
     104         [ #  # ]:          0 :                 for (i = 0; i < len; i++, begin++) {
     105 [ #  # ][ #  # ]:          0 :                     if (notZero || str[begin] != NUMBER_ZERO) {
     106                 :          0 :                         dst[count] = numberChar[str[begin] - NUMBER_ZERO];
     107         [ #  # ]:          0 :                         if (useOffset)
     108                 :          0 :                             offset[count] = begin + startPos;
     109                 :          0 :                         count++;
     110                 :          0 :                         notZero = sal_True;
     111                 :            :                     }
     112                 :            :                 }
     113 [ #  # ][ #  # ]:          0 :                 if (notZero && multiChar > 0) {
     114                 :          0 :                     dst[count] = multiChar;
     115         [ #  # ]:          0 :                     if (useOffset)
     116                 :          0 :                         offset[count] = begin + startPos;
     117                 :          0 :                     count++;
     118                 :            :                 }
     119                 :          0 :                 return notZero;
     120         [ #  # ]:          0 :             } else if (str[begin] != NUMBER_ZERO) {
     121 [ #  # ][ #  # ]:          0 :                 if (!(number->numberFlag & (multiChar_index < 0 ? 0 : NUMBER_OMIT_ONE_CHECK(multiChar_index))) || str[begin] != NUMBER_ONE) {
                 [ #  # ]
     122                 :          0 :                     dst[count] = numberChar[str[begin] - NUMBER_ZERO];
     123         [ #  # ]:          0 :                     if (useOffset)
     124                 :          0 :                         offset[count] = begin + startPos;
     125                 :          0 :                     count++;
     126                 :            :                 }
     127         [ #  # ]:          0 :                 if (multiChar > 0) {
     128                 :          0 :                     dst[count] = multiChar;
     129         [ #  # ]:          0 :                     if (useOffset)
     130                 :          0 :                         offset[count] = begin + startPos;
     131                 :          0 :                     count++;
     132                 :            :                 }
     133 [ #  # ][ #  # ]:          0 :             } else if (!(number->numberFlag & NUMBER_OMIT_ZERO) && count > 0 && dst[count-1] != numberChar[0]) {
                 [ #  # ]
     134                 :          0 :                 dst[count] = numberChar[0];
     135         [ #  # ]:          0 :                 if (useOffset)
     136                 :          0 :                     offset[count] = begin + startPos;
     137                 :          0 :                 count++;
     138                 :            :             }
     139                 :          0 :             return str[begin] != NUMBER_ZERO;
     140                 :            :         } else {
     141                 :          0 :             sal_Bool printPower = sal_False;
     142                 :            :             // sal_Int16 last = 0;
     143         [ #  # ]:          0 :             for (sal_Int16 i = 1; i <= number->exponentCount; i++) {
     144         [ #  # ]:          0 :                 sal_Int32 tmp = len - (i == number->exponentCount ? 0 : number->multiplierExponent[i]);
     145         [ #  # ]:          0 :                 if (tmp > 0) {
     146                 :            :                     printPower |= AsciiToNative_numberMaker(str, begin, tmp, dst, count,
     147         [ #  # ]:          0 :                         (i == number->exponentCount ? -1 : i), offset, useOffset, startPos, number, numberChar);
     148                 :          0 :                     begin += tmp;
     149                 :          0 :                     len -= tmp;
     150                 :            :                 }
     151                 :            :             }
     152         [ #  # ]:          0 :             if (printPower) {
     153 [ #  # ][ #  # ]:          0 :                 if (count > 0 && number->multiplierExponent[number->exponentCount-1] == 1 &&
                 [ #  # ]
     154                 :          0 :                             dst[count-1] == numberChar[0])
     155                 :          0 :                     count--;
     156         [ #  # ]:          0 :                 if (multiChar > 0) {
     157                 :          0 :                     dst[count] = multiChar;
     158         [ #  # ]:          0 :                     if (useOffset)
     159                 :          0 :                         offset[count] = begin + startPos;
     160                 :          0 :                     count++;
     161                 :            :                 }
     162                 :            :             }
     163                 :          0 :             return printPower;
     164                 :            :         }
     165                 :            : }
     166                 :            : 
     167                 :          0 : OUString SAL_CALL AsciiToNative( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
     168                 :            :         Sequence< sal_Int32 >& offset, sal_Bool useOffset, Number* number ) throw(RuntimeException)
     169                 :            : {
     170                 :          0 :         rtl::OUString aRet;
     171                 :            : 
     172                 :          0 :         sal_Int32 strLen = inStr.getLength() - startPos;
     173                 :          0 :         sal_Unicode *numberChar = NumberChar[number->number];
     174                 :            : 
     175         [ #  # ]:          0 :         if (nCount > strLen)
     176                 :          0 :             nCount = strLen;
     177                 :            : 
     178         [ #  # ]:          0 :         if (nCount > 0)
     179                 :            :         {
     180                 :          0 :             const sal_Unicode *str = inStr.getStr() + startPos;
     181         [ #  # ]:          0 :             sal_Unicode *newStr = new sal_Unicode[nCount * 2 + 1];
     182         [ #  # ]:          0 :             sal_Unicode *srcStr = new sal_Unicode[nCount + 1]; // for keeping number without comma
     183                 :          0 :             sal_Int32 i, len = 0, count = 0;
     184                 :            : 
     185         [ #  # ]:          0 :             if (useOffset)
     186         [ #  # ]:          0 :                 offset.realloc( nCount * 2 );
     187                 :          0 :             sal_Bool doDecimal = sal_False;
     188                 :            : 
     189         [ #  # ]:          0 :             for (i = 0; i <= nCount; i++)
     190                 :            :             {
     191 [ #  # ][ #  # ]:          0 :                 if (i < nCount && isNumber(str[i])) {
                 [ #  # ]
     192         [ #  # ]:          0 :                     if (doDecimal) {
     193                 :          0 :                         newStr[count] = numberChar[str[i] - NUMBER_ZERO];
     194         [ #  # ]:          0 :                         if (useOffset)
     195         [ #  # ]:          0 :                             offset[count] = i + startPos;
     196                 :          0 :                         count++;
     197                 :            :                     }
     198                 :            :                     else
     199                 :          0 :                         srcStr[len++] = str[i];
     200                 :            :                 } else {
     201         [ #  # ]:          0 :                     if (len > 0) {
     202 [ #  # ][ #  # ]:          0 :                         if (isSeparator(str[i]) && i < nCount-1 && isNumber(str[i+1]))
         [ #  # ][ #  # ]
     203                 :          0 :                             continue; // skip comma inside number string
     204                 :          0 :                         sal_Bool notZero = sal_False;
     205         [ #  # ]:          0 :                         for (sal_Int32 begin = 0, end = len % number->multiplierExponent[0];
     206                 :          0 :                                 end <= len; begin = end, end += number->multiplierExponent[0]) {
     207         [ #  # ]:          0 :                             if (end == 0) continue;
     208                 :          0 :                             sal_Int32 _count = count;
     209                 :            :                             notZero |= AsciiToNative_numberMaker(srcStr, begin, end - begin, newStr, count,
     210 [ #  # ][ #  # ]:          0 :                                         end == len ? -1 : 0, offset, useOffset, i - len + startPos, number, numberChar);
     211 [ #  # ][ #  # ]:          0 :                             if (count > 0 && number->multiplierExponent[number->exponentCount-1] == 1 &&
                 [ #  # ]
     212                 :          0 :                                         newStr[count-1] == numberChar[0])
     213                 :          0 :                                 count--;
     214 [ #  # ][ #  # ]:          0 :                             if (notZero && _count == count) {
     215         [ #  # ]:          0 :                                 if (end != len) {
     216                 :          0 :                                     newStr[count] = number->multiplierChar[0];
     217         [ #  # ]:          0 :                                     if (useOffset)
     218         [ #  # ]:          0 :                                         offset[count] = i - len + startPos;
     219                 :          0 :                                     count++;
     220                 :            :                                 }
     221                 :            :                             }
     222                 :            :                         }
     223 [ #  # ][ #  # ]:          0 :                         if (! notZero && ! (number->numberFlag & NUMBER_OMIT_ONLY_ZERO)) {
     224                 :          0 :                             newStr[count] = numberChar[0];
     225         [ #  # ]:          0 :                             if (useOffset)
     226         [ #  # ]:          0 :                                 offset[count] = i - len + startPos;
     227                 :          0 :                             count++;
     228                 :            :                         }
     229                 :          0 :                         len = 0;
     230                 :            :                     }
     231         [ #  # ]:          0 :                     if (i < nCount) {
     232 [ #  # ][ #  # ]:          0 :                         if ((doDecimal = (!doDecimal && isDecimal(str[i]) && i < nCount-1 && isNumber(str[i+1]))) != sal_False)
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     233         [ #  # ]:          0 :                             newStr[count] = (DecimalChar[number->number] ? DecimalChar[number->number] : str[i]);
     234 [ #  # ][ #  # ]:          0 :                         else if (isMinus(str[i]) && i < nCount-1 && isNumber(str[i+1]))
         [ #  # ][ #  # ]
     235         [ #  # ]:          0 :                             newStr[count] = (MinusChar[number->number] ? MinusChar[number->number] : str[i]);
     236 [ #  # ][ #  # ]:          0 :                         else if (isSeparator(str[i]) && i < nCount-1 && isNumber(str[i+1]))
         [ #  # ][ #  # ]
     237         [ #  # ]:          0 :                             newStr[count] = (SeparatorChar[number->number] ? SeparatorChar[number->number] : str[i]);
     238                 :            :                         else
     239                 :          0 :                             newStr[count] = str[i];
     240         [ #  # ]:          0 :                         if (useOffset)
     241         [ #  # ]:          0 :                             offset[count] = i + startPos;
     242                 :          0 :                         count++;
     243                 :            :                     }
     244                 :            :                 }
     245                 :            :             }
     246                 :            : 
     247         [ #  # ]:          0 :             delete[] srcStr;
     248                 :            : 
     249         [ #  # ]:          0 :             if (useOffset)
     250         [ #  # ]:          0 :                 offset.realloc(count);
     251                 :          0 :             aRet = OUString(newStr, count);
     252         [ #  # ]:          0 :             delete[] newStr;
     253                 :            :         }
     254                 :          0 :         return aRet;
     255                 :            : }
     256                 :          0 : static void SAL_CALL NativeToAscii_numberMaker(sal_Int16 max, sal_Int16 prev, const sal_Unicode *str,
     257                 :            :         sal_Int32& i, sal_Int32 nCount, sal_Unicode *dst, sal_Int32& count, Sequence< sal_Int32 >& offset, sal_Bool useOffset,
     258                 :            :         OUString& numberChar, OUString& multiplierChar)
     259                 :            : {
     260                 :          0 :         sal_Int16 curr = 0, num = 0, end = 0, shift = 0;
     261         [ #  # ]:          0 :         while (++i < nCount) {
     262         [ #  # ]:          0 :             if ((curr = sal::static_int_cast<sal_Int16>( numberChar.indexOf(str[i]) )) >= 0) {
     263         [ #  # ]:          0 :                 if (num > 0)
     264                 :          0 :                     break;
     265                 :          0 :                 num = curr % 10;
     266         [ #  # ]:          0 :             } else if ((curr = sal::static_int_cast<sal_Int16>( multiplierChar.indexOf(str[i]) )) >= 0) {
     267                 :          0 :                 curr = MultiplierExponent_7_CJK[curr % ExponentCount_7_CJK];
     268 [ #  # ][ #  # ]:          0 :                 if (prev > curr && num == 0) num = 1; // One may be omitted in informal format
     269                 :          0 :                 shift = end = 0;
     270         [ #  # ]:          0 :                 if (curr >= max)
     271                 :          0 :                     max = curr;
     272         [ #  # ]:          0 :                 else if (curr > prev)
     273                 :          0 :                     shift = max - curr;
     274                 :            :                 else
     275                 :          0 :                     end = curr;
     276         [ #  # ]:          0 :                 while (end++ < prev) {
     277         [ #  # ]:          0 :                     dst[count] = NUMBER_ZERO + (end == prev ? num : 0);
     278         [ #  # ]:          0 :                     if (useOffset)
     279                 :          0 :                         offset[count] = i;
     280                 :          0 :                     count++;
     281                 :            :                 }
     282         [ #  # ]:          0 :                 if (shift) {
     283                 :          0 :                     count -= max;
     284         [ #  # ]:          0 :                     for (sal_Int16 j = 0; j < shift; j++, count++) {
     285                 :          0 :                         dst[count] = dst[count + curr];
     286         [ #  # ]:          0 :                         if (useOffset)
     287                 :          0 :                             offset[count] = offset[count + curr];
     288                 :            :                     }
     289                 :          0 :                     max = curr;
     290                 :            :                 }
     291                 :            :                 NativeToAscii_numberMaker(max, curr, str, i, nCount, dst,
     292                 :          0 :                         count, offset, useOffset, numberChar, multiplierChar);
     293                 :          0 :                 return;
     294                 :            :             } else
     295                 :          0 :                 break;
     296                 :            :         }
     297         [ #  # ]:          0 :         while (end++ < prev) {
     298         [ #  # ]:          0 :             dst[count] = NUMBER_ZERO + (end == prev ? num : 0);
     299         [ #  # ]:          0 :             if (useOffset)
     300                 :          0 :                 offset[count] = i - 1;
     301                 :          0 :             count++;
     302                 :            :         }
     303                 :            : }
     304                 :            : 
     305                 :          0 : static OUString SAL_CALL NativeToAscii(const OUString& inStr,
     306                 :            :         sal_Int32 startPos, sal_Int32 nCount, Sequence< sal_Int32 >& offset, sal_Bool useOffset ) throw(RuntimeException)
     307                 :            : {
     308                 :          0 :         OUString aRet;
     309                 :            : 
     310                 :          0 :         sal_Int32 strLen = inStr.getLength() - startPos;
     311                 :            : 
     312         [ #  # ]:          0 :         if (nCount > strLen)
     313                 :          0 :             nCount = strLen;
     314                 :            : 
     315         [ #  # ]:          0 :         if (nCount > 0) {
     316                 :          0 :             const sal_Unicode *str = inStr.getStr() + startPos;
     317         [ #  # ]:          0 :             sal_Unicode *newStr = new sal_Unicode[nCount * MultiplierExponent_7_CJK[0] + 2];
     318         [ #  # ]:          0 :             if (useOffset)
     319         [ #  # ]:          0 :                 offset.realloc( nCount * MultiplierExponent_7_CJK[0] + 1 );
     320                 :          0 :             sal_Int32 count = 0, index;
     321                 :            :             sal_Int32 i;
     322                 :            : 
     323                 :          0 :             OUString numberChar, multiplierChar, decimalChar, minusChar, separatorChar;
     324                 :          0 :             numberChar = OUString((sal_Unicode*)NumberChar, 10*NumberChar_Count);
     325                 :          0 :             multiplierChar = OUString((sal_Unicode*) MultiplierChar_7_CJK, ExponentCount_7_CJK*Multiplier_Count);
     326                 :          0 :             decimalChar = OUString(DecimalChar, NumberChar_Count);
     327                 :          0 :             minusChar = OUString(MinusChar, NumberChar_Count);
     328                 :          0 :             separatorChar = OUString(SeparatorChar, NumberChar_Count);
     329                 :            : 
     330         [ #  # ]:          0 :             for ( i = 0; i < nCount; i++) {
     331         [ #  # ]:          0 :                 if ((index = multiplierChar.indexOf(str[i])) >= 0) {
     332 [ #  # ][ #  # ]:          0 :                     if (count == 0 || !isNumber(newStr[count-1])) { // add 1 in front of multiplier
                 [ #  # ]
     333                 :          0 :                         newStr[count] = NUMBER_ONE;
     334         [ #  # ]:          0 :                         if (useOffset)
     335         [ #  # ]:          0 :                             offset[count] = i;
     336                 :          0 :                         count++;
     337                 :            :                     }
     338                 :          0 :                     index = MultiplierExponent_7_CJK[index % ExponentCount_7_CJK];
     339                 :            :                     NativeToAscii_numberMaker(
     340                 :          0 :                                 sal::static_int_cast<sal_Int16>( index ), sal::static_int_cast<sal_Int16>( index ),
     341                 :            :                                 str, i, nCount, newStr, count, offset, useOffset,
     342         [ #  # ]:          0 :                                 numberChar, multiplierChar);
     343                 :            :                 } else {
     344         [ #  # ]:          0 :                     if ((index = numberChar.indexOf(str[i])) >= 0)
     345                 :          0 :                         newStr[count] = sal::static_int_cast<sal_Unicode>( (index % 10) + NUMBER_ZERO );
     346 [ #  # ][ #  #  :          0 :                     else if ((index = separatorChar.indexOf(str[i])) >= 0 &&
             #  #  #  # ]
                 [ #  # ]
     347                 :          0 :                             (i < nCount-1 && (numberChar.indexOf(str[i+1]) >= 0 ||
     348                 :          0 :                                             multiplierChar.indexOf(str[i+1]) >= 0)))
     349                 :          0 :                         newStr[count] = SeparatorChar[NumberChar_HalfWidth];
     350 [ #  # ][ #  #  :          0 :                     else if ((index = decimalChar.indexOf(str[i])) >= 0 &&
             #  #  #  # ]
                 [ #  # ]
     351                 :          0 :                             (i < nCount-1 && (numberChar.indexOf(str[i+1]) >= 0 ||
     352                 :          0 :                                             multiplierChar.indexOf(str[i+1]) >= 0)))
     353                 :            :                         // Only when decimal point is followed by numbers,
     354                 :            :                         // it will be convert to ASCII decimal point
     355                 :          0 :                         newStr[count] = DecimalChar[NumberChar_HalfWidth];
     356 [ #  # ][ #  #  :          0 :                     else if ((index = minusChar.indexOf(str[i])) >= 0 &&
             #  #  #  # ]
                 [ #  # ]
     357                 :          0 :                             (i < nCount-1 && (numberChar.indexOf(str[i+1]) >= 0 ||
     358                 :          0 :                                             multiplierChar.indexOf(str[i+1]) >= 0)))
     359                 :            :                         // Only when minus is followed by numbers,
     360                 :            :                         // it will be convert to ASCII minus sign
     361                 :          0 :                         newStr[count] = MinusChar[NumberChar_HalfWidth];
     362                 :            :                     else
     363                 :          0 :                         newStr[count] = str[i];
     364         [ #  # ]:          0 :                     if (useOffset)
     365         [ #  # ]:          0 :                         offset[count] = i;
     366                 :          0 :                     count++;
     367                 :            :                 }
     368                 :            :             }
     369                 :            : 
     370         [ #  # ]:          0 :             if (useOffset) {
     371         [ #  # ]:          0 :                 offset.realloc(count);
     372         [ #  # ]:          0 :                 for (i = 0; i < count; i++)
     373         [ #  # ]:          0 :                     offset[i] += startPos;
     374                 :            :             }
     375                 :          0 :             aRet = OUString(newStr, count);
     376         [ #  # ]:          0 :             delete[] newStr;
     377                 :            :         }
     378                 :          0 :         return aRet;
     379                 :            : }
     380                 :            : 
     381                 :            : static Number natnum4[4] = {
     382                 :            :         { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh], 0,
     383                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     384                 :            :         { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], 0,
     385                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     386                 :            :         { NumberChar_Modern_ja, MultiplierChar_7_CJK[Multiplier_Modern_ja], NUMBER_OMIT_ZERO_ONE_67,
     387                 :            :                 ExponentCount_7_CJK, MultiplierExponent_7_CJK },
     388                 :            :         { NumberChar_Lower_ko, MultiplierChar_6_CJK[Multiplier_Lower_ko], NUMBER_OMIT_ZERO,
     389                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     390                 :            : };
     391                 :            : 
     392                 :            : static Number natnum5[4] = {
     393                 :            :         { NumberChar_Upper_zh, MultiplierChar_6_CJK[Multiplier_Upper_zh], 0,
     394                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     395                 :            :         { NumberChar_Upper_zh_TW, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], 0,
     396                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     397                 :            :         { NumberChar_Traditional_ja, MultiplierChar_7_CJK[Multiplier_Traditional_ja], NUMBER_OMIT_ZERO_ONE_67,
     398                 :            :                 ExponentCount_7_CJK, MultiplierExponent_7_CJK },
     399                 :            :         { NumberChar_Upper_ko, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], NUMBER_OMIT_ZERO,
     400                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     401                 :            : };
     402                 :            : 
     403                 :            : static Number natnum6[4] = {
     404                 :            :         { NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Lower_zh], 0,
     405                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     406                 :            :         { NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], 0,
     407                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     408                 :            :         { NumberChar_FullWidth, MultiplierChar_7_CJK[Multiplier_Modern_ja], NUMBER_OMIT_ZERO_ONE_67,
     409                 :            :                 ExponentCount_7_CJK, MultiplierExponent_7_CJK },
     410                 :            :         { NumberChar_FullWidth, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ZERO,
     411                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     412                 :            : };
     413                 :            : 
     414                 :            : static Number natnum7[4] = {
     415                 :            :         { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh], NUMBER_OMIT_ALL,
     416                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     417                 :            :         { NumberChar_Lower_zh, MultiplierChar_6_CJK[Multiplier_Lower_zh_TW], NUMBER_OMIT_ALL,
     418                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     419                 :            :         { NumberChar_Modern_ja, MultiplierChar_2_CJK[Multiplier_Modern_ja], NUMBER_OMIT_ZERO_ONE,
     420                 :            :                 ExponentCount_2_CJK, MultiplierExponent_2_CJK },
     421                 :            :         { NumberChar_Lower_ko, MultiplierChar_6_CJK[Multiplier_Lower_ko], NUMBER_OMIT_ALL,
     422                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     423                 :            : };
     424                 :            : 
     425                 :            : static Number natnum8[4] = {
     426                 :            :         { NumberChar_Upper_zh, MultiplierChar_6_CJK[Multiplier_Upper_zh], NUMBER_OMIT_ALL,
     427                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     428                 :            :         { NumberChar_Upper_zh_TW, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], NUMBER_OMIT_ALL,
     429                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     430                 :            :         { NumberChar_Traditional_ja, MultiplierChar_2_CJK[Multiplier_Traditional_ja], NUMBER_OMIT_ZERO_ONE,
     431                 :            :                 ExponentCount_2_CJK, MultiplierExponent_2_CJK },
     432                 :            :         { NumberChar_Upper_ko, MultiplierChar_6_CJK[Multiplier_Upper_zh_TW], NUMBER_OMIT_ALL,
     433                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK },
     434                 :            : };
     435                 :            : 
     436                 :            : static Number natnum10 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ZERO,
     437                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK };
     438                 :            : static Number natnum11 = { NumberChar_Hangul_ko, MultiplierChar_6_CJK[Multiplier_Hangul_ko], NUMBER_OMIT_ALL,
     439                 :            :                 ExponentCount_6_CJK, MultiplierExponent_6_CJK };
     440                 :            : 
     441                 :            : //! ATTENTION: Do not change order of elements!
     442                 :            : //! Append new languages to the end of the list!
     443                 :            : static const sal_Char *natnum1Locales[] = {
     444                 :            :     "zh_CN",
     445                 :            :     "zh_TW",
     446                 :            :     "ja",
     447                 :            :     "ko",
     448                 :            :     "he",
     449                 :            :     "ar",
     450                 :            :     "th",
     451                 :            :     "hi",
     452                 :            :     "or",
     453                 :            :     "mr",
     454                 :            :     "bn",
     455                 :            :     "pa",
     456                 :            :     "gu",
     457                 :            :     "ta",
     458                 :            :     "te",
     459                 :            :     "kn",
     460                 :            :     "ml",
     461                 :            :     "lo",
     462                 :            :     "bo",
     463                 :            :     "my",
     464                 :            :     "km",
     465                 :            :     "mn",
     466                 :            :     "ne",
     467                 :            :     "dz",
     468                 :            :     "fa"
     469                 :            : };
     470                 :            : static sal_Int16 nbOfLocale = SAL_N_ELEMENTS(natnum1Locales);
     471                 :            : 
     472                 :            : //! ATTENTION: Do not change order of elements!
     473                 :            : //! Number and order must match elements of natnum1Locales!
     474                 :            : static sal_Int16 natnum1[] = {
     475                 :            :     NumberChar_Lower_zh,
     476                 :            :     NumberChar_Lower_zh,
     477                 :            :     NumberChar_Modern_ja,
     478                 :            :     NumberChar_Lower_ko,
     479                 :            :     NumberChar_he,
     480                 :            :     NumberChar_Indic_ar,
     481                 :            :     NumberChar_th,
     482                 :            :     NumberChar_hi,
     483                 :            :     NumberChar_or,
     484                 :            :     NumberChar_mr,
     485                 :            :     NumberChar_bn,
     486                 :            :     NumberChar_pa,
     487                 :            :     NumberChar_gu,
     488                 :            :     NumberChar_ta,
     489                 :            :     NumberChar_te,
     490                 :            :     NumberChar_kn,
     491                 :            :     NumberChar_ml,
     492                 :            :     NumberChar_lo,
     493                 :            :     NumberChar_bo,
     494                 :            :     NumberChar_my,
     495                 :            :     NumberChar_km,
     496                 :            :     NumberChar_mn,
     497                 :            :     NumberChar_ne,
     498                 :            :     NumberChar_dz,
     499                 :            :     NumberChar_EastIndic_ar
     500                 :            : };
     501                 :            : static sal_Int16 sizeof_natnum1 = SAL_N_ELEMENTS(natnum1);
     502                 :            : 
     503                 :            : //! ATTENTION: Do not change order of elements!
     504                 :            : //! Order must match first elements of natnum1Locales!
     505                 :            : static sal_Int16 natnum2[] = {
     506                 :            :     NumberChar_Upper_zh,
     507                 :            :     NumberChar_Upper_zh_TW,
     508                 :            :     NumberChar_Traditional_ja,
     509                 :            :     NumberChar_Upper_ko,
     510                 :            :     NumberChar_he
     511                 :            : };
     512                 :            : static sal_Int16 sizeof_natnum2 = SAL_N_ELEMENTS(natnum2);
     513                 :            : 
     514                 :            : #define isLang(lang) rLocale.Language.equalsAsciiL(lang, 2)
     515                 :            : 
     516                 :          0 : static sal_Int16 SAL_CALL getLanguageNumber( const Locale& rLocale)
     517                 :            : {
     518                 :            :     // return zh_TW for TW, HK and MO, return zh_CN for other zh locales.
     519 [ #  # ][ #  # ]:          0 :     if (isLang("zh")) return MsLangId::isTraditionalChinese(rLocale) ? 1 : 0;
     520                 :            : 
     521         [ #  # ]:          0 :     for (sal_Int16 i = 2; i < nbOfLocale; i++)
     522         [ #  # ]:          0 :         if (isLang(natnum1Locales[i]))
     523                 :          0 :             return i;
     524                 :            : 
     525                 :          0 :     return -1;
     526                 :            : }
     527                 :            : 
     528                 :          0 : OUString SAL_CALL NativeNumberSupplier::getNativeNumberString(const OUString& aNumberString, const Locale& rLocale,
     529                 :            :                 sal_Int16 nNativeNumberMode, Sequence< sal_Int32 >& offset) throw (RuntimeException)
     530                 :            : {
     531                 :          0 :         Number *number = 0;
     532                 :          0 :         sal_Int16 num = -1;
     533                 :            : 
     534         [ #  # ]:          0 :         if (isValidNatNum(rLocale, nNativeNumberMode)) {
     535                 :          0 :             sal_Int16 langnum = getLanguageNumber(rLocale);
     536   [ #  #  #  #  :          0 :             switch (nNativeNumberMode) {
          #  #  #  #  #  
             #  #  #  # ]
     537                 :            :                 case NativeNumberMode::NATNUM0: // Ascii
     538                 :          0 :                     return NativeToAscii(aNumberString,  0, aNumberString.getLength(), offset, useOffset);
     539                 :            :                 case NativeNumberMode::NATNUM1: // Char, Lower
     540                 :          0 :                     num = natnum1[langnum];
     541                 :          0 :                 break;
     542                 :            :                 case NativeNumberMode::NATNUM2: // Char, Upper
     543                 :          0 :                     num = natnum2[langnum];
     544                 :          0 :                 break;
     545                 :            :                 case NativeNumberMode::NATNUM3: // Char, FullWidth
     546                 :          0 :                     num = NumberChar_FullWidth;
     547                 :          0 :                 break;
     548                 :            :                 case NativeNumberMode::NATNUM4: // Text, Lower, Long
     549                 :          0 :                     number = &natnum4[langnum];
     550                 :          0 :                 break;
     551                 :            :                 case NativeNumberMode::NATNUM5: // Text, Upper, Long
     552                 :          0 :                     number = &natnum5[langnum];
     553                 :          0 :                 break;
     554                 :            :                 case NativeNumberMode::NATNUM6: // Text, FullWidth
     555                 :          0 :                     number = &natnum6[langnum];
     556                 :          0 :                 break;
     557                 :            :                 case NativeNumberMode::NATNUM7: // Text. Lower, Short
     558                 :          0 :                     number = &natnum7[langnum];
     559                 :          0 :                 break;
     560                 :            :                 case NativeNumberMode::NATNUM8: // Text, Upper, Short
     561                 :          0 :                     number = &natnum8[langnum];
     562                 :          0 :                 break;
     563                 :            :                 case NativeNumberMode::NATNUM9: // Char, Hangul
     564                 :          0 :                     num = NumberChar_Hangul_ko;
     565                 :          0 :                 break;
     566                 :            :                 case NativeNumberMode::NATNUM10:        // Text, Hangul, Long
     567                 :          0 :                     number = &natnum10;
     568                 :          0 :                 break;
     569                 :            :                 case NativeNumberMode::NATNUM11:        // Text, Hangul, Short
     570                 :          0 :                     number = &natnum11;
     571                 :          0 :                 break;
     572                 :            :                 default:
     573                 :          0 :                 break;
     574                 :            :             }
     575                 :            :         }
     576                 :            : 
     577 [ #  # ][ #  # ]:          0 :         if (number || num >= 0) {
     578   [ #  #  #  #  :          0 :             if (!aLocale.Language.equals(rLocale.Language) ||
           #  # ][ #  # ]
     579                 :          0 :                     !aLocale.Country.equals(rLocale.Country) ||
     580                 :          0 :                     !aLocale.Variant.equals(rLocale.Variant)) {
     581 [ #  # ][ #  # ]:          0 :                 LocaleDataItem item = LocaleData().getLocaleItem( rLocale );
                 [ #  # ]
     582                 :          0 :                 aLocale = rLocale;
     583                 :          0 :                 DecimalChar[NumberChar_HalfWidth]=item.decimalSeparator.toChar();
     584 [ #  # ][ #  # ]:          0 :                 if (DecimalChar[NumberChar_HalfWidth] > 0x7E || DecimalChar[NumberChar_HalfWidth] < 0x21)
     585                 :          0 :                     DecimalChar[NumberChar_FullWidth]=0xFF0E;
     586                 :            :                 else
     587                 :          0 :                     DecimalChar[NumberChar_FullWidth]=DecimalChar[NumberChar_HalfWidth]+0xFEE0;
     588                 :          0 :                 SeparatorChar[NumberChar_HalfWidth]=item.thousandSeparator.toChar();
     589 [ #  # ][ #  # ]:          0 :                 if (SeparatorChar[NumberChar_HalfWidth] > 0x7E || SeparatorChar[NumberChar_HalfWidth] < 0x21)
     590                 :          0 :                     SeparatorChar[NumberChar_FullWidth]=0xFF0C;
     591                 :            :                 else
     592                 :          0 :                     SeparatorChar[NumberChar_FullWidth]=SeparatorChar[NumberChar_HalfWidth]+0xFEE0;
     593                 :            :             }
     594         [ #  # ]:          0 :             if (number)
     595                 :          0 :                 return AsciiToNative( aNumberString, 0, aNumberString.getLength(), offset, useOffset, number );
     596         [ #  # ]:          0 :             else if (num == NumberChar_he)
     597                 :            :                 return getHebrewNativeNumberString(aNumberString,
     598                 :          0 :                                 nNativeNumberMode == NativeNumberMode::NATNUM2);
     599                 :            :             else
     600                 :          0 :                 return AsciiToNativeChar(aNumberString, 0, aNumberString.getLength(), offset, useOffset, num);
     601                 :            :         }
     602                 :            :         else
     603                 :          0 :             return aNumberString;
     604                 :            : }
     605                 :            : 
     606                 :          0 : OUString SAL_CALL NativeNumberSupplier::getNativeNumberString(const OUString& aNumberString, const Locale& rLocale,
     607                 :            :                 sal_Int16 nNativeNumberMode) throw (RuntimeException)
     608                 :            : {
     609         [ #  # ]:          0 :     Sequence< sal_Int32 > offset;
     610 [ #  # ][ #  # ]:          0 :     return getNativeNumberString(aNumberString, rLocale, nNativeNumberMode, offset);
     611                 :            : }
     612                 :            : 
     613                 :          0 : sal_Unicode SAL_CALL NativeNumberSupplier::getNativeNumberChar( const sal_Unicode inChar, const Locale& rLocale, sal_Int16 nNativeNumberMode ) throw(com::sun::star::uno::RuntimeException)
     614                 :            : {
     615         [ #  # ]:          0 :         if (nNativeNumberMode == NativeNumberMode::NATNUM0) { // Ascii
     616         [ #  # ]:          0 :             for (sal_Int16 i = 0; i < NumberChar_Count; i++)
     617         [ #  # ]:          0 :                 for (sal_Int16 j = 0; j < 10; j++)
     618         [ #  # ]:          0 :                     if (inChar == NumberChar[i][j])
     619                 :          0 :                         return j;
     620                 :          0 :             return inChar;
     621                 :            :         }
     622 [ #  # ][ #  # ]:          0 :         else if (isNumber(inChar) && isValidNatNum(rLocale, nNativeNumberMode)) {
         [ #  # ][ #  # ]
     623                 :          0 :             sal_Int16 langnum = getLanguageNumber(rLocale);
     624   [ #  #  #  #  :          0 :             switch (nNativeNumberMode) {
                      # ]
     625                 :            :                 case NativeNumberMode::NATNUM1: // Char, Lower
     626                 :            :                 case NativeNumberMode::NATNUM4: // Text, Lower, Long
     627                 :            :                 case NativeNumberMode::NATNUM7: // Text. Lower, Short
     628                 :          0 :                     return NumberChar[natnum1[langnum]][inChar - NUMBER_ZERO];
     629                 :            :                 case NativeNumberMode::NATNUM2: // Char, Upper
     630                 :            :                 case NativeNumberMode::NATNUM5: // Text, Upper, Long
     631                 :            :                 case NativeNumberMode::NATNUM8: // Text, Upper, Short
     632                 :          0 :                     return NumberChar[natnum2[langnum]][inChar - NUMBER_ZERO];
     633                 :            :                 case NativeNumberMode::NATNUM3: // Char, FullWidth
     634                 :            :                 case NativeNumberMode::NATNUM6: // Text, FullWidth
     635                 :          0 :                     return NumberChar[NumberChar_FullWidth][inChar - NUMBER_ZERO];
     636                 :            :                 case NativeNumberMode::NATNUM9: // Char, Hangul
     637                 :            :                 case NativeNumberMode::NATNUM10:        // Text, Hangul, Long
     638                 :            :                 case NativeNumberMode::NATNUM11:        // Text, Hangul, Short
     639                 :          0 :                     return NumberChar[NumberChar_Hangul_ko][inChar - NUMBER_ZERO];
     640                 :            :                 default:
     641                 :          0 :                 break;
     642                 :            :             }
     643                 :            :         }
     644                 :          0 :         return inChar;
     645                 :            : }
     646                 :            : 
     647                 :          0 : sal_Bool SAL_CALL NativeNumberSupplier::isValidNatNum( const Locale& rLocale, sal_Int16 nNativeNumberMode ) throw (RuntimeException)
     648                 :            : {
     649                 :          0 :         sal_Int16 langnum = getLanguageNumber(rLocale);
     650                 :            : 
     651   [ #  #  #  #  :          0 :         switch (nNativeNumberMode) {
                   #  # ]
     652                 :            :             case NativeNumberMode::NATNUM0:     // Ascii
     653                 :            :             case NativeNumberMode::NATNUM3:     // Char, FullWidth
     654                 :          0 :                 return sal_True;
     655                 :            :             case NativeNumberMode::NATNUM1:     // Char, Lower
     656                 :          0 :                 return (langnum >= 0);
     657                 :            :             case NativeNumberMode::NATNUM2:     // Char, Upper
     658         [ #  # ]:          0 :                 if (langnum == 4) // Hebrew numbering
     659                 :          0 :                     return sal_True;
     660                 :            :             case NativeNumberMode::NATNUM4:     // Text, Lower, Long
     661                 :            :             case NativeNumberMode::NATNUM5:     // Text, Upper, Long
     662                 :            :             case NativeNumberMode::NATNUM6:     // Text, FullWidth
     663                 :            :             case NativeNumberMode::NATNUM7:     // Text. Lower, Short
     664                 :            :             case NativeNumberMode::NATNUM8:     // Text, Upper, Short
     665 [ #  # ][ #  # ]:          0 :                 return (langnum >= 0 && langnum < 4); // CJK numbering
     666                 :            :             case NativeNumberMode::NATNUM9:     // Char, Hangul
     667                 :            :             case NativeNumberMode::NATNUM10:    // Text, Hangul, Long
     668                 :            :             case NativeNumberMode::NATNUM11:    // Text, Hangul, Short
     669                 :          0 :                 return (langnum == 3); // Korean numbering
     670                 :            :         }
     671                 :          0 :         return sal_False;
     672                 :            : }
     673                 :            : 
     674                 :          0 : NativeNumberXmlAttributes SAL_CALL NativeNumberSupplier::convertToXmlAttributes( const Locale& rLocale, sal_Int16 nNativeNumberMode ) throw (RuntimeException)
     675                 :            : {
     676                 :            :         static const sal_Int16 attShort         = 0;
     677                 :            :         static const sal_Int16 attMedium        = 1;
     678                 :            :         static const sal_Int16 attLong          = 2;
     679                 :            :         static const sal_Char *attType[] = { "short", "medium", "long" };
     680                 :            : 
     681                 :          0 :         sal_Int16 number = NumberChar_HalfWidth, type = attShort;
     682                 :            : 
     683         [ #  # ]:          0 :         if (isValidNatNum(rLocale, nNativeNumberMode)) {
     684                 :          0 :             sal_Int16 langnum = getLanguageNumber(rLocale);
     685   [ #  #  #  #  :          0 :             switch (nNativeNumberMode) {
          #  #  #  #  #  
             #  #  #  # ]
     686                 :            :                 case NativeNumberMode::NATNUM0: // Ascii
     687                 :          0 :                     number = NumberChar_HalfWidth;
     688                 :          0 :                     type = attShort;
     689                 :          0 :                 break;
     690                 :            :                 case NativeNumberMode::NATNUM1: // Char, Lower
     691                 :          0 :                     number = natnum1[langnum];
     692                 :          0 :                     type = attShort;
     693                 :          0 :                 break;
     694                 :            :                 case NativeNumberMode::NATNUM2: // Char, Upper
     695                 :          0 :                     number = natnum2[langnum];
     696         [ #  # ]:          0 :                     type = number == NumberChar_he ? attMedium : attShort;
     697                 :          0 :                 break;
     698                 :            :                 case NativeNumberMode::NATNUM3: // Char, FullWidth
     699                 :          0 :                     number = NumberChar_FullWidth;
     700                 :          0 :                     type = attShort;
     701                 :          0 :                 break;
     702                 :            :                 case NativeNumberMode::NATNUM4: // Text, Lower, Long
     703                 :          0 :                     number = natnum1[langnum];
     704                 :          0 :                     type = attLong;
     705                 :          0 :                 break;
     706                 :            :                 case NativeNumberMode::NATNUM5: // Text, Upper, Long
     707                 :          0 :                     number = natnum2[langnum];
     708                 :          0 :                     type = attLong;
     709                 :          0 :                 break;
     710                 :            :                 case NativeNumberMode::NATNUM6: // Text, FullWidth
     711                 :          0 :                     number = NumberChar_FullWidth;
     712                 :          0 :                     type = attLong;
     713                 :          0 :                 break;
     714                 :            :                 case NativeNumberMode::NATNUM7: // Text. Lower, Short
     715                 :          0 :                     number = natnum1[langnum];
     716                 :          0 :                     type = attMedium;
     717                 :          0 :                 break;
     718                 :            :                 case NativeNumberMode::NATNUM8: // Text, Upper, Short
     719                 :          0 :                     number = natnum2[langnum];
     720                 :          0 :                     type = attMedium;
     721                 :          0 :                 break;
     722                 :            :                 case NativeNumberMode::NATNUM9: // Char, Hangul
     723                 :          0 :                     number = NumberChar_Hangul_ko;
     724                 :          0 :                     type = attShort;
     725                 :          0 :                 break;
     726                 :            :                 case NativeNumberMode::NATNUM10:        // Text, Hangul, Long
     727                 :          0 :                     number = NumberChar_Hangul_ko;
     728                 :          0 :                     type = attLong;
     729                 :          0 :                 break;
     730                 :            :                 case NativeNumberMode::NATNUM11:        // Text, Hangul, Short
     731                 :          0 :                     number = NumberChar_Hangul_ko;
     732                 :          0 :                     type = attMedium;
     733                 :          0 :                 break;
     734                 :            :                 default:
     735                 :          0 :                 break;
     736                 :            :             }
     737                 :            :         }
     738                 :          0 :         return NativeNumberXmlAttributes(rLocale, OUString(&NumberChar[number][1], 1),
     739                 :          0 :                                             OUString::createFromAscii(attType[type]));
     740                 :            : }
     741                 :            : 
     742                 :          0 : static sal_Bool natNumIn(sal_Int16 num, sal_Int16 natnum[], sal_Int16 len)
     743                 :            : {
     744         [ #  # ]:          0 :         for (sal_Int16 i = 0; i < len; i++)
     745         [ #  # ]:          0 :             if (natnum[i] == num)
     746                 :          0 :                 return sal_True;
     747                 :          0 :         return sal_False;
     748                 :            : }
     749                 :            : 
     750                 :          0 : sal_Int16 SAL_CALL NativeNumberSupplier::convertFromXmlAttributes( const NativeNumberXmlAttributes& aAttr ) throw (RuntimeException)
     751                 :            : {
     752                 :            :         sal_Unicode numberChar[NumberChar_Count];
     753         [ #  # ]:          0 :         for (sal_Int16 i = 0; i < NumberChar_Count; i++)
     754                 :          0 :             numberChar[i] = NumberChar[i][1];
     755                 :          0 :         OUString number(numberChar, NumberChar_Count);
     756                 :            : 
     757                 :          0 :         sal_Int16 num = sal::static_int_cast<sal_Int16>( number.indexOf(aAttr.Format) );
     758                 :            : 
     759         [ #  # ]:          0 :         if ( aAttr.Style == "short" ) {
     760         [ #  # ]:          0 :             if (num == NumberChar_FullWidth)
     761                 :          0 :                 return NativeNumberMode::NATNUM3;
     762         [ #  # ]:          0 :             else if (num == NumberChar_Hangul_ko)
     763                 :          0 :                 return NativeNumberMode::NATNUM9;
     764         [ #  # ]:          0 :             else if (natNumIn(num, natnum1, sizeof_natnum1))
     765                 :          0 :                 return NativeNumberMode::NATNUM1;
     766         [ #  # ]:          0 :             else if (natNumIn(num, natnum2, sizeof_natnum2))
     767                 :          0 :                 return NativeNumberMode::NATNUM2;
     768         [ #  # ]:          0 :         } else if ( aAttr.Style == "medium" ) {
     769         [ #  # ]:          0 :             if (num == NumberChar_Hangul_ko)
     770                 :          0 :                 return NativeNumberMode::NATNUM11;
     771         [ #  # ]:          0 :             else if (num == NumberChar_he)
     772                 :          0 :                 return NativeNumberMode::NATNUM2;
     773         [ #  # ]:          0 :             else if (natNumIn(num, natnum1, sizeof_natnum1))
     774                 :          0 :                 return NativeNumberMode::NATNUM7;
     775         [ #  # ]:          0 :             else if (natNumIn(num, natnum2, sizeof_natnum2))
     776                 :          0 :                 return NativeNumberMode::NATNUM8;
     777         [ #  # ]:          0 :         } else if ( aAttr.Style == "long" ) {
     778         [ #  # ]:          0 :             if (num == NumberChar_FullWidth)
     779                 :          0 :                 return NativeNumberMode::NATNUM6;
     780         [ #  # ]:          0 :             else if (num == NumberChar_Hangul_ko)
     781                 :          0 :                 return NativeNumberMode::NATNUM10;
     782         [ #  # ]:          0 :             else if (natNumIn(num, natnum1, sizeof_natnum1))
     783                 :          0 :                 return NativeNumberMode::NATNUM4;
     784         [ #  # ]:          0 :             else if (natNumIn(num, natnum2, sizeof_natnum2))
     785                 :          0 :                 return NativeNumberMode::NATNUM5;
     786                 :            :         } else {
     787         [ #  # ]:          0 :             throw RuntimeException();
     788                 :            :         }
     789                 :          0 :         return NativeNumberMode::NATNUM0;
     790                 :            : }
     791                 :            : 
     792                 :            : 
     793                 :            : // Following code generates Hebrew Number,
     794                 :            : // see numerical system in the Hebrew Numbering System in following link for details,
     795                 :            : // http://people.netscape.com/smontagu/writings/HebrewNumbers.html
     796                 :            : 
     797                 :            : struct HebrewNumberChar {
     798                 :            :     sal_Unicode code;
     799                 :            :     sal_Int16 value;
     800                 :            : } HebrewNumberCharArray[] = {
     801                 :            :     { 0x05ea, 400 },
     802                 :            :     { 0x05ea, 400 },
     803                 :            :     { 0x05e9, 300 },
     804                 :            :     { 0x05e8, 200 },
     805                 :            :     { 0x05e7, 100 },
     806                 :            :     { 0x05e6, 90 },
     807                 :            :     { 0x05e4, 80 },
     808                 :            :     { 0x05e2, 70 },
     809                 :            :     { 0x05e1, 60 },
     810                 :            :     { 0x05e0, 50 },
     811                 :            :     { 0x05de, 40 },
     812                 :            :     { 0x05dc, 30 },
     813                 :            :     { 0x05db, 20 },
     814                 :            :     { 0x05d9, 10 },
     815                 :            :     { 0x05d8, 9 },
     816                 :            :     { 0x05d7, 8 },
     817                 :            :     { 0x05d6, 7 },
     818                 :            :     { 0x05d5, 6 },
     819                 :            :     { 0x05d4, 5 },
     820                 :            :     { 0x05d3, 4 },
     821                 :            :     { 0x05d2, 3 },
     822                 :            :     { 0x05d1, 2 },
     823                 :            :     { 0x05d0, 1 }
     824                 :            : };
     825                 :            : 
     826                 :            : static sal_Int16 nbOfHebrewNumberChar = sizeof(HebrewNumberCharArray)/sizeof(HebrewNumberChar);
     827                 :            : 
     828                 :            : static sal_Unicode thousand[] = {0x05d0, 0x05dc, 0x05e3, 0x0};
     829                 :            : static sal_Unicode thousands[] = {0x05d0, 0x05dc, 0x05e4, 0x05d9, 0x0};
     830                 :            : static sal_Unicode thousands_last[] = {0x05d0, 0x05dc, 0x05e4, 0x05d9, 0x05dd, 0x0};
     831                 :            : static sal_Unicode geresh = 0x05f3;
     832                 :            : static sal_Unicode gershayim = 0x05f4;
     833                 :            : 
     834                 :          0 : void makeHebrewNumber(sal_Int64 value, OUStringBuffer& output, sal_Bool isLast, sal_Bool useGeresh)
     835                 :            : {
     836                 :          0 :     sal_Int16 num = sal::static_int_cast<sal_Int16>(value % 1000);
     837                 :            : 
     838         [ #  # ]:          0 :     if (value > 1000) {
     839                 :          0 :         makeHebrewNumber(value / 1000, output, num != 0, useGeresh);
     840                 :          0 :         output.appendAscii(" ");
     841                 :            :     }
     842         [ #  # ]:          0 :     if (num == 0) {
     843 [ #  # ][ #  # ]:          0 :         output.append(value == 1000 ? thousand : isLast ? thousands_last : thousands);
     844                 :            :     } else {
     845                 :          0 :         sal_Int16 nbOfChar = 0;
     846 [ #  # ][ #  # ]:          0 :         for (sal_Int32 j = 0; num > 0 && j < nbOfHebrewNumberChar; j++) {
                 [ #  # ]
     847         [ #  # ]:          0 :             if (num - HebrewNumberCharArray[j].value >= 0) {
     848                 :          0 :                 nbOfChar++;
     849 [ #  # ][ #  # ]:          0 :                 if (num == 15 || num == 16) // substitution for 15 and 16
     850                 :          0 :                     j++;
     851                 :          0 :                 num = sal::static_int_cast<sal_Int16>( num - HebrewNumberCharArray[j].value );
     852                 :          0 :                 output.append(HebrewNumberCharArray[j].code);
     853                 :            :             }
     854                 :            :         }
     855         [ #  # ]:          0 :         if (useGeresh) {
     856         [ #  # ]:          0 :             if (nbOfChar > 1)   // a number is written as more than one character
     857                 :          0 :                 output.insert(output.getLength() - 1, gershayim);
     858         [ #  # ]:          0 :             else if (nbOfChar == 1) // a number is written as a single character
     859                 :          0 :                 output.append(geresh);
     860                 :            :         }
     861                 :            :     }
     862                 :          0 : }
     863                 :            : 
     864                 :          0 : OUString SAL_CALL getHebrewNativeNumberString(const OUString& aNumberString, sal_Bool useGeresh)
     865                 :            : {
     866                 :          0 :     sal_Int64 value = 0;
     867                 :          0 :     sal_Int32 i, count = 0, len = aNumberString.getLength();
     868                 :          0 :     const sal_Unicode *src = aNumberString.getStr();
     869                 :            : 
     870         [ #  # ]:          0 :     for (i = 0; i < len; i++) {
     871                 :          0 :         sal_Unicode ch = src[i];
     872 [ #  # ][ #  # ]:          0 :         if (isNumber(ch)) {
     873         [ #  # ]:          0 :             if (++count >= 20) // Number is too long, could not be handled.
     874                 :          0 :                 return aNumberString;
     875                 :          0 :             value = value * 10 + (ch - NUMBER_ZERO);
     876                 :            :         }
     877 [ #  # ][ #  # ]:          0 :         else if (isSeparator(ch) && count > 0) continue;
     878 [ #  # ][ #  # ]:          0 :         else if (isMinus(ch) && count == 0) continue;
     879                 :          0 :         else break;
     880                 :            :     }
     881                 :            : 
     882         [ #  # ]:          0 :     if (value > 0) {
     883                 :          0 :         OUStringBuffer output(count*2 + 2 + len - i);
     884                 :            : 
     885         [ #  # ]:          0 :         makeHebrewNumber(value, output, sal_True, useGeresh);
     886                 :            : 
     887         [ #  # ]:          0 :         if (i < len)
     888         [ #  # ]:          0 :             output.append(aNumberString.copy(i));
     889                 :            : 
     890         [ #  # ]:          0 :         return output.makeStringAndClear();
     891                 :            :     }
     892                 :            :     else
     893                 :          0 :         return aNumberString;
     894                 :            : }
     895                 :            : 
     896                 :            : static const sal_Char* implementationName = "com.sun.star.i18n.NativeNumberSupplier";
     897                 :            : 
     898                 :          0 : OUString SAL_CALL NativeNumberSupplier::getImplementationName() throw( RuntimeException )
     899                 :            : {
     900                 :          0 :     return OUString::createFromAscii( implementationName );
     901                 :            : }
     902                 :            : 
     903                 :            : sal_Bool SAL_CALL
     904                 :          0 : NativeNumberSupplier::supportsService(const OUString& rServiceName) throw( RuntimeException )
     905                 :            : {
     906                 :          0 :     return rServiceName.compareToAscii(implementationName) == 0;
     907                 :            : }
     908                 :            : 
     909                 :            : Sequence< OUString > SAL_CALL
     910                 :          0 : NativeNumberSupplier::getSupportedServiceNames() throw( RuntimeException )
     911                 :            : {
     912                 :          0 :     Sequence< OUString > aRet(1);
     913         [ #  # ]:          0 :     aRet[0] = OUString::createFromAscii( implementationName );
     914                 :          0 :     return aRet;
     915                 :            : }
     916                 :            : 
     917                 :            : } } } }
     918                 :            : 
     919                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10