bump product version to 4.1.6.2
[LibreOffice.git] / i18npool / source / collator / collator_unicode.cxx
blobbcdef824a9aaf51887dda9dcb5822ff62b3ef7c1
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 // generated list of languages
22 #include "lrl_include.hxx"
24 #include <rtl/ustrbuf.hxx>
25 #include <i18nlangtag/languagetag.hxx>
26 #include <i18nlangtag/languagetagicu.hxx>
27 #include <collator_unicode.hxx>
28 #include <localedata.hxx>
29 #include <com/sun/star/i18n/CollatorOptions.hpp>
31 using namespace ::com::sun::star;
32 using namespace ::com::sun::star::lang;
33 using namespace ::com::sun::star::uno;
34 using namespace ::rtl;
36 namespace com { namespace sun { namespace star { namespace i18n {
38 Collator_Unicode::Collator_Unicode()
40 implementationName = "com.sun.star.i18n.Collator_Unicode";
41 collator = NULL;
42 uca_base = NULL;
43 #ifndef DISABLE_DYNLOADING
44 hModule = NULL;
45 #endif
48 Collator_Unicode::~Collator_Unicode()
50 if (collator) delete collator;
51 if (uca_base) delete uca_base;
52 #ifndef DISABLE_DYNLOADING
53 if (hModule) osl_unloadModule(hModule);
54 #endif
57 #ifdef DISABLE_DYNLOADING
59 extern "C" {
61 // For DISABLE_DYNLOADING the generated functions have names that
62 // start with get_collator_data_ to avoid clashing with a few
63 // functions in the generated libindex_data that are called just
64 // get_zh_pinyin for instance.
66 const sal_uInt8* get_collator_data_ca_charset();
67 const sal_uInt8* get_collator_data_dz_charset();
68 const sal_uInt8* get_collator_data_hu_charset();
69 const sal_uInt8* get_collator_data_ja_charset();
70 const sal_uInt8* get_collator_data_ja_phonetic_alphanumeric_first();
71 const sal_uInt8* get_collator_data_ja_phonetic_alphanumeric_last();
72 const sal_uInt8* get_collator_data_ko_charset();
73 const sal_uInt8* get_collator_data_ku_alphanumeric();
74 const sal_uInt8* get_collator_data_ln_charset();
75 const sal_uInt8* get_collator_data_my_dictionary();
76 const sal_uInt8* get_collator_data_ne_charset();
77 const sal_uInt8* get_collator_data_sid_charset();
78 const sal_uInt8* get_collator_data_zh_TW_charset();
79 const sal_uInt8* get_collator_data_zh_TW_radical();
80 const sal_uInt8* get_collator_data_zh_TW_stroke();
81 const sal_uInt8* get_collator_data_zh_charset();
82 const sal_uInt8* get_collator_data_zh_pinyin();
83 const sal_uInt8* get_collator_data_zh_radical();
84 const sal_uInt8* get_collator_data_zh_stroke();
85 const sal_uInt8* get_collator_data_zh_zhuyin();
89 #endif
91 sal_Int32 SAL_CALL
92 Collator_Unicode::compareSubstring( const OUString& str1, sal_Int32 off1, sal_Int32 len1,
93 const OUString& str2, sal_Int32 off2, sal_Int32 len2) throw(RuntimeException)
95 return collator->compare(reinterpret_cast<const UChar *>(str1.getStr()) + off1, len1, reinterpret_cast<const UChar *>(str2.getStr()) + off2, len2); // UChar != sal_Unicode in MinGW
98 sal_Int32 SAL_CALL
99 Collator_Unicode::compareString( const OUString& str1, const OUString& str2) throw(RuntimeException)
101 return collator->compare(reinterpret_cast<const UChar *>(str1.getStr()), reinterpret_cast<const UChar *>(str2.getStr())); // UChar != sal_Unicode in MinGW
104 #ifndef DISABLE_DYNLOADING
106 extern "C" { static void SAL_CALL thisModule() {} }
108 #endif
110 sal_Int32 SAL_CALL
111 Collator_Unicode::loadCollatorAlgorithm(const OUString& rAlgorithm, const lang::Locale& rLocale, sal_Int32 options)
112 throw(RuntimeException)
114 if (!collator) {
115 UErrorCode status = U_ZERO_ERROR;
116 OUString rule = LocaleData().getCollatorRuleByAlgorithm(rLocale, rAlgorithm);
117 if (!rule.isEmpty()) {
118 collator = new RuleBasedCollator(reinterpret_cast<const UChar *>(rule.getStr()), status); // UChar != sal_Unicode in MinGW
119 if (! U_SUCCESS(status)) throw RuntimeException();
121 if (!collator && OUString::createFromAscii(LOCAL_RULE_LANGS).indexOf(rLocale.Language) >= 0) {
122 const sal_uInt8* (*func)() = NULL;
124 #ifndef DISABLE_DYNLOADING
125 OUStringBuffer aBuf;
126 #ifdef SAL_DLLPREFIX
127 aBuf.appendAscii(SAL_DLLPREFIX);
128 #endif
129 aBuf.appendAscii( "collator_data" ).appendAscii( SAL_DLLEXTENSION );
130 hModule = osl_loadModuleRelative( &thisModule, aBuf.makeStringAndClear().pData, SAL_LOADMODULE_DEFAULT );
131 if (hModule) {
132 aBuf.appendAscii("get_").append(rLocale.Language).appendAscii("_");
133 if ( rLocale.Language == "zh" ) {
134 OUString func_base = aBuf.makeStringAndClear();
135 if (OUString("TW HK MO").indexOf(rLocale.Country) >= 0)
136 func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule,
137 OUString(func_base + "TW_" + rAlgorithm).pData);
138 if (!func)
139 func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule, OUString(func_base + rAlgorithm).pData);
140 } else {
141 if ( rLocale.Language == "ja" ) {
142 // replace algorithm name to implementation name.
143 if (rAlgorithm.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("phonetic (alphanumeric first)")) )
144 aBuf.appendAscii("phonetic_alphanumeric_first");
145 else if (rAlgorithm.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("phonetic (alphanumeric last)")))
146 aBuf.appendAscii("phonetic_alphanumeric_last");
147 else
148 aBuf.append(rAlgorithm);
149 } else {
150 aBuf.append(rAlgorithm);
152 func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule, aBuf.makeStringAndClear().pData);
155 #else
156 if ( rLocale.Language == "ca" ) {
157 if ( rAlgorithm == "charset" )
158 func = get_collator_data_ca_charset;
159 } else if ( rLocale.Language == "dz" ) {
160 if ( rAlgorithm == "charset" )
161 func = get_collator_data_dz_charset;
162 } else if ( rLocale.Language == "hu" ) {
163 if ( rAlgorithm == "charset" )
164 func = get_collator_data_hu_charset;
165 } else if ( rLocale.Language == "ja" ) {
166 if ( rAlgorithm == "charset" )
167 func = get_collator_data_ja_charset;
168 else if ( rAlgorithm == "phonetic (alphanumeric first)" )
169 func = get_collator_data_ja_phonetic_alphanumeric_first;
170 else if ( rAlgorithm == "phonetic (alphanumeric last)" )
171 func = get_collator_data_ja_phonetic_alphanumeric_last;
172 } else if ( rLocale.Language == "ko" ) {
173 if ( rAlgorithm == "charset" )
174 func = get_collator_data_ko_charset;
175 } else if ( rLocale.Language == "ku" ) {
176 if ( rAlgorithm == "alphanumeric" )
177 func = get_collator_data_ku_alphanumeric;
178 } else if ( rLocale.Language == "ln" ) {
179 if ( rAlgorithm == "charset" )
180 func = get_collator_data_ln_charset;
181 } else if ( rLocale.Language == "my" ) {
182 if ( rAlgorithm == "dictionary" )
183 func = get_collator_data_my_dictionary;
184 } else if ( rLocale.Language == "ne" ) {
185 if ( rAlgorithm == "charset" )
186 func = get_collator_data_ne_charset;
187 } else if ( rLocale.Language == "sid" ) {
188 if ( rAlgorithm == "charset" )
189 func = get_collator_data_sid_charset;
190 } else if ( rLocale.Language == "zh" && (rLocale.Country == "TW" || rLocale.Country == "HK" || rLocale.Country == "MO") ) {
191 if ( rAlgorithm == "charset" )
192 func = get_collator_data_zh_TW_charset;
193 else if ( rAlgorithm == "radical" )
194 func = get_collator_data_zh_TW_radical;
195 else if ( rAlgorithm == "stroke" )
196 func = get_collator_data_zh_TW_stroke;
197 } else if ( rLocale.Language == "zh" ) {
198 if ( rAlgorithm == "charset" )
199 func = get_collator_data_zh_charset;
200 else if ( rAlgorithm == "pinyin" )
201 func = get_collator_data_zh_pinyin;
202 else if ( rAlgorithm == "radical" )
203 func = get_collator_data_zh_radical;
204 else if ( rAlgorithm == "stroke" )
205 func = get_collator_data_zh_stroke;
206 else if ( rAlgorithm == "zhuyin" )
207 func = get_collator_data_zh_zhuyin;
209 #endif
210 if (func) {
211 const sal_uInt8* ruleImage=func();
212 uca_base = new RuleBasedCollator(static_cast<UChar*>(NULL), status);
213 if (! U_SUCCESS(status)) throw RuntimeException();
214 collator = new RuleBasedCollator(reinterpret_cast<const uint8_t*>(ruleImage), -1, uca_base, status);
215 if (! U_SUCCESS(status)) throw RuntimeException();
218 if (!collator) {
219 /** ICU collators are loaded using a locale only.
220 ICU uses Variant as collation algorithm name (like de__PHONEBOOK
221 locale), note the empty territory (Country) designator in this special
222 case here. The icu::Locale constructor changes the algorithm name to
223 uppercase itself, so we don't have to bother with that.
225 icu::Locale icuLocale( LanguageTagIcu::getIcuLocale( LanguageTag( rLocale), rAlgorithm));
226 // load ICU collator
227 collator = (RuleBasedCollator*) icu::Collator::createInstance(icuLocale, status);
228 if (! U_SUCCESS(status)) throw RuntimeException();
232 if (options & CollatorOptions::CollatorOptions_IGNORE_CASE_ACCENT)
233 collator->setStrength(Collator::PRIMARY);
234 else if (options & CollatorOptions::CollatorOptions_IGNORE_CASE)
235 collator->setStrength(Collator::SECONDARY);
236 else
237 collator->setStrength(Collator::TERTIARY);
239 return(0);
243 OUString SAL_CALL
244 Collator_Unicode::getImplementationName() throw( RuntimeException )
246 return OUString::createFromAscii(implementationName);
249 sal_Bool SAL_CALL
250 Collator_Unicode::supportsService(const OUString& rServiceName) throw( RuntimeException )
252 return !rServiceName.compareToAscii(implementationName);
255 Sequence< OUString > SAL_CALL
256 Collator_Unicode::getSupportedServiceNames() throw( RuntimeException )
258 Sequence< OUString > aRet(1);
259 aRet[0] = OUString::createFromAscii(implementationName);
260 return aRet;
263 } } } }
265 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */