1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_i18npool.hxx"
30 
31 #include <transliteration_Numeric.hxx>
32 #include <nativenumbersupplier.hxx>
33 #include <defaultnumberingprovider.hxx>
34 
35 using namespace com::sun::star::uno;
36 using namespace rtl;
37 
38 namespace com { namespace sun { namespace star { namespace i18n {
39 
40 sal_Int16 SAL_CALL transliteration_Numeric::getType() throw(RuntimeException)
41 {
42         return TransliterationType::NUMERIC;
43 }
44 
45 OUString SAL_CALL
46 transliteration_Numeric::folding( const OUString& /*inStr*/, sal_Int32 /*startPos*/, sal_Int32 /*nCount*/, Sequence< sal_Int32 >& /*offset*/ )
47         throw(RuntimeException)
48 {
49         throw (new RuntimeException());
50 }
51 
52 sal_Bool SAL_CALL
53 transliteration_Numeric::equals( const OUString& /*str1*/, sal_Int32 /*pos1*/, sal_Int32 /*nCount1*/, sal_Int32& /*nMatch1*/, const OUString& /*str2*/, sal_Int32 /*pos2*/, sal_Int32 /*nCount2*/, sal_Int32& /*nMatch2*/ )
54         throw(RuntimeException)
55 {
56         throw (new RuntimeException());
57 }
58 
59 Sequence< OUString > SAL_CALL
60 transliteration_Numeric::transliterateRange( const OUString& /*str1*/, const OUString& /*str2*/ )
61         throw(RuntimeException)
62 {
63         throw (new RuntimeException());
64 }
65 
66 
67 #define isNumber(c) ((c) >= 0x30 && (c) <= 0x39)
68 #define NUMBER_ZERO 0x30
69 
70 OUString SAL_CALL
71 transliteration_Numeric::transliterateBullet( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
72         Sequence< sal_Int32 >& offset ) throw(RuntimeException)
73 {
74         sal_Int32 number = -1, j = 0, endPos = startPos + nCount;
75 
76         if (endPos >  inStr.getLength())
77             endPos = inStr.getLength();
78 
79         rtl_uString* pStr = x_rtl_uString_new_WithLength( nCount, 1 );  // our x_rtl_ustring.h
80         sal_Unicode* out = pStr->buffer;
81 
82         if (useOffset)
83             offset.realloc(nCount);
84 
85         for (sal_Int32 i = startPos; i < endPos; i++) {
86             if (i < endPos && isNumber(inStr[i])) {
87                 if (number == -1) {
88                     startPos = i;
89                     number = (inStr[i] - NUMBER_ZERO);
90                 } else  {
91                     number = number * 10 + (inStr[i] - NUMBER_ZERO);
92                 }
93             } else {
94                 if (number == 0) {
95                     if (useOffset)
96                         offset[j] = startPos;
97                     out[j++] = NUMBER_ZERO;
98                 } if (number > tableSize && !recycleSymbol) {
99                     for (sal_Int32 k = startPos; k < i; k++) {
100                         if (useOffset)
101                             offset[j] = k;
102                         out[j++] = inStr[k];
103                     }
104                 } else if (number > 0) {
105                     if (useOffset)
106                         offset[j] = startPos;
107                     out[j++] = table[--number % tableSize];
108                 } else if (i < endPos) {
109                     if (useOffset)
110                         offset[j] = i;
111                     out[j++] = inStr[i];
112                 }
113                 number = -1;
114             }
115         }
116         out[j] = 0;
117 
118         if (useOffset)
119             offset.realloc(j);
120 
121         return OUString( pStr, SAL_NO_ACQUIRE );
122 }
123 
124 OUString SAL_CALL
125 transliteration_Numeric::transliterate( const OUString& inStr, sal_Int32 startPos, sal_Int32 nCount,
126         Sequence< sal_Int32 >& offset ) throw(RuntimeException)
127 {
128         if (tableSize)
129             return transliterateBullet( inStr, startPos, nCount, offset);
130         else
131             return NativeNumberSupplier(useOffset).getNativeNumberString( inStr.copy(startPos, nCount), aLocale, nNativeNumberMode, offset );
132 }
133 
134 sal_Unicode SAL_CALL
135 transliteration_Numeric::transliterateChar2Char( sal_Unicode inChar ) throw(RuntimeException, MultipleCharsOutputException)
136 {
137         if (tableSize) {
138             if (isNumber(inChar)) {
139                 sal_Int16 number = inChar - NUMBER_ZERO;
140                 if (number <= tableSize || recycleSymbol)
141                     return table[--number % tableSize];
142             }
143             return inChar;
144         }
145         else
146             return NativeNumberSupplier().getNativeNumberChar( inChar, aLocale, nNativeNumberMode );
147 }
148 
149 } } } }
150