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
;
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() {
49 for (size_t l
= 0; l
< lookupTable
.size(); l
++)
50 delete lookupTable
[l
];
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
);
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
);
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
);
77 CharacterClassificationImpl::getType( const OUString
& Text
, sal_Int32 nPos
)
78 throw(RuntimeException
)
81 return xUCI
->getType(Text
, nPos
);
82 throw RuntimeException();
86 CharacterClassificationImpl::getCharacterDirection( const OUString
& Text
, sal_Int32 nPos
)
87 throw(RuntimeException
)
90 return xUCI
->getCharacterDirection(Text
, nPos
);
91 throw RuntimeException();
95 CharacterClassificationImpl::getScript( const OUString
& Text
, sal_Int32 nPos
)
96 throw(RuntimeException
)
99 return xUCI
->getScript(Text
, nPos
);
100 throw RuntimeException();
104 CharacterClassificationImpl::getCharacterType( const OUString
& Text
, sal_Int32 nPos
,
105 const Locale
& rLocale
) throw(RuntimeException
)
107 return getLocaleSpecificCharacterClassification(rLocale
)->getCharacterType(Text
, nPos
, rLocale
);
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
) );
151 Reference
< XInterface
> xI
= xMSF
->createInstance(
152 OUString::createFromAscii("com.sun.star.i18n.CharacterClassification_") + serviceName
);
154 Reference
< XCharacterClassification
> xCI
;
156 xI
->queryInterface(::getCppuType((const Reference
< XCharacterClassification
>*)0) ) >>= xCI
;
158 lookupTable
.push_back( cachedItem
= new lookupTableItem(rLocale
, serviceName
, xCI
) );
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>
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
)) ||
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";
215 CharacterClassificationImpl::getImplementationName(void)
216 throw( RuntimeException
)
218 return OUString::createFromAscii(cClass
);
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
);