xref: /trunk/main/i18npool/source/characterclassification/characterclassificationImpl.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_i18npool.hxx"
26 
27 #include <characterclassificationImpl.hxx>
28 #include <rtl/ustrbuf.hxx>
29 
30 using namespace com::sun::star::uno;
31 using namespace com::sun::star::lang;
32 using namespace rtl;
33 
34 namespace com { namespace sun { namespace star { namespace i18n {
35 
CharacterClassificationImpl(const Reference<lang::XMultiServiceFactory> & rxMSF)36 CharacterClassificationImpl::CharacterClassificationImpl(
37         const Reference < lang::XMultiServiceFactory >& rxMSF ) : xMSF( rxMSF )
38 {
39         if (createLocaleSpecificCharacterClassification(OUString::createFromAscii("Unicode"), Locale()))
40             xUCI = cachedItem->xCI;
41 }
42 
~CharacterClassificationImpl()43 CharacterClassificationImpl::~CharacterClassificationImpl() {
44         // Clear lookuptable
45         for (size_t l = 0; l < lookupTable.size(); l++)
46             delete lookupTable[l];
47         lookupTable.clear();
48 }
49 
50 
51 OUString SAL_CALL
toUpper(const OUString & Text,sal_Int32 nPos,sal_Int32 nCount,const Locale & rLocale)52 CharacterClassificationImpl::toUpper( const OUString& Text, sal_Int32 nPos,
53         sal_Int32 nCount, const Locale& rLocale )
54 {
55         return getLocaleSpecificCharacterClassification(rLocale)->toUpper(Text, nPos, nCount, rLocale);
56 }
57 
58 OUString SAL_CALL
toLower(const OUString & Text,sal_Int32 nPos,sal_Int32 nCount,const Locale & rLocale)59 CharacterClassificationImpl::toLower( const OUString& Text, sal_Int32 nPos,
60         sal_Int32 nCount, const Locale& rLocale )
61 {
62         return getLocaleSpecificCharacterClassification(rLocale)->toLower(Text, nPos, nCount, rLocale);
63 }
64 
65 OUString SAL_CALL
toTitle(const OUString & Text,sal_Int32 nPos,sal_Int32 nCount,const Locale & rLocale)66 CharacterClassificationImpl::toTitle( const OUString& Text, sal_Int32 nPos,
67         sal_Int32 nCount, const Locale& rLocale )
68 {
69         return getLocaleSpecificCharacterClassification(rLocale)->toTitle(Text, nPos, nCount, rLocale);
70 }
71 
72 sal_Int16 SAL_CALL
getType(const OUString & Text,sal_Int32 nPos)73 CharacterClassificationImpl::getType( const OUString& Text, sal_Int32 nPos )
74 {
75         if (xUCI.is())
76             return xUCI->getType(Text, nPos);
77         throw RuntimeException();
78 }
79 
80 sal_Int16 SAL_CALL
getCharacterDirection(const OUString & Text,sal_Int32 nPos)81 CharacterClassificationImpl::getCharacterDirection( const OUString& Text, sal_Int32 nPos )
82 {
83         if (xUCI.is())
84             return xUCI->getCharacterDirection(Text, nPos);
85         throw RuntimeException();
86 }
87 
88 sal_Int16 SAL_CALL
getScript(const OUString & Text,sal_Int32 nPos)89 CharacterClassificationImpl::getScript( const OUString& Text, sal_Int32 nPos )
90 {
91         if (xUCI.is())
92             return xUCI->getScript(Text, nPos);
93         throw RuntimeException();
94 }
95 
96 sal_Int32 SAL_CALL
getCharacterType(const OUString & Text,sal_Int32 nPos,const Locale & rLocale)97 CharacterClassificationImpl::getCharacterType( const OUString& Text, sal_Int32 nPos,
98         const Locale& rLocale )
99 {
100         return getLocaleSpecificCharacterClassification(rLocale)->getCharacterType(Text, nPos, rLocale);
101 }
102 
103 sal_Int32 SAL_CALL
getStringType(const OUString & Text,sal_Int32 nPos,sal_Int32 nCount,const Locale & rLocale)104 CharacterClassificationImpl::getStringType( const OUString& Text, sal_Int32 nPos,
105         sal_Int32 nCount, const Locale& rLocale )
106 {
107         return getLocaleSpecificCharacterClassification(rLocale)->getStringType(Text, nPos, nCount, rLocale);
108 }
109 
parseAnyToken(const OUString & Text,sal_Int32 nPos,const Locale & rLocale,sal_Int32 startCharTokenType,const OUString & userDefinedCharactersStart,sal_Int32 contCharTokenType,const OUString & userDefinedCharactersCont)110 ParseResult SAL_CALL CharacterClassificationImpl::parseAnyToken(
111         const OUString& Text, sal_Int32 nPos, const Locale& rLocale,
112         sal_Int32 startCharTokenType, const OUString& userDefinedCharactersStart,
113         sal_Int32 contCharTokenType, const OUString& userDefinedCharactersCont )
114 {
115         return getLocaleSpecificCharacterClassification(rLocale)->parseAnyToken(Text, nPos, rLocale,
116                 startCharTokenType,userDefinedCharactersStart,
117                 contCharTokenType, userDefinedCharactersCont);
118 }
119 
120 
parsePredefinedToken(sal_Int32 nTokenType,const OUString & Text,sal_Int32 nPos,const Locale & rLocale,sal_Int32 startCharTokenType,const OUString & userDefinedCharactersStart,sal_Int32 contCharTokenType,const OUString & userDefinedCharactersCont)121 ParseResult SAL_CALL CharacterClassificationImpl::parsePredefinedToken(
122         sal_Int32 nTokenType, const OUString& Text, sal_Int32 nPos,
123         const Locale& rLocale, sal_Int32 startCharTokenType,
124         const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType,
125         const OUString& userDefinedCharactersCont )
126 {
127         return getLocaleSpecificCharacterClassification(rLocale)->parsePredefinedToken(
128                 nTokenType, Text, nPos, rLocale, startCharTokenType, userDefinedCharactersStart,
129                 contCharTokenType, userDefinedCharactersCont);
130 }
131 
createLocaleSpecificCharacterClassification(const OUString & serviceName,const Locale & rLocale)132 sal_Bool SAL_CALL CharacterClassificationImpl::createLocaleSpecificCharacterClassification(const OUString& serviceName, const Locale& rLocale)
133 {
134         // to share service between same Language but different Country code, like zh_CN and zh_SG
135         for (size_t l = 0; l < lookupTable.size(); l++) {
136             cachedItem = lookupTable[l];
137             if (serviceName == cachedItem->aName) {
138                 lookupTable.push_back( cachedItem = new lookupTableItem(rLocale, serviceName, cachedItem->xCI) );
139                 return sal_True;
140             }
141         }
142 
143         Reference < XInterface > xI = xMSF->createInstance(
144             OUString::createFromAscii("com.sun.star.i18n.CharacterClassification_") + serviceName);
145 
146         Reference < XCharacterClassification > xCI;
147         if ( xI.is() ) {
148             xI->queryInterface(::getCppuType((const Reference< XCharacterClassification>*)0) ) >>= xCI;
149             if (xCI.is()) {
150                 lookupTable.push_back( cachedItem =  new lookupTableItem(rLocale, serviceName, xCI) );
151                 return sal_True;
152             }
153         }
154         return sal_False;
155 }
156 
157 Reference < XCharacterClassification > SAL_CALL
getLocaleSpecificCharacterClassification(const Locale & rLocale)158 CharacterClassificationImpl::getLocaleSpecificCharacterClassification(const Locale& rLocale)
159 {
160         // reuse instance if locale didn't change
161         if (cachedItem && cachedItem->equals(rLocale))
162             return cachedItem->xCI;
163         else if (xMSF.is()) {
164             for (size_t i = 0; i < lookupTable.size(); i++) {
165                 cachedItem = lookupTable[i];
166                 if (cachedItem->equals(rLocale))
167                     return cachedItem->xCI;
168             }
169 
170             static sal_Unicode under = (sal_Unicode)'_';
171             static OUString tw(OUString::createFromAscii("TW"));
172             sal_Int32 l = rLocale.Language.getLength();
173             sal_Int32 c = rLocale.Country.getLength();
174             sal_Int32 v = rLocale.Variant.getLength();
175             OUStringBuffer aBuf(l+c+v+3);
176 
177                     // load service with name <base>_<lang>_<country>_<varian>
178             if ((l > 0 && c > 0 && v > 0 &&
179                     createLocaleSpecificCharacterClassification(aBuf.append(rLocale.Language).append(under).append(
180                                     rLocale.Country).append(under).append(rLocale.Variant).makeStringAndClear(), rLocale)) ||
181                     // load service with name <base>_<lang>_<country>
182                 (l > 0 && c > 0 &&
183                     createLocaleSpecificCharacterClassification(aBuf.append(rLocale.Language).append(under).append(
184                                     rLocale.Country).makeStringAndClear(), rLocale)) ||
185                 (l > 0 && c > 0 && rLocale.Language.compareToAscii("zh") == 0 &&
186                                     (rLocale.Country.compareToAscii("HK") == 0 ||
187                                     rLocale.Country.compareToAscii("MO") == 0) &&
188                     // if the country code is HK or MO, one more step to try TW.
189                     createLocaleSpecificCharacterClassification(aBuf.append(rLocale.Language).append(under).append(
190                                     tw).makeStringAndClear(), rLocale)) ||
191                 (l > 0 &&
192                     // load service with name <base>_<lang>
193                     createLocaleSpecificCharacterClassification(rLocale.Language, rLocale))) {
194                 return cachedItem->xCI;
195             } else if (xUCI.is()) {
196                 lookupTable.push_back( cachedItem = new lookupTableItem(rLocale, OUString::createFromAscii("Unicode"), xUCI) );
197                 return cachedItem->xCI;
198             }
199         }
200         throw RuntimeException();
201 }
202 
203 const sal_Char cClass[] = "com.sun.star.i18n.CharacterClassification";
204 
205 OUString SAL_CALL
getImplementationName(void)206 CharacterClassificationImpl::getImplementationName(void)
207 {
208     return OUString::createFromAscii(cClass);
209 }
210 
211 sal_Bool SAL_CALL
supportsService(const rtl::OUString & rServiceName)212 CharacterClassificationImpl::supportsService(const rtl::OUString& rServiceName)
213 {
214     return !rServiceName.compareToAscii(cClass);
215 }
216 
217 Sequence< OUString > SAL_CALL
getSupportedServiceNames(void)218 CharacterClassificationImpl::getSupportedServiceNames(void)
219 {
220     Sequence< OUString > aRet(1);
221     aRet[0] = OUString::createFromAscii(cClass);
222     return aRet;
223 }
224 
225 } } } }
226