bump product version to 4.1.6.2
[LibreOffice.git] / i18npool / source / characterclassification / characterclassificationImpl.cxx
blob65f8f9cc047ca73d4c4888a71532860986409fce
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <characterclassificationImpl.hxx>
22 #include <rtl/ustrbuf.hxx>
24 using namespace com::sun::star::uno;
25 using namespace com::sun::star::lang;
28 namespace com { namespace sun { namespace star { namespace i18n {
30 CharacterClassificationImpl::CharacterClassificationImpl(
31 const Reference < uno::XComponentContext >& rxContext ) : m_xContext( rxContext )
33 if (createLocaleSpecificCharacterClassification(OUString("Unicode"), Locale()))
34 xUCI = cachedItem->xCI;
37 CharacterClassificationImpl::~CharacterClassificationImpl() {
38 // Clear lookuptable
39 for (size_t l = 0; l < lookupTable.size(); l++)
40 delete lookupTable[l];
41 lookupTable.clear();
45 OUString SAL_CALL
46 CharacterClassificationImpl::toUpper( const OUString& Text, sal_Int32 nPos,
47 sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
49 return getLocaleSpecificCharacterClassification(rLocale)->toUpper(Text, nPos, nCount, rLocale);
52 OUString SAL_CALL
53 CharacterClassificationImpl::toLower( const OUString& Text, sal_Int32 nPos,
54 sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
56 return getLocaleSpecificCharacterClassification(rLocale)->toLower(Text, nPos, nCount, rLocale);
59 OUString SAL_CALL
60 CharacterClassificationImpl::toTitle( const OUString& Text, sal_Int32 nPos,
61 sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
63 return getLocaleSpecificCharacterClassification(rLocale)->toTitle(Text, nPos, nCount, rLocale);
66 sal_Int16 SAL_CALL
67 CharacterClassificationImpl::getType( const OUString& Text, sal_Int32 nPos )
68 throw(RuntimeException)
70 if (xUCI.is())
71 return xUCI->getType(Text, nPos);
72 throw RuntimeException();
75 sal_Int16 SAL_CALL
76 CharacterClassificationImpl::getCharacterDirection( const OUString& Text, sal_Int32 nPos )
77 throw(RuntimeException)
79 if (xUCI.is())
80 return xUCI->getCharacterDirection(Text, nPos);
81 throw RuntimeException();
84 sal_Int16 SAL_CALL
85 CharacterClassificationImpl::getScript( const OUString& Text, sal_Int32 nPos )
86 throw(RuntimeException)
88 if (xUCI.is())
89 return xUCI->getScript(Text, nPos);
90 throw RuntimeException();
93 sal_Int32 SAL_CALL
94 CharacterClassificationImpl::getCharacterType( const OUString& Text, sal_Int32 nPos,
95 const Locale& rLocale ) throw(RuntimeException)
97 return getLocaleSpecificCharacterClassification(rLocale)->getCharacterType(Text, nPos, rLocale);
100 sal_Int32 SAL_CALL
101 CharacterClassificationImpl::getStringType( const OUString& Text, sal_Int32 nPos,
102 sal_Int32 nCount, const Locale& rLocale ) throw(RuntimeException)
104 return getLocaleSpecificCharacterClassification(rLocale)->getStringType(Text, nPos, nCount, rLocale);
107 ParseResult SAL_CALL CharacterClassificationImpl::parseAnyToken(
108 const OUString& Text, sal_Int32 nPos, const Locale& rLocale,
109 sal_Int32 startCharTokenType, const OUString& userDefinedCharactersStart,
110 sal_Int32 contCharTokenType, const OUString& userDefinedCharactersCont )
111 throw(RuntimeException)
113 return getLocaleSpecificCharacterClassification(rLocale)->parseAnyToken(Text, nPos, rLocale,
114 startCharTokenType,userDefinedCharactersStart,
115 contCharTokenType, userDefinedCharactersCont);
119 ParseResult SAL_CALL CharacterClassificationImpl::parsePredefinedToken(
120 sal_Int32 nTokenType, const OUString& Text, sal_Int32 nPos,
121 const Locale& rLocale, sal_Int32 startCharTokenType,
122 const OUString& userDefinedCharactersStart, sal_Int32 contCharTokenType,
123 const OUString& userDefinedCharactersCont ) throw(RuntimeException)
125 return getLocaleSpecificCharacterClassification(rLocale)->parsePredefinedToken(
126 nTokenType, Text, nPos, rLocale, startCharTokenType, userDefinedCharactersStart,
127 contCharTokenType, userDefinedCharactersCont);
130 sal_Bool SAL_CALL CharacterClassificationImpl::createLocaleSpecificCharacterClassification(const OUString& serviceName, const Locale& rLocale)
132 // to share service between same Language but different Country code, like zh_CN and zh_SG
133 for (size_t l = 0; l < lookupTable.size(); l++) {
134 cachedItem = lookupTable[l];
135 if (serviceName == cachedItem->aName) {
136 lookupTable.push_back( cachedItem = new lookupTableItem(rLocale, serviceName, cachedItem->xCI) );
137 return sal_True;
141 Reference < XInterface > xI = m_xContext->getServiceManager()->createInstanceWithContext(
142 OUString("com.sun.star.i18n.CharacterClassification_") + serviceName, m_xContext);
144 Reference < XCharacterClassification > xCI;
145 if ( xI.is() ) {
146 xCI.set( xI, UNO_QUERY );
147 if (xCI.is()) {
148 lookupTable.push_back( cachedItem = new lookupTableItem(rLocale, serviceName, xCI) );
149 return sal_True;
152 return sal_False;
155 Reference < XCharacterClassification > SAL_CALL
156 CharacterClassificationImpl::getLocaleSpecificCharacterClassification(const Locale& rLocale)
157 throw(RuntimeException)
159 // reuse instance if locale didn't change
160 if (cachedItem && cachedItem->equals(rLocale))
161 return cachedItem->xCI;
162 else {
163 for (size_t i = 0; i < lookupTable.size(); i++) {
164 cachedItem = lookupTable[i];
165 if (cachedItem->equals(rLocale))
166 return cachedItem->xCI;
169 static sal_Unicode under = (sal_Unicode)'_';
170 sal_Int32 l = rLocale.Language.getLength();
171 sal_Int32 c = rLocale.Country.getLength();
172 sal_Int32 v = rLocale.Variant.getLength();
173 OUStringBuffer aBuf(l+c+v+3);
175 // load service with name <base>_<lang>_<country>_<varian>
176 if ((l > 0 && c > 0 && v > 0 &&
177 createLocaleSpecificCharacterClassification(aBuf.append(rLocale.Language).append(under).append(
178 rLocale.Country).append(under).append(rLocale.Variant).makeStringAndClear(), rLocale)) ||
179 // load service with name <base>_<lang>_<country>
180 (l > 0 && c > 0 &&
181 createLocaleSpecificCharacterClassification(aBuf.append(rLocale.Language).append(under).append(
182 rLocale.Country).makeStringAndClear(), rLocale)) ||
183 (l > 0 && c > 0 && rLocale.Language.compareToAscii("zh") == 0 &&
184 (rLocale.Country.compareToAscii("HK") == 0 ||
185 rLocale.Country.compareToAscii("MO") == 0) &&
186 // if the country code is HK or MO, one more step to try TW.
187 createLocaleSpecificCharacterClassification(aBuf.append(rLocale.Language).append(under).append(
188 "TW").makeStringAndClear(), rLocale)) ||
189 (l > 0 &&
190 // load service with name <base>_<lang>
191 createLocaleSpecificCharacterClassification(rLocale.Language, rLocale))) {
192 return cachedItem->xCI;
193 } else if (xUCI.is()) {
194 lookupTable.push_back( cachedItem = new lookupTableItem(rLocale, OUString("Unicode"), xUCI) );
195 return cachedItem->xCI;
198 throw RuntimeException();
201 const sal_Char cClass[] = "com.sun.star.i18n.CharacterClassification";
203 OUString SAL_CALL
204 CharacterClassificationImpl::getImplementationName(void)
205 throw( RuntimeException )
207 return OUString::createFromAscii(cClass);
210 sal_Bool SAL_CALL
211 CharacterClassificationImpl::supportsService(const OUString& rServiceName)
212 throw( RuntimeException )
214 return !rServiceName.compareToAscii(cClass);
217 Sequence< OUString > SAL_CALL
218 CharacterClassificationImpl::getSupportedServiceNames(void) throw( RuntimeException )
220 Sequence< OUString > aRet(1);
221 aRet[0] = OUString::createFromAscii(cClass);
222 return aRet;
225 } } } }
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */