20#include <config_locales.h>
23#include <rtl/ustrbuf.hxx>
25#include <lrl_include.hxx>
31#include <com/sun/star/i18n/CollatorOptions.hpp>
47#ifndef DISABLE_DYNLOADING
56#ifndef DISABLE_DYNLOADING
61#ifdef DISABLE_DYNLOADING
70const sal_uInt8* get_collator_data_ca_charset();
71const sal_uInt8* get_collator_data_cu_charset();
72const sal_uInt8* get_collator_data_dz_charset();
73const sal_uInt8* get_collator_data_hu_charset();
74const sal_uInt8* get_collator_data_ja_charset();
75const sal_uInt8* get_collator_data_ja_phonetic_alphanumeric_first();
76const sal_uInt8* get_collator_data_ja_phonetic_alphanumeric_last();
77const sal_uInt8* get_collator_data_ko_charset();
78const sal_uInt8* get_collator_data_ku_alphanumeric();
79const sal_uInt8* get_collator_data_ln_charset();
80const sal_uInt8* get_collator_data_my_dictionary();
81const sal_uInt8* get_collator_data_ne_charset();
82const sal_uInt8* get_collator_data_sid_charset();
83const sal_uInt8* get_collator_data_vro_alphanumeric();
84const sal_uInt8* get_collator_data_zh_TW_charset();
85const sal_uInt8* get_collator_data_zh_TW_radical();
86const sal_uInt8* get_collator_data_zh_TW_stroke();
87const sal_uInt8* get_collator_data_zh_charset();
88const sal_uInt8* get_collator_data_zh_pinyin();
89const sal_uInt8* get_collator_data_zh_radical();
90const sal_uInt8* get_collator_data_zh_stroke();
91const sal_uInt8* get_collator_data_zh_zhuyin();
93size_t get_collator_data_ca_charset_length();
94size_t get_collator_data_cu_charset_length();
95size_t get_collator_data_dz_charset_length();
96size_t get_collator_data_hu_charset_length();
97size_t get_collator_data_ja_charset_length();
98size_t get_collator_data_ja_phonetic_alphanumeric_first_length();
99size_t get_collator_data_ja_phonetic_alphanumeric_last_length();
100size_t get_collator_data_ko_charset_length();
101size_t get_collator_data_ku_alphanumeric_length();
102size_t get_collator_data_ln_charset_length();
103size_t get_collator_data_my_dictionary_length();
104size_t get_collator_data_ne_charset_length();
105size_t get_collator_data_sid_charset_length();
106size_t get_collator_data_vro_alphanumeric_length();
107size_t get_collator_data_zh_TW_charset_length();
108size_t get_collator_data_zh_TW_radical_length();
109size_t get_collator_data_zh_TW_stroke_length();
110size_t get_collator_data_zh_charset_length();
111size_t get_collator_data_zh_pinyin_length();
112size_t get_collator_data_zh_radical_length();
113size_t get_collator_data_zh_stroke_length();
114size_t get_collator_data_zh_zhuyin_length();
122 const OUString& str2, sal_Int32 off2, sal_Int32 len2)
124 return collator->compare(
reinterpret_cast<const UChar *
>(str1.getStr()) + off1, len1,
reinterpret_cast<const UChar *
>(str2.getStr()) + off2, len2);
130 return collator->compare(
reinterpret_cast<const UChar *
>(str1.getStr()), str1.getLength(),
131 reinterpret_cast<const UChar *
>(str2.getStr()), str2.getLength());
134#ifndef DISABLE_DYNLOADING
144 UErrorCode status = U_ZERO_ERROR;
146 if (!rule.isEmpty()) {
147 collator.reset(
new icu::RuleBasedCollator(
reinterpret_cast<const UChar *
>(rule.getStr()), status) );
148 if (! U_SUCCESS(status)) {
149 OUString message =
"icu::RuleBasedCollator ctor failed: " + OUString::createFromAscii(u_errorName(status));
154 if (!
collator && OUString(LOCAL_RULE_LANGS).indexOf(rLocale.Language) >= 0) {
156 size_t (*funclen)() =
nullptr;
158#ifndef DISABLE_DYNLOADING
164 hModule = osl_loadModuleRelative( &
thisModule,
aBuf.makeStringAndClear().pData, SAL_LOADMODULE_DEFAULT );
166 aBuf.append(
"get_" + rLocale.Language +
"_");
167 if ( rLocale.Language ==
"zh" ) {
168 OUString func_base =
aBuf.makeStringAndClear();
169 if (OUString(
"TW HK MO").indexOf(rLocale.Country) >= 0)
171 func =
reinterpret_cast<const sal_uInt8* (*)()
>(osl_getFunctionSymbol(
hModule,
172 OUString(func_base +
"TW_" + rAlgorithm).
pData));
173 funclen =
reinterpret_cast<size_t (*)()
>(osl_getFunctionSymbol(
hModule,
174 OUString(func_base +
"TW_" + rAlgorithm +
"_length").
pData));
178 func =
reinterpret_cast<const sal_uInt8* (*)()
>(osl_getFunctionSymbol(
180 funclen =
reinterpret_cast<size_t (*)()
>(osl_getFunctionSymbol(
181 hModule, OUString(func_base + rAlgorithm +
"_length").
pData));
184 if ( rLocale.Language ==
"ja" ) {
186 if (rAlgorithm ==
"phonetic (alphanumeric first)")
187 aBuf.append(
"phonetic_alphanumeric_first");
188 else if (rAlgorithm ==
"phonetic (alphanumeric last)")
189 aBuf.append(
"phonetic_alphanumeric_last");
191 aBuf.append(rAlgorithm);
193 aBuf.append(rAlgorithm);
195 OUString func_base =
aBuf.makeStringAndClear();
196 OUString funclen_base = func_base +
"_length";
197 func =
reinterpret_cast<const sal_uInt8* (*)()
>(osl_getFunctionSymbol(
hModule, func_base.pData));
198 funclen =
reinterpret_cast<size_t (*)()
>(osl_getFunctionSymbol(
hModule, funclen_base.pData));
204#if WITH_LOCALE_ALL || WITH_LOCALE_ca
205 }
else if ( rLocale.Language ==
"ca" ) {
206 if ( rAlgorithm ==
"charset" )
208 func = get_collator_data_ca_charset;
209 funclen = get_collator_data_ca_charset_length;
212#if WITH_LOCALE_ALL || WITH_LOCALE_cu
213 }
else if ( rLocale.Language ==
"cu" ) {
214 if ( rAlgorithm ==
"charset" )
216 func = get_collator_data_cu_charset;
217 funclen = get_collator_data_cu_charset_length;
220#if WITH_LOCALE_ALL || WITH_LOCALE_dz
221 }
else if ( rLocale.Language ==
"dz" || rLocale.Language ==
"bo" ) {
223 if ( rAlgorithm ==
"charset" )
225 func = get_collator_data_dz_charset;
226 funclen = get_collator_data_dz_charset_length;
229#if WITH_LOCALE_ALL || WITH_LOCALE_hu
230 }
else if ( rLocale.Language ==
"hu" ) {
231 if ( rAlgorithm ==
"charset" )
233 func = get_collator_data_hu_charset;
234 funclen = get_collator_data_hu_charset_length;
237#if WITH_LOCALE_ALL || WITH_LOCALE_ja
238 }
else if ( rLocale.Language ==
"ja" ) {
239 if ( rAlgorithm ==
"charset" )
241 func = get_collator_data_ja_charset;
242 funclen = get_collator_data_ja_charset_length;
244 else if ( rAlgorithm ==
"phonetic (alphanumeric first)" )
246 func = get_collator_data_ja_phonetic_alphanumeric_first;
247 funclen = get_collator_data_ja_phonetic_alphanumeric_first_length;
249 else if ( rAlgorithm ==
"phonetic (alphanumeric last)" )
251 func = get_collator_data_ja_phonetic_alphanumeric_last;
252 funclen = get_collator_data_ja_phonetic_alphanumeric_last_length;
255#if WITH_LOCALE_ALL || WITH_LOCALE_ko
256#if (U_ICU_VERSION_MAJOR_NUM < 53)
257 }
else if ( rLocale.Language ==
"ko" ) {
258 if ( rAlgorithm ==
"charset" )
260 func = get_collator_data_ko_charset;
261 funclen = get_collator_data_ko_charset_length;
265#if WITH_LOCALE_ALL || WITH_LOCALE_ku
266 }
else if ( rLocale.Language ==
"ku" ) {
267 if ( rAlgorithm ==
"alphanumeric" )
269 func = get_collator_data_ku_alphanumeric;
270 funclen = get_collator_data_ku_alphanumeric_length;
273#if WITH_LOCALE_ALL || WITH_LOCALE_ln
274 }
else if ( rLocale.Language ==
"ln" ) {
275 if ( rAlgorithm ==
"charset" )
277 func = get_collator_data_ln_charset;
278 funclen = get_collator_data_ln_charset_length;
281#if WITH_LOCALE_ALL || WITH_LOCALE_my
282 }
else if ( rLocale.Language ==
"my" ) {
283 if ( rAlgorithm ==
"dictionary" )
285 func = get_collator_data_my_dictionary;
286 funclen = get_collator_data_my_dictionary_length;
289#if WITH_LOCALE_ALL || WITH_LOCALE_ne
290 }
else if ( rLocale.Language ==
"ne" ) {
291 if ( rAlgorithm ==
"charset" )
293 func = get_collator_data_ne_charset;
294 funclen = get_collator_data_ne_charset_length;
297#if WITH_LOCALE_ALL || WITH_LOCALE_sid
298 }
else if ( rLocale.Language ==
"sid" ) {
299 if ( rAlgorithm ==
"charset" )
301 func = get_collator_data_sid_charset;
302 funclen = get_collator_data_sid_charset_length;
305#if WITH_LOCALE_ALL || WITH_LOCALE_vro
306 }
else if ( rLocale.Language ==
"vro" ) {
307 if ( rAlgorithm ==
"alphanumeric" )
309 func = get_collator_data_vro_alphanumeric;
310 funclen = get_collator_data_vro_alphanumeric_length;
313#if WITH_LOCALE_ALL || WITH_LOCALE_zh
314 }
else if ( rLocale.Language ==
"zh" && (rLocale.Country ==
"TW" || rLocale.Country ==
"HK" || rLocale.Country ==
"MO") ) {
315 if ( rAlgorithm ==
"charset" )
317 func = get_collator_data_zh_TW_charset;
318 funclen = get_collator_data_zh_TW_charset_length;
320 else if ( rAlgorithm ==
"radical" )
322 func = get_collator_data_zh_TW_radical;
323 funclen = get_collator_data_zh_TW_radical_length;
325 else if ( rAlgorithm ==
"stroke" )
327 func = get_collator_data_zh_TW_stroke;
328 funclen = get_collator_data_zh_TW_stroke_length;
330 }
else if ( rLocale.Language ==
"zh" ) {
331 if ( rAlgorithm ==
"charset" )
333 func = get_collator_data_zh_charset;
334 funclen = get_collator_data_zh_charset_length;
336 else if ( rAlgorithm ==
"pinyin" )
338 func = get_collator_data_zh_pinyin;
339 funclen = get_collator_data_zh_pinyin_length;
341 else if ( rAlgorithm ==
"radical" )
343 func = get_collator_data_zh_radical;
344 funclen = get_collator_data_zh_radical_length;
346 else if ( rAlgorithm ==
"stroke" )
348 func = get_collator_data_zh_stroke;
349 funclen = get_collator_data_zh_stroke_length;
351 else if ( rAlgorithm ==
"zhuyin" )
353 func = get_collator_data_zh_zhuyin;
354 funclen = get_collator_data_zh_zhuyin_length;
359 if (func && funclen) {
361 size_t ruleImageSize = funclen();
372 uca_base.reset(
static_cast<icu::RuleBasedCollator*
>(icu::Collator::createInstance(
373 icu::Locale::getRoot(), status)) );
374 if (! U_SUCCESS(status)) {
375 OUString message =
"icu::Collator::createInstance() failed: " + OUString::createFromAscii(u_errorName(status));
379 collator.reset(
new icu::RuleBasedCollator(
380 reinterpret_cast<const uint8_t*
>(ruleImage), ruleImageSize,
uca_base.get(), status) );
381 if (! U_SUCCESS(status)) {
382 OUString message =
"icu::RuleBasedCollator ctor failed: " + OUString::createFromAscii(u_errorName(status));
402 u"", rAlgorithm.isEmpty() ? OUString(
"") :
"collation=" + rAlgorithm));
406 if (!strcmp(icuLocale.getLanguage(),
"ja"))
407 icuLocale = icu::Locale::getJapanese();
410 collator.reset(
static_cast<icu::RuleBasedCollator*
>( icu::Collator::createInstance(icuLocale, status) ) );
411 if (! U_SUCCESS(status)) {
412 OUString message =
"icu::Collator::createInstance() failed: " + OUString::createFromAscii(u_errorName(status));
419 if (options & CollatorOptions::CollatorOptions_IGNORE_CASE_ACCENT)
420 collator->setStrength(icu::Collator::PRIMARY);
421 else if (options & CollatorOptions::CollatorOptions_IGNORE_CASE)
422 collator->setStrength(icu::Collator::SECONDARY);
424 collator->setStrength(icu::Collator::TERTIARY);
442Sequence< OUString > SAL_CALL
static icu::Locale getIcuLocale(const LanguageTag &rLanguageTag)
virtual ~Collator_Unicode() override
std::unique_ptr< icu::RuleBasedCollator > uca_base
virtual OUString SAL_CALL getImplementationName() override
sal_Int32 SAL_CALL compareString(const OUString &s1, const OUString &s2) override
sal_Int32 SAL_CALL loadCollatorAlgorithm(const OUString &impl, const css::lang::Locale &rLocale, sal_Int32 collatorOptions) override
std::unique_ptr< icu::RuleBasedCollator > collator
sal_Int32 SAL_CALL compareSubstring(const OUString &s1, sal_Int32 off1, sal_Int32 len1, const OUString &s2, sal_Int32 off2, sal_Int32 len2) override
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
static rtl::Reference< LocaleDataImpl > get()
#define SAL_WARN(area, stream)
std::unique_ptr< sal_Int32[]> pData
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Constant values shared between i18npool and, for example, the number formatter.
constexpr OUStringLiteral implementationName