Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : // generated list of languages
22 : #include "lrl_include.hxx"
23 :
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>
30 :
31 : using namespace ::com::sun::star;
32 : using namespace ::com::sun::star::lang;
33 : using namespace ::com::sun::star::uno;
34 : using namespace ::rtl;
35 :
36 : namespace com { namespace sun { namespace star { namespace i18n {
37 :
38 366 : Collator_Unicode::Collator_Unicode()
39 : {
40 366 : implementationName = "com.sun.star.i18n.Collator_Unicode";
41 366 : collator = NULL;
42 366 : uca_base = NULL;
43 : #ifndef DISABLE_DYNLOADING
44 366 : hModule = NULL;
45 : #endif
46 366 : }
47 :
48 1050 : Collator_Unicode::~Collator_Unicode()
49 : {
50 350 : if (collator) delete collator;
51 350 : if (uca_base) delete uca_base;
52 : #ifndef DISABLE_DYNLOADING
53 350 : if (hModule) osl_unloadModule(hModule);
54 : #endif
55 700 : }
56 :
57 : #ifdef DISABLE_DYNLOADING
58 :
59 : extern "C" {
60 :
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.
65 :
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();
86 :
87 : }
88 :
89 : #endif
90 :
91 : sal_Int32 SAL_CALL
92 608146 : Collator_Unicode::compareSubstring( const OUString& str1, sal_Int32 off1, sal_Int32 len1,
93 : const OUString& str2, sal_Int32 off2, sal_Int32 len2) throw(RuntimeException)
94 : {
95 608146 : return collator->compare(reinterpret_cast<const UChar *>(str1.getStr()) + off1, len1, reinterpret_cast<const UChar *>(str2.getStr()) + off2, len2); // UChar != sal_Unicode in MinGW
96 : }
97 :
98 : sal_Int32 SAL_CALL
99 76790 : Collator_Unicode::compareString( const OUString& str1, const OUString& str2) throw(RuntimeException)
100 : {
101 76790 : return collator->compare(reinterpret_cast<const UChar *>(str1.getStr()), reinterpret_cast<const UChar *>(str2.getStr())); // UChar != sal_Unicode in MinGW
102 : }
103 :
104 : #ifndef DISABLE_DYNLOADING
105 :
106 0 : extern "C" { static void SAL_CALL thisModule() {} }
107 :
108 : #endif
109 :
110 : sal_Int32 SAL_CALL
111 366 : Collator_Unicode::loadCollatorAlgorithm(const OUString& rAlgorithm, const lang::Locale& rLocale, sal_Int32 options)
112 : throw(RuntimeException)
113 : {
114 366 : if (!collator) {
115 366 : UErrorCode status = U_ZERO_ERROR;
116 366 : OUString rule = LocaleData().getCollatorRuleByAlgorithm(rLocale, rAlgorithm);
117 366 : if (!rule.isEmpty()) {
118 0 : collator = new RuleBasedCollator(reinterpret_cast<const UChar *>(rule.getStr()), status); // UChar != sal_Unicode in MinGW
119 0 : if (! U_SUCCESS(status)) throw RuntimeException();
120 : }
121 366 : if (!collator && OUString::createFromAscii(LOCAL_RULE_LANGS).indexOf(rLocale.Language) >= 0) {
122 0 : const sal_uInt8* (*func)() = NULL;
123 :
124 : #ifndef DISABLE_DYNLOADING
125 0 : OUStringBuffer aBuf;
126 : #ifdef SAL_DLLPREFIX
127 0 : aBuf.appendAscii(SAL_DLLPREFIX);
128 : #endif
129 0 : aBuf.appendAscii( "collator_data" ).appendAscii( SAL_DLLEXTENSION );
130 0 : hModule = osl_loadModuleRelative( &thisModule, aBuf.makeStringAndClear().pData, SAL_LOADMODULE_DEFAULT );
131 0 : if (hModule) {
132 0 : aBuf.appendAscii("get_").append(rLocale.Language).appendAscii("_");
133 0 : if ( rLocale.Language == "zh" ) {
134 0 : OUString func_base = aBuf.makeStringAndClear();
135 0 : if (OUString("TW HK MO").indexOf(rLocale.Country) >= 0)
136 : func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule,
137 0 : OUString(func_base + "TW_" + rAlgorithm).pData);
138 0 : if (!func)
139 0 : func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule, OUString(func_base + rAlgorithm).pData);
140 : } else {
141 0 : if ( rLocale.Language == "ja" ) {
142 : // replace algorithm name to implementation name.
143 0 : if (rAlgorithm.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("phonetic (alphanumeric first)")) )
144 0 : aBuf.appendAscii("phonetic_alphanumeric_first");
145 0 : else if (rAlgorithm.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("phonetic (alphanumeric last)")))
146 0 : aBuf.appendAscii("phonetic_alphanumeric_last");
147 : else
148 0 : aBuf.append(rAlgorithm);
149 : } else {
150 0 : aBuf.append(rAlgorithm);
151 : }
152 0 : func=(const sal_uInt8* (*)()) osl_getFunctionSymbol(hModule, aBuf.makeStringAndClear().pData);
153 : }
154 : }
155 : #else
156 : if ( rLocale.Language == "ca" ) {
157 : if ( rAlgorithm == "charset" )
158 : func = get_collator_data_ca_charset;
159 : } else if ( rLocale.Language == "dz" || rLocale.Language == "bo" ) {
160 : // 'bo' Tibetan uses the same collation rules as 'dz' Dzongkha
161 : if ( rAlgorithm == "charset" )
162 : func = get_collator_data_dz_charset;
163 : } else if ( rLocale.Language == "hu" ) {
164 : if ( rAlgorithm == "charset" )
165 : func = get_collator_data_hu_charset;
166 : } else if ( rLocale.Language == "ja" ) {
167 : if ( rAlgorithm == "charset" )
168 : func = get_collator_data_ja_charset;
169 : else if ( rAlgorithm == "phonetic (alphanumeric first)" )
170 : func = get_collator_data_ja_phonetic_alphanumeric_first;
171 : else if ( rAlgorithm == "phonetic (alphanumeric last)" )
172 : func = get_collator_data_ja_phonetic_alphanumeric_last;
173 : } else if ( rLocale.Language == "ko" ) {
174 : if ( rAlgorithm == "charset" )
175 : func = get_collator_data_ko_charset;
176 : } else if ( rLocale.Language == "ku" ) {
177 : if ( rAlgorithm == "alphanumeric" )
178 : func = get_collator_data_ku_alphanumeric;
179 : } else if ( rLocale.Language == "ln" ) {
180 : if ( rAlgorithm == "charset" )
181 : func = get_collator_data_ln_charset;
182 : } else if ( rLocale.Language == "my" ) {
183 : if ( rAlgorithm == "dictionary" )
184 : func = get_collator_data_my_dictionary;
185 : } else if ( rLocale.Language == "ne" ) {
186 : if ( rAlgorithm == "charset" )
187 : func = get_collator_data_ne_charset;
188 : } else if ( rLocale.Language == "sid" ) {
189 : if ( rAlgorithm == "charset" )
190 : func = get_collator_data_sid_charset;
191 : } else if ( rLocale.Language == "zh" && (rLocale.Country == "TW" || rLocale.Country == "HK" || rLocale.Country == "MO") ) {
192 : if ( rAlgorithm == "charset" )
193 : func = get_collator_data_zh_TW_charset;
194 : else if ( rAlgorithm == "radical" )
195 : func = get_collator_data_zh_TW_radical;
196 : else if ( rAlgorithm == "stroke" )
197 : func = get_collator_data_zh_TW_stroke;
198 : } else if ( rLocale.Language == "zh" ) {
199 : if ( rAlgorithm == "charset" )
200 : func = get_collator_data_zh_charset;
201 : else if ( rAlgorithm == "pinyin" )
202 : func = get_collator_data_zh_pinyin;
203 : else if ( rAlgorithm == "radical" )
204 : func = get_collator_data_zh_radical;
205 : else if ( rAlgorithm == "stroke" )
206 : func = get_collator_data_zh_stroke;
207 : else if ( rAlgorithm == "zhuyin" )
208 : func = get_collator_data_zh_zhuyin;
209 : }
210 : #endif
211 0 : if (func) {
212 0 : const sal_uInt8* ruleImage=func();
213 0 : uca_base = new RuleBasedCollator(static_cast<UChar*>(NULL), status);
214 0 : if (! U_SUCCESS(status)) throw RuntimeException();
215 0 : collator = new RuleBasedCollator(reinterpret_cast<const uint8_t*>(ruleImage), -1, uca_base, status);
216 0 : if (! U_SUCCESS(status)) throw RuntimeException();
217 0 : }
218 : }
219 366 : if (!collator) {
220 : /** ICU collators are loaded using a locale only.
221 : ICU uses Variant as collation algorithm name (like de__PHONEBOOK
222 : locale), note the empty territory (Country) designator in this special
223 : case here. The icu::Locale constructor changes the algorithm name to
224 : uppercase itself, so we don't have to bother with that.
225 : */
226 366 : icu::Locale icuLocale( LanguageTagIcu::getIcuLocale( LanguageTag( rLocale), rAlgorithm));
227 : // load ICU collator
228 366 : collator = (RuleBasedCollator*) icu::Collator::createInstance(icuLocale, status);
229 366 : if (! U_SUCCESS(status)) throw RuntimeException();
230 366 : }
231 : }
232 :
233 366 : if (options & CollatorOptions::CollatorOptions_IGNORE_CASE_ACCENT)
234 10 : collator->setStrength(Collator::PRIMARY);
235 356 : else if (options & CollatorOptions::CollatorOptions_IGNORE_CASE)
236 24 : collator->setStrength(Collator::SECONDARY);
237 : else
238 332 : collator->setStrength(Collator::TERTIARY);
239 :
240 366 : return(0);
241 : }
242 :
243 :
244 : OUString SAL_CALL
245 0 : Collator_Unicode::getImplementationName() throw( RuntimeException )
246 : {
247 0 : return OUString::createFromAscii(implementationName);
248 : }
249 :
250 : sal_Bool SAL_CALL
251 0 : Collator_Unicode::supportsService(const OUString& rServiceName) throw( RuntimeException )
252 : {
253 0 : return !rServiceName.compareToAscii(implementationName);
254 : }
255 :
256 : Sequence< OUString > SAL_CALL
257 0 : Collator_Unicode::getSupportedServiceNames() throw( RuntimeException )
258 : {
259 0 : Sequence< OUString > aRet(1);
260 0 : aRet[0] = OUString::createFromAscii(implementationName);
261 0 : return aRet;
262 : }
263 :
264 : } } } }
265 :
266 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|