merged tag ooo/OOO330_m14
[LibreOffice.git] / i18npool / source / characterclassification / characterclassificationImpl.cxx
blob5665bf6541940c0580310ca67937b7fc9e096f9d
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_i18npool.hxx"
31 #include <characterclassificationImpl.hxx>
32 #include <rtl/ustrbuf.hxx>
34 using namespace com::sun::star::uno;
35 using namespace com::sun::star::lang;
36 using namespace rtl;
38 namespace com { namespace sun { namespace star { namespace i18n {
40 CharacterClassificationImpl::CharacterClassificationImpl(
41 const Reference < lang::XMultiServiceFactory >& rxMSF ) : xMSF( rxMSF )
43 if (createLocaleSpecificCharacterClassification(OUString::createFromAscii("Unicode"), Locale()))
44 xUCI = cachedItem->xCI;
47 CharacterClassificationImpl::~CharacterClassificationImpl() {
48 // Clear lookuptable
49 for (size_t l = 0; l < lookupTable.size(); l++)
50 delete lookupTable[l];
51 lookupTable.clear();
55 OUString SAL_CALL
56 CharacterClassificationImpl::toUpper( const OUString& Text, sal_Int32 nPos,
57 sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
59 return getLocaleSpecificCharacterClassification(rLocale)->toUpper(Text, nPos, nCount, rLocale);
62 OUString SAL_CALL
63 CharacterClassificationImpl::toLower( const OUString& Text, sal_Int32 nPos,
64 sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
66 return getLocaleSpecificCharacterClassification(rLocale)->toLower(Text, nPos, nCount, rLocale);
69 OUString SAL_CALL
70 CharacterClassificationImpl::toTitle( const OUString& Text, sal_Int32 nPos,
71 sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
73 return getLocaleSpecificCharacterClassification(rLocale)->toTitle(Text, nPos, nCount, rLocale);
76 sal_Int16 SAL_CALL
77 CharacterClassificationImpl::getType( const OUString& Text, sal_Int32 nPos )
78 throw(RuntimeException)
80 if (xUCI.is())
81 return xUCI->getType(Text, nPos);
82 throw RuntimeException();
85 sal_Int16 SAL_CALL
86 CharacterClassificationImpl::getCharacterDirection( const OUString& Text, sal_Int32 nPos )
87 throw(RuntimeException)
89 if (xUCI.is())
90 return xUCI->getCharacterDirection(Text, nPos);
91 throw RuntimeException();
94 sal_Int16 SAL_CALL
95 CharacterClassificationImpl::getScript( const OUString& Text, sal_Int32 nPos )
96 throw(RuntimeException)
98 if (xUCI.is())
99 return xUCI->getScript(Text, nPos);
100 throw RuntimeException();
103 sal_Int32 SAL_CALL
104 CharacterClassificationImpl::getCharacterType( const OUString& Text, sal_Int32 nPos,
105 const Locale& rLocale ) throw(RuntimeException)
107 return getLocaleSpecificCharacterClassification(rLocale)->getCharacterType(Text, nPos, rLocale);
110 sal_Int32 SAL_CALL
111 CharacterClassificationImpl::getStringType( const OUString& Text, sal_Int32 nPos,
112 sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
114 return getLocaleSpecificCharacterClassification(rLocale)->getStringType(Text, nPos, nCount, rLocale);
117 ParseResult SAL_CALL CharacterClassificationImpl::parseAnyToken(
118 const OUString& Text, sal_Int32 nPos, const Locale& rLocale,
119 sal_Int32 startCharTokenType, const OUString& userDefinedCharactersStart,
120 sal_Int32 contCharTokenType, const OUString& userDefinedCharactersCont )
121 throw(RuntimeException)
123 return getLocaleSpecificCharacterClassification(rLocale)->parseAnyToken(Text, nPos, rLocale,
124 startCharTokenType,userDefinedCharactersStart,
125 contCharTokenType, userDefinedCharactersCont);
129 ParseResult SAL_CALL CharacterClassificationImpl::parsePredefinedToken(
130 sal_Int32 nTokenType, const OUString& Text, sal_Int32 nPos,
131 const Locale& rLocale, sal_Int32 startCharTokenType,
132 const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType,
133 const OUString& userDefinedCharactersCont ) throw(RuntimeException)
135 return getLocaleSpecificCharacterClassification(rLocale)->parsePredefinedToken(
136 nTokenType, Text, nPos, rLocale, startCharTokenType, userDefinedCharactersStart,
137 contCharTokenType, userDefinedCharactersCont);
140 sal_Bool SAL_CALL CharacterClassificationImpl::createLocaleSpecificCharacterClassification(const OUString& serviceName, const Locale& rLocale)
142 // to share service between same Language but different Country code, like zh_CN and zh_SG
143 for (size_t l = 0; l < lookupTable.size(); l++) {
144 cachedItem = lookupTable[l];
145 if (serviceName == cachedItem->aName) {
146 lookupTable.push_back( cachedItem = new lookupTableItem(rLocale, serviceName, cachedItem->xCI) );
147 return sal_True;
151 Reference < XInterface > xI = xMSF->createInstance(
152 OUString::createFromAscii("com.sun.star.i18n.CharacterClassification_") + serviceName);
154 Reference < XCharacterClassification > xCI;
155 if ( xI.is() ) {
156 xI->queryInterface(::getCppuType((const Reference< XCharacterClassification>*)0) ) >>= xCI;
157 if (xCI.is()) {
158 lookupTable.push_back( cachedItem = new lookupTableItem(rLocale, serviceName, xCI) );
159 return sal_True;
162 return sal_False;
165 Reference < XCharacterClassification > SAL_CALL
166 CharacterClassificationImpl::getLocaleSpecificCharacterClassification(const Locale& rLocale)
167 throw(RuntimeException)
169 // reuse instance if locale didn't change
170 if (cachedItem && cachedItem->equals(rLocale))
171 return cachedItem->xCI;
172 else if (xMSF.is()) {
173 for (size_t i = 0; i < lookupTable.size(); i++) {
174 cachedItem = lookupTable[i];
175 if (cachedItem->equals(rLocale))
176 return cachedItem->xCI;
179 static sal_Unicode under = (sal_Unicode)'_';
180 static OUString tw(OUString::createFromAscii("TW"));
181 sal_Int32 l = rLocale.Language.getLength();
182 sal_Int32 c = rLocale.Country.getLength();
183 sal_Int32 v = rLocale.Variant.getLength();
184 OUStringBuffer aBuf(l+c+v+3);
186 // load service with name <base>_<lang>_<country>_<varian>
187 if ((l > 0 && c > 0 && v > 0 &&
188 createLocaleSpecificCharacterClassification(aBuf.append(rLocale.Language).append(under).append(
189 rLocale.Country).append(under).append(rLocale.Variant).makeStringAndClear(), rLocale)) ||
190 // load service with name <base>_<lang>_<country>
191 (l > 0 && c > 0 &&
192 createLocaleSpecificCharacterClassification(aBuf.append(rLocale.Language).append(under).append(
193 rLocale.Country).makeStringAndClear(), rLocale)) ||
194 (l > 0 && c > 0 && rLocale.Language.compareToAscii("zh") == 0 &&
195 (rLocale.Country.compareToAscii("HK") == 0 ||
196 rLocale.Country.compareToAscii("MO") == 0) &&
197 // if the country code is HK or MO, one more step to try TW.
198 createLocaleSpecificCharacterClassification(aBuf.append(rLocale.Language).append(under).append(
199 tw).makeStringAndClear(), rLocale)) ||
200 (l > 0 &&
201 // load service with name <base>_<lang>
202 createLocaleSpecificCharacterClassification(rLocale.Language, rLocale))) {
203 return cachedItem->xCI;
204 } else if (xUCI.is()) {
205 lookupTable.push_back( cachedItem = new lookupTableItem(rLocale, OUString::createFromAscii("Unicode"), xUCI) );
206 return cachedItem->xCI;
209 throw RuntimeException();
212 const sal_Char cClass[] = "com.sun.star.i18n.CharacterClassification";
214 OUString SAL_CALL
215 CharacterClassificationImpl::getImplementationName(void)
216 throw( RuntimeException )
218 return OUString::createFromAscii(cClass);
221 sal_Bool SAL_CALL
222 CharacterClassificationImpl::supportsService(const rtl::OUString& rServiceName)
223 throw( RuntimeException )
225 return !rServiceName.compareToAscii(cClass);
228 Sequence< OUString > SAL_CALL
229 CharacterClassificationImpl::getSupportedServiceNames(void) throw( RuntimeException )
231 Sequence< OUString > aRet(1);
232 aRet[0] = OUString::createFromAscii(cClass);
233 return aRet;
236 } } } }