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_ku
256 }
else if ( rLocale.Language ==
"ku" ) {
257 if ( rAlgorithm ==
"alphanumeric" )
259 func = get_collator_data_ku_alphanumeric;
260 funclen = get_collator_data_ku_alphanumeric_length;
263#if WITH_LOCALE_ALL || WITH_LOCALE_ln
264 }
else if ( rLocale.Language ==
"ln" ) {
265 if ( rAlgorithm ==
"charset" )
267 func = get_collator_data_ln_charset;
268 funclen = get_collator_data_ln_charset_length;
271#if WITH_LOCALE_ALL || WITH_LOCALE_my
272 }
else if ( rLocale.Language ==
"my" ) {
273 if ( rAlgorithm ==
"dictionary" )
275 func = get_collator_data_my_dictionary;
276 funclen = get_collator_data_my_dictionary_length;
279#if WITH_LOCALE_ALL || WITH_LOCALE_ne
280 }
else if ( rLocale.Language ==
"ne" ) {
281 if ( rAlgorithm ==
"charset" )
283 func = get_collator_data_ne_charset;
284 funclen = get_collator_data_ne_charset_length;
287#if WITH_LOCALE_ALL || WITH_LOCALE_sid
288 }
else if ( rLocale.Language ==
"sid" ) {
289 if ( rAlgorithm ==
"charset" )
291 func = get_collator_data_sid_charset;
292 funclen = get_collator_data_sid_charset_length;
295#if WITH_LOCALE_ALL || WITH_LOCALE_vro
296 }
else if ( rLocale.Language ==
"vro" ) {
297 if ( rAlgorithm ==
"alphanumeric" )
299 func = get_collator_data_vro_alphanumeric;
300 funclen = get_collator_data_vro_alphanumeric_length;
303#if WITH_LOCALE_ALL || WITH_LOCALE_zh
304 }
else if ( rLocale.Language ==
"zh" && (rLocale.Country ==
"TW" || rLocale.Country ==
"HK" || rLocale.Country ==
"MO") ) {
305 if ( rAlgorithm ==
"charset" )
307 func = get_collator_data_zh_TW_charset;
308 funclen = get_collator_data_zh_TW_charset_length;
310 else if ( rAlgorithm ==
"radical" )
312 func = get_collator_data_zh_TW_radical;
313 funclen = get_collator_data_zh_TW_radical_length;
315 else if ( rAlgorithm ==
"stroke" )
317 func = get_collator_data_zh_TW_stroke;
318 funclen = get_collator_data_zh_TW_stroke_length;
320 }
else if ( rLocale.Language ==
"zh" ) {
321 if ( rAlgorithm ==
"charset" )
323 func = get_collator_data_zh_charset;
324 funclen = get_collator_data_zh_charset_length;
326 else if ( rAlgorithm ==
"pinyin" )
328 func = get_collator_data_zh_pinyin;
329 funclen = get_collator_data_zh_pinyin_length;
331 else if ( rAlgorithm ==
"radical" )
333 func = get_collator_data_zh_radical;
334 funclen = get_collator_data_zh_radical_length;
336 else if ( rAlgorithm ==
"stroke" )
338 func = get_collator_data_zh_stroke;
339 funclen = get_collator_data_zh_stroke_length;
341 else if ( rAlgorithm ==
"zhuyin" )
343 func = get_collator_data_zh_zhuyin;
344 funclen = get_collator_data_zh_zhuyin_length;
349 if (func && funclen) {
351 size_t ruleImageSize = funclen();
362 uca_base.reset(
static_cast<icu::RuleBasedCollator*
>(icu::Collator::createInstance(
363 icu::Locale::getRoot(), status)) );
364 if (! U_SUCCESS(status)) {
365 OUString message =
"icu::Collator::createInstance() failed: " + OUString::createFromAscii(u_errorName(status));
369 collator.reset(
new icu::RuleBasedCollator(
370 reinterpret_cast<const uint8_t*
>(ruleImage), ruleImageSize,
uca_base.get(), status) );
371 if (! U_SUCCESS(status)) {
372 OUString message =
"icu::RuleBasedCollator ctor failed: " + OUString::createFromAscii(u_errorName(status));
392 u"", rAlgorithm.isEmpty() ? OUString(
"") :
"collation=" + rAlgorithm));
396 if (!strcmp(icuLocale.getLanguage(),
"ja"))
397 icuLocale = icu::Locale::getJapanese();
400 collator.reset(
static_cast<icu::RuleBasedCollator*
>( icu::Collator::createInstance(icuLocale, status) ) );
401 if (! U_SUCCESS(status)) {
402 OUString message =
"icu::Collator::createInstance() failed: " + OUString::createFromAscii(u_errorName(status));
409 if (options & CollatorOptions::CollatorOptions_IGNORE_CASE_ACCENT)
410 collator->setStrength(icu::Collator::PRIMARY);
411 else if (options & CollatorOptions::CollatorOptions_IGNORE_CASE)
412 collator->setStrength(icu::Collator::SECONDARY);
414 collator->setStrength(icu::Collator::TERTIARY);
432Sequence< 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