LibreOffice Module i18npool (master) 1
localedata.cxx
Go to the documentation of this file.
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#include <memory>
21#include <mutex>
22#include <string_view>
23#include <com/sun/star/beans/PropertyValue.hpp>
24#include <com/sun/star/container/XIndexAccess.hpp>
25#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
29#include <editeng/svxenum.hxx>
30#include <localedata.hxx>
33#include <sal/log.hxx>
34#include <osl/diagnose.h>
35#include <sal/macros.h>
36#include <o3tl/string_view.hxx>
37
38namespace com::sun::star::uno { class XComponentContext; }
39
40using namespace com::sun::star::i18n;
41using namespace com::sun::star::uno;
42using namespace com::sun::star::lang;
43using namespace com::sun::star;
44
45typedef OUString const * (* MyFuncOUString_Type)( sal_Int16&);
46typedef OUString const ** (* MyFunc_Type2)( sal_Int16&, sal_Int16& );
47typedef OUString const *** (* MyFunc_Type3)( sal_Int16&, sal_Int16&, sal_Int16& );
48typedef OUString const * (* MyFunc_FormatCode)( sal_Int16&, sal_Unicode const *&, sal_Unicode const *& );
49
50#ifndef DISABLE_DYNLOADING
51
52static const char *lcl_DATA_EN = "localedata_en";
53static const char *lcl_DATA_ES = "localedata_es";
54static const char *lcl_DATA_EURO = "localedata_euro";
55static const char *lcl_DATA_OTHERS = "localedata_others";
56
57const struct {
58 const char* pLocale;
59 const char* pLib;
60} aLibTable[] = {
61 { "en_US", lcl_DATA_EN },
62 { "en_AU", lcl_DATA_EN },
63 { "en_BZ", lcl_DATA_EN },
64 { "en_CA", lcl_DATA_EN },
65 { "en_GB", lcl_DATA_EN },
66 { "en_IE", lcl_DATA_EN },
67 { "en_JM", lcl_DATA_EN },
68 { "en_NZ", lcl_DATA_EN },
69 { "en_PH", lcl_DATA_EN },
70 { "en_TT", lcl_DATA_EN },
71 { "en_ZA", lcl_DATA_EN },
72 { "en_ZW", lcl_DATA_EN },
73 { "en_NA", lcl_DATA_EN },
74 { "en_GH", lcl_DATA_EN },
75 { "en_MW", lcl_DATA_EN },
76 { "en_GM", lcl_DATA_EN },
77 { "en_BW", lcl_DATA_EN },
78 { "en_ZM", lcl_DATA_EN },
79 { "en_LK", lcl_DATA_EN },
80 { "en_NG", lcl_DATA_EN },
81 { "en_KE", lcl_DATA_EN },
82 { "en_DK", lcl_DATA_EN },
83 { "en_MU", lcl_DATA_EN },
84
85 { "es_ES", lcl_DATA_ES },
86 { "es_AR", lcl_DATA_ES },
87 { "es_BO", lcl_DATA_ES },
88 { "es_CL", lcl_DATA_ES },
89 { "es_CO", lcl_DATA_ES },
90 { "es_CR", lcl_DATA_ES },
91 { "es_DO", lcl_DATA_ES },
92 { "es_EC", lcl_DATA_ES },
93 { "es_GT", lcl_DATA_ES },
94 { "es_HN", lcl_DATA_ES },
95 { "es_MX", lcl_DATA_ES },
96 { "es_NI", lcl_DATA_ES },
97 { "es_PA", lcl_DATA_ES },
98 { "es_PE", lcl_DATA_ES },
99 { "es_PR", lcl_DATA_ES },
100 { "es_PY", lcl_DATA_ES },
101 { "es_SV", lcl_DATA_ES },
102 { "es_UY", lcl_DATA_ES },
103 { "es_VE", lcl_DATA_ES },
104 { "gl_ES", lcl_DATA_ES },
105 { "oc_ES_aranes", lcl_DATA_ES },
106
107 { "de_DE", lcl_DATA_EURO },
108 { "de_AT", lcl_DATA_EURO },
109 { "de_CH", lcl_DATA_EURO },
110 { "de_LI", lcl_DATA_EURO },
111 { "de_LU", lcl_DATA_EURO },
112 { "fr_FR", lcl_DATA_EURO },
113 { "fr_BE", lcl_DATA_EURO },
114 { "fr_CA", lcl_DATA_EURO },
115 { "fr_CH", lcl_DATA_EURO },
116 { "fr_LU", lcl_DATA_EURO },
117 { "fr_MC", lcl_DATA_EURO },
118 { "fr_BF", lcl_DATA_EURO },
119 { "fr_CI", lcl_DATA_EURO },
120 { "fr_ML", lcl_DATA_EURO },
121 { "fr_SN", lcl_DATA_EURO },
122 { "fr_BJ", lcl_DATA_EURO },
123 { "fr_NE", lcl_DATA_EURO },
124 { "fr_TG", lcl_DATA_EURO },
125 { "it_IT", lcl_DATA_EURO },
126 { "it_CH", lcl_DATA_EURO },
127 { "sl_SI", lcl_DATA_EURO },
128 { "sv_SE", lcl_DATA_EURO },
129 { "sv_FI", lcl_DATA_EURO },
130 { "ca_ES", lcl_DATA_EURO },
131 { "ca_ES_valencia", lcl_DATA_EURO },
132 { "cs_CZ", lcl_DATA_EURO },
133 { "sk_SK", lcl_DATA_EURO },
134 { "da_DK", lcl_DATA_EURO },
135 { "el_GR", lcl_DATA_EURO },
136 { "fi_FI", lcl_DATA_EURO },
137 { "is_IS", lcl_DATA_EURO },
138 { "nl_BE", lcl_DATA_EURO },
139 { "nl_NL", lcl_DATA_EURO },
140 { "no_NO", lcl_DATA_EURO },
141 { "nn_NO", lcl_DATA_EURO },
142 { "nb_NO", lcl_DATA_EURO },
143 { "nds_DE", lcl_DATA_EURO },
144 { "pl_PL", lcl_DATA_EURO },
145 { "pt_PT", lcl_DATA_EURO },
146 { "pt_BR", lcl_DATA_EURO }, // needs to be in EURO because inherits from pt_PT
147 { "pt_MZ", lcl_DATA_EURO }, // needs to be in EURO because inherits from pt_PT
148 { "ru_RU", lcl_DATA_EURO },
149 { "tr_TR", lcl_DATA_EURO },
150 { "tt_RU", lcl_DATA_EURO },
151 { "et_EE", lcl_DATA_EURO },
152 { "vro_EE", lcl_DATA_EURO },
153 { "lb_LU", lcl_DATA_EURO },
154 { "lt_LT", lcl_DATA_EURO },
155 { "lv_LV", lcl_DATA_EURO },
156 { "uk_UA", lcl_DATA_EURO },
157 { "ro_RO", lcl_DATA_EURO },
158 { "cy_GB", lcl_DATA_EURO },
159 { "bg_BG", lcl_DATA_EURO },
160 { "sr_Latn_ME", lcl_DATA_EURO },
161 { "sr_Latn_RS", lcl_DATA_EURO },
162 { "sr_Latn_CS", lcl_DATA_EURO },
163 { "sr_ME", lcl_DATA_EURO },
164 { "sr_RS", lcl_DATA_EURO },
165 { "sr_CS", lcl_DATA_EURO },
166 { "hr_HR", lcl_DATA_EURO },
167 { "bs_BA", lcl_DATA_EURO },
168 { "eu_ES", lcl_DATA_EURO },
169 { "fo_FO", lcl_DATA_EURO },
170 { "ga_IE", lcl_DATA_EURO },
171 { "gd_GB", lcl_DATA_EURO },
172 { "ka_GE", lcl_DATA_EURO },
173 { "be_BY", lcl_DATA_EURO },
174 { "kl_GL", lcl_DATA_EURO },
175 { "mk_MK", lcl_DATA_EURO },
176 { "br_FR", lcl_DATA_EURO },
177 { "la_VA", lcl_DATA_EURO },
178 { "cv_RU", lcl_DATA_EURO },
179 { "wa_BE", lcl_DATA_EURO },
180 { "fur_IT", lcl_DATA_EURO },
181 { "gsc_FR", lcl_DATA_EURO },
182 { "fy_NL", lcl_DATA_EURO },
183 { "oc_FR_lengadoc", lcl_DATA_EURO },
184 { "mt_MT", lcl_DATA_EURO },
185 { "sc_IT", lcl_DATA_EURO },
186 { "ast_ES", lcl_DATA_EURO },
187 { "ltg_LV", lcl_DATA_EURO },
188 { "hsb_DE", lcl_DATA_EURO },
189 { "dsb_DE", lcl_DATA_EURO },
190 { "rue_SK", lcl_DATA_EURO },
191 { "an_ES", lcl_DATA_EURO },
192 { "myv_RU", lcl_DATA_EURO },
193 { "lld_IT", lcl_DATA_EURO },
194 { "cu_RU", lcl_DATA_EURO },
195 { "vec_IT", lcl_DATA_EURO },
196 { "szl_PL", lcl_DATA_EURO },
197 { "lij_IT", lcl_DATA_EURO },
198
199 { "ja_JP", lcl_DATA_OTHERS },
200 { "ko_KR", lcl_DATA_OTHERS },
201 { "zh_CN", lcl_DATA_OTHERS },
202 { "zh_HK", lcl_DATA_OTHERS },
203 { "zh_SG", lcl_DATA_OTHERS },
204 { "zh_TW", lcl_DATA_OTHERS },
205 { "zh_MO", lcl_DATA_OTHERS },
206 { "en_HK", lcl_DATA_OTHERS }, // needs to be in OTHERS instead of EN because currency inherited from zh_HK
207
208 { "ar_EG", lcl_DATA_OTHERS },
209 { "ar_DZ", lcl_DATA_OTHERS },
210 { "ar_LB", lcl_DATA_OTHERS },
211 { "ar_SA", lcl_DATA_OTHERS },
212 { "ar_TN", lcl_DATA_OTHERS },
213 { "he_IL", lcl_DATA_OTHERS },
214 { "hi_IN", lcl_DATA_OTHERS },
215 { "kn_IN", lcl_DATA_OTHERS },
216 { "ta_IN", lcl_DATA_OTHERS },
217 { "te_IN", lcl_DATA_OTHERS },
218 { "gu_IN", lcl_DATA_OTHERS },
219 { "mr_IN", lcl_DATA_OTHERS },
220 { "pa_IN", lcl_DATA_OTHERS },
221 { "bn_IN", lcl_DATA_OTHERS },
222 { "or_IN", lcl_DATA_OTHERS },
223 { "en_IN", lcl_DATA_OTHERS }, // keep in OTHERS for IN
224 { "ml_IN", lcl_DATA_OTHERS },
225 { "bn_BD", lcl_DATA_OTHERS },
226 { "th_TH", lcl_DATA_OTHERS },
227
228 { "af_ZA", lcl_DATA_OTHERS },
229 { "hu_HU", lcl_DATA_OTHERS },
230 { "id_ID", lcl_DATA_OTHERS },
231 { "ms_MY", lcl_DATA_OTHERS },
232 { "en_MY", lcl_DATA_OTHERS }, // needs to be in OTHERS instead of EN because currency inherited from ms_MY
233 { "ia", lcl_DATA_OTHERS },
234 { "mn_Cyrl_MN", lcl_DATA_OTHERS },
235 { "az_AZ", lcl_DATA_OTHERS },
236 { "sw_TZ", lcl_DATA_OTHERS },
237 { "km_KH", lcl_DATA_OTHERS },
238 { "lo_LA", lcl_DATA_OTHERS },
239 { "rw_RW", lcl_DATA_OTHERS },
240 { "eo", lcl_DATA_OTHERS },
241 { "dz_BT", lcl_DATA_OTHERS },
242 { "ne_NP", lcl_DATA_OTHERS },
243 { "zu_ZA", lcl_DATA_OTHERS },
244 { "nso_ZA", lcl_DATA_OTHERS },
245 { "vi_VN", lcl_DATA_OTHERS },
246 { "tn_ZA", lcl_DATA_OTHERS },
247 { "xh_ZA", lcl_DATA_OTHERS },
248 { "st_ZA", lcl_DATA_OTHERS },
249 { "ss_ZA", lcl_DATA_OTHERS },
250 { "ve_ZA", lcl_DATA_OTHERS },
251 { "nr_ZA", lcl_DATA_OTHERS },
252 { "ts_ZA", lcl_DATA_OTHERS },
253 { "kmr_Latn_TR", lcl_DATA_OTHERS },
254 { "ak_GH", lcl_DATA_OTHERS },
255 { "af_NA", lcl_DATA_OTHERS },
256 { "am_ET", lcl_DATA_OTHERS },
257 { "ti_ER", lcl_DATA_OTHERS },
258 { "tg_TJ", lcl_DATA_OTHERS },
259 { "ky_KG", lcl_DATA_OTHERS },
260 { "kk_KZ", lcl_DATA_OTHERS },
261 { "fa_IR", lcl_DATA_OTHERS },
262 { "ha_Latn_GH", lcl_DATA_OTHERS },
263 { "ee_GH", lcl_DATA_OTHERS },
264 { "sg_CF", lcl_DATA_OTHERS },
265 { "lg_UG", lcl_DATA_OTHERS },
266 { "uz_UZ", lcl_DATA_OTHERS },
267 { "ln_CD", lcl_DATA_OTHERS },
268 { "hy_AM", lcl_DATA_OTHERS },
269 { "hil_PH", lcl_DATA_OTHERS },
270 { "so_SO", lcl_DATA_OTHERS },
271 { "gug_PY", lcl_DATA_OTHERS },
272 { "tk_TM", lcl_DATA_OTHERS },
273 { "my_MM", lcl_DATA_OTHERS },
274 { "shs_CA", lcl_DATA_OTHERS },
275 { "tpi_PG", lcl_DATA_OTHERS },
276 { "ar_OM", lcl_DATA_OTHERS },
277 { "ug_CN", lcl_DATA_OTHERS },
278 { "om_ET", lcl_DATA_OTHERS },
279 { "plt_MG", lcl_DATA_OTHERS },
280 { "mai_IN", lcl_DATA_OTHERS },
281 { "yi_US", lcl_DATA_OTHERS },
282 { "haw_US", lcl_DATA_OTHERS },
283 { "lif_NP", lcl_DATA_OTHERS },
284 { "ur_PK", lcl_DATA_OTHERS },
285 { "ht_HT", lcl_DATA_OTHERS },
286 { "jbo", lcl_DATA_OTHERS },
287 { "kab_DZ", lcl_DATA_OTHERS },
288 { "pt_AO", lcl_DATA_OTHERS },
289 { "pjt_AU", lcl_DATA_OTHERS },
290 { "pap_BQ", lcl_DATA_OTHERS },
291 { "pap_CW", lcl_DATA_OTHERS },
292 { "ebo_CG", lcl_DATA_OTHERS },
293 { "tyx_CG", lcl_DATA_OTHERS },
294 { "axk_CG", lcl_DATA_OTHERS },
295 { "beq_CG", lcl_DATA_OTHERS },
296 { "bkw_CG", lcl_DATA_OTHERS },
297 { "bvx_CG", lcl_DATA_OTHERS },
298 { "dde_CG", lcl_DATA_OTHERS },
299 { "iyx_CG", lcl_DATA_OTHERS },
300 { "kkw_CG", lcl_DATA_OTHERS },
301 { "kng_CG", lcl_DATA_OTHERS },
302 { "ldi_CG", lcl_DATA_OTHERS },
303 { "mdw_CG", lcl_DATA_OTHERS },
304 { "mkw_CG", lcl_DATA_OTHERS },
305 { "njx_CG", lcl_DATA_OTHERS },
306 { "ngz_CG", lcl_DATA_OTHERS },
307 { "njy_CG", lcl_DATA_OTHERS },
308 { "puu_CG", lcl_DATA_OTHERS },
309 { "sdj_CG", lcl_DATA_OTHERS },
310 { "tek_CG", lcl_DATA_OTHERS },
311 { "tsa_CG", lcl_DATA_OTHERS },
312 { "vif_CG", lcl_DATA_OTHERS },
313 { "xku_CG", lcl_DATA_OTHERS },
314 { "yom_CG", lcl_DATA_OTHERS },
315 { "sid_ET", lcl_DATA_OTHERS },
316 { "bo_CN", lcl_DATA_OTHERS },
317 { "bo_IN", lcl_DATA_OTHERS },
318 { "ar_AE", lcl_DATA_OTHERS },
319 { "ar_KW", lcl_DATA_OTHERS },
320 { "bm_ML", lcl_DATA_OTHERS },
321 { "pui_CO", lcl_DATA_OTHERS },
322 { "lgr_SB", lcl_DATA_OTHERS },
323 { "mos_BF", lcl_DATA_OTHERS },
324 { "ny_MW", lcl_DATA_OTHERS },
325 { "ar_BH", lcl_DATA_OTHERS },
326 { "ar_IQ", lcl_DATA_OTHERS },
327 { "ar_JO", lcl_DATA_OTHERS },
328 { "ar_LY", lcl_DATA_OTHERS },
329 { "ar_MA", lcl_DATA_OTHERS },
330 { "ar_QA", lcl_DATA_OTHERS },
331 { "ar_SY", lcl_DATA_OTHERS },
332 { "ar_YE", lcl_DATA_OTHERS },
333 { "ilo_PH", lcl_DATA_OTHERS },
334 { "ha_Latn_NG", lcl_DATA_OTHERS },
335 { "min_ID", lcl_DATA_OTHERS },
336 { "sun_ID", lcl_DATA_OTHERS },
337 { "en_IL", lcl_DATA_OTHERS }, // needs to be in OTHERS instead of EN because inherits from he_IL
338 { "pdc_US", lcl_DATA_OTHERS },
339 { "dv_MV", lcl_DATA_OTHERS },
340 { "mfe_MU", lcl_DATA_OTHERS },
341 { "sat_IN", lcl_DATA_OTHERS }
343
344#else
345
346#include "localedata_static.hxx"
347
348#endif
349
350const sal_Unicode cUnder = '_';
352
354
355namespace i18npool {
356
357// static
359{
360 return comphelper::containerToSequence<CalendarItem>(rCi);
361}
362
363
364// static
366{
367 Calendar aCal(
368 downcastCalendarItems( rC.Days),
369 downcastCalendarItems( rC.Months),
370 downcastCalendarItems( rC.Eras),
371 rC.StartOfWeek,
372 rC.MinimumNumberOfDaysForFirstWeek,
373 rC.Default,
374 rC.Name
375 );
376 return aCal;
377}
378
379
381{
382}
384{
385}
386
387
388LocaleDataItem SAL_CALL
389LocaleDataImpl::getLocaleItem( const Locale& rLocale )
390{
391 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getLocaleItem" ));
392
393 if ( func ) {
394 sal_Int16 dataItemCount = 0;
395 OUString const *dataItem = func(dataItemCount);
396
397 LocaleDataItem item{
398 dataItem[0],
399 dataItem[1],
400 dataItem[2],
401 dataItem[3],
402 dataItem[4],
403 dataItem[5],
404 dataItem[6],
405 dataItem[7],
406 dataItem[8],
407 dataItem[9],
408 dataItem[10],
409 dataItem[11],
410 dataItem[12],
411 dataItem[13],
412 dataItem[14],
413 dataItem[15],
414 dataItem[16],
415 dataItem[17]
416 };
417 return item;
418 }
419 else {
420 LocaleDataItem item1;
421 return item1;
422 }
423}
424
425
426LocaleDataItem2 SAL_CALL
427LocaleDataImpl::getLocaleItem2( const Locale& rLocale )
428{
429 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getLocaleItem" ));
430
431 if ( func ) {
432 sal_Int16 dataItemCount = 0;
433 OUString const *dataItem = func(dataItemCount);
434
435 assert(dataItemCount >= 18);
436
437 LocaleDataItem2 item{
438 dataItem[0],
439 dataItem[1],
440 dataItem[2],
441 dataItem[3],
442 dataItem[4],
443 dataItem[5],
444 dataItem[6],
445 dataItem[7],
446 dataItem[8],
447 dataItem[9],
448 dataItem[10],
449 dataItem[11],
450 dataItem[12],
451 dataItem[13],
452 dataItem[14],
453 dataItem[15],
454 dataItem[16],
455 dataItem[17],
456 dataItemCount >= 19 ? dataItem[18] : OUString()
457 };
458 return item;
459 }
460 else {
461 LocaleDataItem2 item1;
462 return item1;
463 }
464}
465
466#ifndef DISABLE_DYNLOADING
467
468extern "C" { static void thisModule() {} }
469
470#endif
471
472namespace
473{
474
475// implement the lookup table as a safe static object
476class lcl_LookupTableHelper
477{
478public:
479 lcl_LookupTableHelper();
480 ~lcl_LookupTableHelper();
481
482 oslGenericFunction getFunctionSymbolByName(
483 const OUString& localeName, const char* pFunction,
484 std::optional<LocaleDataLookupTableItem>& rOutCachedItem );
485
486private:
487 std::mutex maMutex;
488 ::std::vector< LocaleDataLookupTableItem > maLookupTable;
489};
490
491// from instance.hxx: Helper base class for a late-initialized
492// (default-constructed) static variable, implementing the double-checked
493// locking pattern correctly.
494// usage: lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get();
495// retrieves the singleton lookup table instance
496lcl_LookupTableHelper& lcl_LookupTableStatic()
497{
498 static lcl_LookupTableHelper SINGLETON;
499 return SINGLETON;
500}
501
502lcl_LookupTableHelper::lcl_LookupTableHelper()
503{
504}
505
506lcl_LookupTableHelper::~lcl_LookupTableHelper()
507{
508 for ( const LocaleDataLookupTableItem& item : maLookupTable ) {
509 delete item.module;
510 }
511}
512
513oslGenericFunction lcl_LookupTableHelper::getFunctionSymbolByName(
514 const OUString& localeName, const char* pFunction,
515 std::optional<LocaleDataLookupTableItem>& rOutCachedItem )
516{
517 OUString aFallback;
518 bool bFallback = (localeName.indexOf( cUnder) < 0);
519 if (bFallback)
520 {
521 Locale aLocale;
522 aLocale.Language = localeName;
523 Locale aFbLocale = MsLangId::getFallbackLocale( aLocale);
524 if (aFbLocale == aLocale)
525 bFallback = false; // may be a "language-only-locale" like Interlingua (ia)
526 else
527 aFallback = LocaleDataImpl::getFirstLocaleServiceName( aFbLocale);
528 }
529
530 for (const auto & i : aLibTable)
531 {
532 if (localeName.equalsAscii(i.pLocale) ||
533 (bFallback && aFallback.equalsAscii(i.pLocale)))
534 {
535#ifndef DISABLE_DYNLOADING
536 {
537 std::unique_lock aGuard( maMutex );
538 for (LocaleDataLookupTableItem & rCurrent : maLookupTable)
539 {
540 if (rCurrent.dllName == i.pLib)
541 {
542 rOutCachedItem.emplace( rCurrent );
543 rOutCachedItem->localeName = i.pLocale;
544 OString sSymbolName = OString::Concat(pFunction) + "_" +
545 rOutCachedItem->localeName;
546 return rOutCachedItem->module->getFunctionSymbol(
547 sSymbolName.getStr());
548 }
549 }
550 }
551 // Library not loaded, load it and add it to the list.
552#ifdef SAL_DLLPREFIX
553 OString sModuleName = // mostly "lib*.so"
554 OString::Concat(SAL_DLLPREFIX) + i.pLib + SAL_DLLEXTENSION;
555#else
556 OString sModuleName = // mostly "*.dll"
557 OString::Concat(i.pLib) + SAL_DLLEXTENSION;
558#endif
559 std::unique_ptr<osl::Module> module(new osl::Module());
560 if ( module->loadRelative(&thisModule, sModuleName.getStr()) )
561 {
562 std::unique_lock aGuard( maMutex );
563 auto pTmpModule = module.get();
564 maLookupTable.emplace_back(i.pLib, module.release(), i.pLocale);
565 rOutCachedItem.emplace( maLookupTable.back() );
566 OString sSymbolName = OString::Concat(pFunction) + "_" + rOutCachedItem->localeName;
567 return pTmpModule->getFunctionSymbol(sSymbolName.getStr());
568 }
569 else
570 module.reset();
571#else
572 (void) rOutCachedItem;
573
574 if( strcmp(pFunction, "getAllCalendars") == 0 )
575 return i.getAllCalendars;
576 else if( strcmp(pFunction, "getAllCurrencies") == 0 )
577 return i.getAllCurrencies;
578 else if( strcmp(pFunction, "getAllFormats0") == 0 )
579 return i.getAllFormats0;
580 else if( strcmp(pFunction, "getBreakIteratorRules") == 0 )
581 return i.getBreakIteratorRules;
582 else if( strcmp(pFunction, "getCollationOptions") == 0 )
583 return i.getCollationOptions;
584 else if( strcmp(pFunction, "getCollatorImplementation") == 0 )
585 return i.getCollatorImplementation;
586 else if( strcmp(pFunction, "getContinuousNumberingLevels") == 0 )
587 return i.getContinuousNumberingLevels;
588 else if( strcmp(pFunction, "getDateAcceptancePatterns") == 0 )
589 return i.getDateAcceptancePatterns;
590 else if( strcmp(pFunction, "getFollowPageWords") == 0 )
591 return i.getFollowPageWords;
592 else if( strcmp(pFunction, "getForbiddenCharacters") == 0 )
593 return i.getForbiddenCharacters;
594 else if( strcmp(pFunction, "getIndexAlgorithm") == 0 )
595 return i.getIndexAlgorithm;
596 else if( strcmp(pFunction, "getLCInfo") == 0 )
597 return i.getLCInfo;
598 else if( strcmp(pFunction, "getLocaleItem") == 0 )
599 return i.getLocaleItem;
600 else if( strcmp(pFunction, "getOutlineNumberingLevels") == 0 )
601 return i.getOutlineNumberingLevels;
602 else if( strcmp(pFunction, "getReservedWords") == 0 )
603 return i.getReservedWords;
604 else if( strcmp(pFunction, "getSearchOptions") == 0 )
605 return i.getSearchOptions;
606 else if( strcmp(pFunction, "getTransliterations") == 0 )
607 return i.getTransliterations;
608 else if( strcmp(pFunction, "getUnicodeScripts") == 0 )
609 return i.getUnicodeScripts;
610 else if( strcmp(pFunction, "getAllFormats1") == 0 )
611 return i.getAllFormats1;
612#endif
613 }
614 }
615 return nullptr;
616}
617
618} // anonymous namespace
619
620
621// REF values equal offsets of counts within getAllCalendars() data structure!
622#define REF_DAYS 0
623#define REF_MONTHS 1
624#define REF_GMONTHS 2
625#define REF_PMONTHS 3
626#define REF_ERAS 4
627#define REF_OFFSET_COUNT 5
628
630 const Locale& rLocale, const Sequence< Calendar2 >& calendarsSeq, sal_Int16 item)
631{
632 if (ref_name != name) {
633 OUString aLocStr, id;
634 sal_Int32 nLastUnder = name.lastIndexOf( cUnder);
635 SAL_WARN_IF( nLastUnder < 1, "i18npool",
636 "LocaleDataImpl::getCalendarItemByName - no '_' or first in name can't be right: " << name);
637 if (nLastUnder >= 0)
638 {
639 aLocStr = name.copy( 0, nLastUnder);
640 if (nLastUnder + 1 < name.getLength())
641 id = name.copy( nLastUnder + 1);
642 }
643 Locale loc( LanguageTag::convertToLocale( aLocStr.replace( cUnder, cHyphen)));
645 if (loc == rLocale) {
646 cals = calendarsSeq;
647 } else {
648 cals = getAllCalendars2(loc);
649 }
650 auto pCal = std::find_if(std::cbegin(cals), std::cend(cals),
651 [&id](const Calendar2& rCal) { return id == rCal.Name; });
652 if (pCal != std::cend(cals))
653 ref_cal = *pCal;
654 else {
655 // Referred locale not found, return name for en_US locale.
656 cals = getAllCalendars2( Locale("en", "US", OUString()) );
657 if (!cals.hasElements())
658 throw RuntimeException();
659 ref_cal = cals.getConstArray()[0];
660 }
661 ref_name = name;
662 }
663 switch (item)
664 {
665 case REF_DAYS:
666 return ref_cal.Days;
667 case REF_MONTHS:
668 return ref_cal.Months;
669 case REF_GMONTHS:
670 return ref_cal.GenitiveMonths;
671 case REF_PMONTHS:
672 return ref_cal.PartitiveMonths;
673 default:
674 OSL_FAIL( "LocaleDataImpl::getCalendarItemByName: unhandled REF_* case");
675 [[fallthrough]];
676 case REF_ERAS:
677 return ref_cal.Eras;
678 }
679}
680
682 OUString const * allCalendars, sal_Int16 & rnOffset,
683 const sal_Int16 nWhichItem, const sal_Int16 nCalendar,
684 const Locale & rLocale, const Sequence< Calendar2 > & calendarsSeq )
685{
687 if ( allCalendars[rnOffset] == std::u16string_view(u"ref") )
688 {
689 aItems = getCalendarItemByName( allCalendars[rnOffset+1], rLocale, calendarsSeq, nWhichItem);
690 rnOffset += 2;
691 }
692 else
693 {
694 const sal_Int32 nSize = allCalendars[nWhichItem][nCalendar];
695 aItems.realloc( nSize);
696 switch (nWhichItem)
697 {
698 case REF_DAYS:
699 case REF_MONTHS:
700 case REF_GMONTHS:
701 case REF_PMONTHS:
702 for (CalendarItem2& rItem : asNonConstRange(aItems))
703 {
704 rItem = CalendarItem2{ allCalendars[rnOffset],
705 allCalendars[rnOffset+1],
706 allCalendars[rnOffset+2], allCalendars[rnOffset+3]};
707 rnOffset += 4;
708 }
709 break;
710 case REF_ERAS:
711 // Absent narrow name.
712 for (CalendarItem2& rItem : asNonConstRange(aItems))
713 {
714 rItem = CalendarItem2{ allCalendars[rnOffset],
715 allCalendars[rnOffset+1],
716 allCalendars[rnOffset+2], OUString()};
717 rnOffset += 3;
718 }
719 break;
720 default:
721 OSL_FAIL( "LocaleDataImpl::getCalendarItems: unhandled REF_* case");
722 }
723 }
724 return aItems;
725}
726
728LocaleDataImpl::getAllCalendars2( const Locale& rLocale )
729{
730
731 OUString const * allCalendars = nullptr;
732
733 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getAllCalendars" ));
734
735 if ( func ) {
736 sal_Int16 calendarsCount = 0;
737 allCalendars = func(calendarsCount);
738
739 Sequence< Calendar2 > calendarsSeq(calendarsCount);
740 auto calendarsSeqRange = asNonConstRange(calendarsSeq);
741 sal_Int16 offset = REF_OFFSET_COUNT;
742 for(sal_Int16 i = 0; i < calendarsCount; i++) {
743 OUString calendarID(allCalendars[offset]);
744 offset++;
745 bool defaultCalendar = allCalendars[offset][0] != 0;
746 offset++;
747 Sequence< CalendarItem2 > days = getCalendarItems( allCalendars, offset, REF_DAYS, i,
748 rLocale, calendarsSeq);
749 Sequence< CalendarItem2 > months = getCalendarItems( allCalendars, offset, REF_MONTHS, i,
750 rLocale, calendarsSeq);
751 Sequence< CalendarItem2 > gmonths = getCalendarItems( allCalendars, offset, REF_GMONTHS, i,
752 rLocale, calendarsSeq);
753 Sequence< CalendarItem2 > pmonths = getCalendarItems( allCalendars, offset, REF_PMONTHS, i,
754 rLocale, calendarsSeq);
755 Sequence< CalendarItem2 > eras = getCalendarItems( allCalendars, offset, REF_ERAS, i,
756 rLocale, calendarsSeq);
757 OUString startOfWeekDay(allCalendars[offset]);
758 offset++;
759 sal_Int16 minimalDaysInFirstWeek = allCalendars[offset][0];
760 offset++;
761 Calendar2 aCalendar(days, months, gmonths, pmonths, eras, startOfWeekDay,
762 minimalDaysInFirstWeek, defaultCalendar, calendarID);
763 calendarsSeqRange[i] = aCalendar;
764 }
765 return calendarsSeq;
766 }
767 else {
768 return {};
769 }
770}
771
772
774LocaleDataImpl::getAllCalendars( const Locale& rLocale )
775{
776 const Sequence< Calendar2 > aCal2( getAllCalendars2( rLocale));
777 std::vector<Calendar> aCal1;
778 aCal1.reserve(aCal2.getLength());
779 std::transform(aCal2.begin(), aCal2.end(), std::back_inserter(aCal1),
780 [](const Calendar2& rCal2) { return downcastCalendar(rCal2); });
782}
783
784
786LocaleDataImpl::getAllCurrencies2( const Locale& rLocale )
787{
788 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getAllCurrencies" ));
789
790 if ( func ) {
791 sal_Int16 currencyCount = 0;
792 OUString const *allCurrencies = func(currencyCount);
793
794 Sequence< Currency2 > seq(currencyCount);
795 auto seqRange = asNonConstRange(seq);
796 for(int i = 0, nOff = 0; i < currencyCount; i++, nOff += 8 ) {
797 seqRange[i] = Currency2(
798 allCurrencies[nOff], // string ID
799 allCurrencies[nOff+1], // string Symbol
800 allCurrencies[nOff+2], // string BankSymbol
801 allCurrencies[nOff+3], // string Name
802 allCurrencies[nOff+4][0] != 0, // boolean Default
803 allCurrencies[nOff+5][0] != 0, // boolean UsedInCompatibleFormatCodes
804 allCurrencies[nOff+6][0], // short DecimalPlaces
805 allCurrencies[nOff+7][0] != 0 // boolean LegacyOnly
806 );
807 }
808 return seq;
809 }
810 else {
811 return {};
812 }
813}
814
815
817LocaleDataImpl::getAllCurrencies( const Locale& rLocale )
818{
819 return comphelper::containerToSequence<Currency>(getAllCurrencies2(rLocale));
820}
821
822
824LocaleDataImpl::getAllFormats( const Locale& rLocale )
825{
826 const int SECTIONS = 2;
827 struct FormatSection
828 {
830 sal_Unicode const *from;
831 sal_Unicode const *to;
832 OUString const *formatArray;
833 sal_Int16 formatCount;
834
835 FormatSection() : func(nullptr), from(nullptr), to(nullptr), formatArray(nullptr), formatCount(0) {}
836 sal_Int16 getFunc( LocaleDataImpl& rLocaleData, const Locale& rL, const char* pName )
837 {
838 func = reinterpret_cast<MyFunc_FormatCode>( rLocaleData.getFunctionSymbol( rL, pName));
839 if (func)
840 formatArray = func( formatCount, from, to);
841 return formatCount;
842 }
843 } section[SECTIONS];
844
845 sal_Int32 formatCount;
846 formatCount = section[0].getFunc( *this, rLocale, "getAllFormats0");
847 formatCount += section[1].getFunc( *this, rLocale, "getAllFormats1");
848
849 Sequence< FormatElement > seq(formatCount);
850 auto seqRange = asNonConstRange(seq);
851 sal_Int32 f = 0;
852 for (const FormatSection & s : section)
853 {
854 OUString const * const formatArray = s.formatArray;
855 if ( formatArray )
856 {
857 for (int i = 0, nOff = 0; i < s.formatCount; ++i, nOff += 7, ++f)
858 {
859 seqRange[f] = FormatElement(
860 formatArray[nOff].replaceAll(s.from, s.to),
861 formatArray[nOff + 1],
862 formatArray[nOff + 2],
863 formatArray[nOff + 3],
864 formatArray[nOff + 4],
865 formatArray[nOff + 5][0],
866 formatArray[nOff + 6][0] != 0);
867 }
868 }
869 }
870 return seq;
871}
872
873
876{
877 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getDateAcceptancePatterns" ));
878
879 if (func)
880 {
881 sal_Int16 patternsCount = 0;
882 OUString const *patternsArray = func( patternsCount );
883 Sequence< OUString > seq( patternsCount );
884 auto seqRange = asNonConstRange(seq);
885 for (sal_Int16 i = 0; i < patternsCount; ++i)
886 {
887 seqRange[i] = patternsArray[i];
888 }
889 return seq;
890 }
891 else
892 {
893 return {};
894 }
895}
896
897
898#define COLLATOR_OFFSET_ALGO 0
899#define COLLATOR_OFFSET_DEFAULT 1
900#define COLLATOR_OFFSET_RULE 2
901#define COLLATOR_ELEMENTS 3
902
903OUString
904LocaleDataImpl::getCollatorRuleByAlgorithm( const Locale& rLocale, std::u16string_view algorithm )
905{
906 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getCollatorImplementation" ));
907 if ( func ) {
908 sal_Int16 collatorCount = 0;
909 OUString const *collatorArray = func(collatorCount);
910 for(sal_Int16 i = 0; i < collatorCount; i++)
911 if (algorithm == collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_ALGO])
912 return collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_RULE];
913 }
914 return OUString();
915}
916
917
920{
921 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getCollatorImplementation" ));
922
923 if ( func ) {
924 sal_Int16 collatorCount = 0;
925 OUString const *collatorArray = func(collatorCount);
926 Sequence< Implementation > seq(collatorCount);
927 auto seqRange = asNonConstRange(seq);
928 for(sal_Int16 i = 0; i < collatorCount; i++) {
929 seqRange[i] = Implementation(
930 collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_ALGO],
931 collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_DEFAULT][0] != 0);
932 }
933 return seq;
934 }
935 else {
936 return {};
937 }
938}
939
942{
943 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getCollationOptions" ));
944
945 if ( func ) {
946 sal_Int16 optionsCount = 0;
947 OUString const *optionsArray = func(optionsCount);
948 Sequence< OUString > seq(optionsCount);
949 auto seqRange = asNonConstRange(seq);
950 for(sal_Int16 i = 0; i < optionsCount; i++) {
951 seqRange[i] = optionsArray[i];
952 }
953 return seq;
954 }
955 else {
956 return {};
957 }
958}
959
961LocaleDataImpl::getSearchOptions( const Locale& rLocale )
962{
963 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getSearchOptions" ));
964
965 if ( func ) {
966 sal_Int16 optionsCount = 0;
967 OUString const *optionsArray = func(optionsCount);
968 return Sequence< OUString >(optionsArray, optionsCount);
969 }
970 else {
971 return {};
972 }
973}
974
975OUString const *
976LocaleDataImpl::getIndexArray(const Locale& rLocale, sal_Int16& indexCount)
977{
978 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getIndexAlgorithm" ));
979
980 if (func)
981 return func(indexCount);
982 return nullptr;
983}
984
986LocaleDataImpl::getIndexAlgorithm( const Locale& rLocale )
987{
988 sal_Int16 indexCount = 0;
989 OUString const *indexArray = getIndexArray(rLocale, indexCount);
990
991 if ( indexArray ) {
992 Sequence< OUString > seq(indexCount);
993 auto seqRange = asNonConstRange(seq);
994 for(sal_Int16 i = 0; i < indexCount; i++) {
995 seqRange[i] = indexArray[i*5];
996 }
997 return seq;
998 }
999 else {
1000 return {};
1001 }
1002}
1003
1004OUString
1006{
1007 sal_Int16 indexCount = 0;
1008 OUString const *indexArray = getIndexArray(rLocale, indexCount);
1009
1010 if ( indexArray ) {
1011 for(sal_Int16 i = 0; i < indexCount; i++) {
1012 if (indexArray[i*5 + 3][0])
1013 return indexArray[i*5];
1014 }
1015 }
1016 return OUString();
1017}
1018
1019bool
1020LocaleDataImpl::hasPhonetic( const Locale& rLocale )
1021{
1022 sal_Int16 indexCount = 0;
1023 OUString const *indexArray = getIndexArray(rLocale, indexCount);
1024
1025 if ( indexArray ) {
1026 for(sal_Int16 i = 0; i < indexCount; i++) {
1027 if (indexArray[i*5 + 4][0])
1028 return true;
1029 }
1030 }
1031 return false;
1032}
1033
1034OUString const *
1035LocaleDataImpl::getIndexArrayForAlgorithm(const Locale& rLocale, std::u16string_view algorithm)
1036{
1037 sal_Int16 indexCount = 0;
1038 OUString const *indexArray = getIndexArray(rLocale, indexCount);
1039 if ( indexArray ) {
1040 for(sal_Int16 i = 0; i < indexCount; i++) {
1041 if (algorithm == indexArray[i*5])
1042 return indexArray+i*5;
1043 }
1044 }
1045 return nullptr;
1046}
1047
1048bool
1049LocaleDataImpl::isPhonetic( const Locale& rLocale, std::u16string_view algorithm )
1050{
1051 OUString const *indexArray = getIndexArrayForAlgorithm(rLocale, algorithm);
1052 return indexArray && indexArray[4][0];
1053}
1054
1055OUString
1056LocaleDataImpl::getIndexKeysByAlgorithm( const Locale& rLocale, std::u16string_view algorithm )
1057{
1058 OUString const *indexArray = getIndexArrayForAlgorithm(rLocale, algorithm);
1059 return indexArray ? (OUString::Concat(u"0-9") + indexArray[2]) : OUString();
1060}
1061
1062OUString
1063LocaleDataImpl::getIndexModuleByAlgorithm( const Locale& rLocale, std::u16string_view algorithm )
1064{
1065 OUString const *indexArray = getIndexArrayForAlgorithm(rLocale, algorithm);
1066 return indexArray ? indexArray[1] : OUString();
1067}
1068
1071{
1072 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getUnicodeScripts" ));
1073
1074 if ( func ) {
1075 sal_Int16 scriptCount = 0;
1076 OUString const *scriptArray = func(scriptCount);
1077 Sequence< UnicodeScript > seq(scriptCount);
1078 auto seqRange = asNonConstRange(seq);
1079 for(sal_Int16 i = 0; i < scriptCount; i++) {
1080 seqRange[i] = UnicodeScript( o3tl::toInt32(scriptArray[i].subView(0, 1)) );
1081 }
1082 return seq;
1083 }
1084 else {
1085 return {};
1086 }
1087}
1088
1091{
1092 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getFollowPageWords" ));
1093
1094 if ( func ) {
1095 sal_Int16 wordCount = 0;
1096 OUString const *wordArray = func(wordCount);
1097 return Sequence< OUString >(wordArray, wordCount);
1098 }
1099 else {
1100 return {};
1101 }
1102}
1103
1104Sequence< OUString > SAL_CALL
1106{
1107 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getTransliterations" ));
1108
1109 if ( func ) {
1110 sal_Int16 transliterationsCount = 0;
1111 const OUString *transliterationsArray = func(transliterationsCount);
1112 return Sequence< OUString >(transliterationsArray, transliterationsCount);
1113 }
1114 else {
1115 return {};
1116 }
1117
1118
1119}
1120
1121
1122LanguageCountryInfo SAL_CALL
1124{
1125 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getLCInfo" ));
1126
1127 if ( func ) {
1128 sal_Int16 LCInfoCount = 0;
1129 OUString const *LCInfoArray = func(LCInfoCount);
1130 LanguageCountryInfo info{LCInfoArray[0],
1131 LCInfoArray[1],
1132 LCInfoArray[2],
1133 LCInfoArray[3],
1134 LCInfoArray[4]};
1135 return info;
1136 }
1137 else {
1138 LanguageCountryInfo info1;
1139 return info1;
1140 }
1141
1142}
1143
1144
1145ForbiddenCharacters SAL_CALL
1147{
1148 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getForbiddenCharacters" ));
1149
1150 if ( func ) {
1151 sal_Int16 LCForbiddenCharactersCount = 0;
1152 OUString const *LCForbiddenCharactersArray = func(LCForbiddenCharactersCount);
1153 assert(LCForbiddenCharactersCount == 3);
1154 ForbiddenCharacters chars{
1155 LCForbiddenCharactersArray[0], LCForbiddenCharactersArray[1]};
1156 return chars;
1157 }
1158 else {
1159 ForbiddenCharacters chars1;
1160 return chars1;
1161 }
1162}
1163
1164OUString
1166{
1167 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getForbiddenCharacters" ));
1168
1169 if ( func ) {
1170 sal_Int16 LCForbiddenCharactersCount = 0;
1171 const OUString *LCForbiddenCharactersArray = func(LCForbiddenCharactersCount);
1172 assert(LCForbiddenCharactersCount == 3);
1173 return LCForbiddenCharactersArray[2];
1174 }
1175
1176 return OUString();
1177}
1178
1181{
1182 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getBreakIteratorRules" ));
1183
1184 if ( func ) {
1185 sal_Int16 LCBreakIteratorRuleCount = 0;
1186 OUString const *LCBreakIteratorRulesArray = func(LCBreakIteratorRuleCount);
1187 return Sequence< OUString >(LCBreakIteratorRulesArray, LCBreakIteratorRuleCount);
1188 }
1189 else {
1190 return {};
1191 }
1192}
1193
1194
1195Sequence< OUString > SAL_CALL
1196LocaleDataImpl::getReservedWord( const Locale& rLocale )
1197{
1198 MyFuncOUString_Type func = reinterpret_cast<MyFuncOUString_Type>(getFunctionSymbol( rLocale, "getReservedWords" ));
1199
1200 if ( func ) {
1201 sal_Int16 LCReservedWordsCount = 0;
1202 OUString const *LCReservedWordsArray = func(LCReservedWordsCount);
1203 return Sequence< OUString >(LCReservedWordsArray, LCReservedWordsCount);
1204 }
1205 else {
1206 return {};
1207 }
1208}
1209
1210
1213{
1214 // load symbol
1215 MyFunc_Type2 func = reinterpret_cast<MyFunc_Type2>(getFunctionSymbol( rLocale, "getContinuousNumberingLevels" ));
1216
1217 if ( func )
1218 {
1219 // invoke function
1220 sal_Int16 nStyles;
1221 sal_Int16 nAttributes;
1222 OUString const ** p0 = func( nStyles, nAttributes );
1223
1224 // allocate memory for nAttributes attributes for each of the nStyles styles.
1226 auto pvRange = asNonConstRange(pv);
1227 for( auto& i : pvRange ) {
1229 }
1230
1231 OUString const ** pStyle = p0;
1232 for( int i=0; i<nStyles; i++ ) {
1233 OUString const * pAttribute = pStyle[i];
1234 auto pvElementRange = asNonConstRange(pvRange[i]);
1235 for( int j=0; j<nAttributes; j++ ) { // prefix, numberingtype, ...
1236 OUString const & pString = pAttribute[j];
1237 beans::PropertyValue& rVal = pvElementRange[j];
1238 OUString sVal;
1239 if( 0 != j && 2 != j )
1240 sVal = pString;
1241 else if( !pString.isEmpty() )
1242 sVal = pString.copy( 0, 1 );
1243
1244 switch( j )
1245 {
1246 case 0:
1247 rVal.Name = "Prefix";
1248 rVal.Value <<= sVal;
1249 break;
1250 case 1:
1251 rVal.Name = "NumberingType";
1252 rVal.Value <<= static_cast<sal_Int16>(sVal.toInt32());
1253 break;
1254 case 2:
1255 rVal.Name = "Suffix";
1256 rVal.Value <<= sVal;
1257 break;
1258 case 3:
1259 rVal.Name = "Transliteration";
1260 rVal.Value <<= sVal;
1261 break;
1262 case 4:
1263 rVal.Name = "NatNum";
1264 rVal.Value <<= static_cast<sal_Int16>(sVal.toInt32());
1265 break;
1266 default:
1267 OSL_ASSERT(false);
1268 }
1269 }
1270 }
1271 return pv;
1272 }
1273
1275}
1276
1277// OutlineNumbering helper class
1278
1279namespace {
1280
1281struct OutlineNumberingLevel_Impl
1282{
1283 OUString sPrefix;
1284 sal_Int16 nNumType; //css::style::NumberingType
1285 OUString sSuffix;
1289 sal_Int32 nLeftMargin;
1292 sal_Int16 nAdjust;
1294 sal_Int32 nNatNum;
1295};
1296
1297class OutlineNumbering : public cppu::WeakImplHelper < container::XIndexAccess >
1298{
1299 // OutlineNumbering helper class
1300
1301 std::unique_ptr<const OutlineNumberingLevel_Impl[]> m_pOutlineLevels;
1302 sal_Int16 m_nCount;
1303public:
1304 OutlineNumbering(std::unique_ptr<const OutlineNumberingLevel_Impl[]> pOutlineLevels, int nLevels);
1305
1306 //XIndexAccess
1307 virtual sal_Int32 SAL_CALL getCount( ) override;
1308 virtual Any SAL_CALL getByIndex( sal_Int32 Index ) override;
1309
1310 //XElementAccess
1311 virtual Type SAL_CALL getElementType( ) override;
1312 virtual sal_Bool SAL_CALL hasElements( ) override;
1313};
1314
1315}
1316
1318LocaleDataImpl::getOutlineNumberingLevels( const lang::Locale& rLocale )
1319{
1320 // load symbol
1321 MyFunc_Type3 func = reinterpret_cast<MyFunc_Type3>(getFunctionSymbol( rLocale, "getOutlineNumberingLevels" ));
1322
1323 if ( func )
1324 {
1325 int i;
1326 // invoke function
1327 sal_Int16 nStyles;
1328 sal_Int16 nLevels;
1329 sal_Int16 nAttributes;
1330 OUString const *** p0 = func( nStyles, nLevels, nAttributes );
1331
1333 auto aRetRange = asNonConstRange(aRet);
1334 OUString const *** pStyle = p0;
1335 for( i=0; i<nStyles; i++ )
1336 {
1337 int j;
1338
1339 std::unique_ptr<OutlineNumberingLevel_Impl[]> level(new OutlineNumberingLevel_Impl[ nLevels+1 ]);
1340 OUString const ** pLevel = pStyle[i];
1341 for( j = 0; j < nLevels; j++ )
1342 {
1343 OUString const * pAttribute = pLevel[j];
1344 for( int k=0; k<nAttributes; k++ )
1345 {
1346 OUString tmp( pAttribute[k] );
1347 switch( k )
1348 {
1349 case 0: level[j].sPrefix = tmp; break;
1350 case 1: level[j].nNumType = sal::static_int_cast<sal_Int16>(tmp.toInt32()); break;
1351 case 2: level[j].sSuffix = tmp; break;
1352 case 3: level[j].cBulletChar = sal::static_int_cast<sal_Unicode>(tmp.toUInt32(16)); break; // base 16
1353 case 4: level[j].sBulletFontName = tmp; break;
1354 case 5: level[j].nParentNumbering = sal::static_int_cast<sal_Int16>(tmp.toInt32()); break;
1355 case 6: level[j].nLeftMargin = tmp.toInt32(); break;
1356 case 7: level[j].nSymbolTextDistance = tmp.toInt32(); break;
1357 case 8: level[j].nFirstLineOffset = tmp.toInt32(); break;
1358 case 9: level[j].nAdjust = sal::static_int_cast<sal_Int16>(tmp.toInt32()); break;
1359 case 10: level[j].sTransliteration = tmp; break;
1360 case 11: level[j].nNatNum = tmp.toInt32(); break;
1361 default:
1362 OSL_ASSERT(false);
1363 }
1364 }
1365 }
1366 level[j].sPrefix.clear();
1367 level[j].nNumType = 0;
1368 level[j].sSuffix.clear();
1369 level[j].nAdjust = 0;
1370 level[j].cBulletChar = 0;
1371 level[j].sBulletFontName.clear();
1372 level[j].nParentNumbering = 0;
1373 level[j].nLeftMargin = 0;
1374 level[j].nSymbolTextDistance = 0;
1375 level[j].nFirstLineOffset = 0;
1376 level[j].sTransliteration.clear();
1377 level[j].nNatNum = 0;
1378 aRetRange[i] = new OutlineNumbering( std::move(level), nLevels );
1379 }
1380 return aRet;
1381 }
1382 else {
1383 return {};
1384 }
1385}
1386
1387// helper functions
1388
1389oslGenericFunction LocaleDataImpl::getFunctionSymbol( const Locale& rLocale, const char* pFunction )
1390{
1391 lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic();
1392
1393 if (moCachedItem && moCachedItem->equals(rLocale))
1394 {
1395 OString sSymbolName = OString::Concat(pFunction) + "_" +
1396 moCachedItem->localeName;
1397 return moCachedItem->module->getFunctionSymbol(sSymbolName.getStr());
1398 }
1399
1400 oslGenericFunction pSymbol = nullptr;
1401 std::optional<LocaleDataLookupTableItem> oCachedItem;
1402
1403 // Load function with name <func>_<lang>_<country> or <func>_<bcp47> and
1404 // fallbacks.
1405 pSymbol = rLookupTable.getFunctionSymbolByName( LocaleDataImpl::getFirstLocaleServiceName( rLocale),
1406 pFunction, oCachedItem);
1407 if (!pSymbol)
1408 {
1409 ::std::vector< OUString > aFallbacks( LocaleDataImpl::getFallbackLocaleServiceNames( rLocale));
1410 for (const auto& rFallback : aFallbacks)
1411 {
1412 pSymbol = rLookupTable.getFunctionSymbolByName(rFallback, pFunction, oCachedItem);
1413 if (pSymbol)
1414 break;
1415 }
1416 }
1417 if (!pSymbol)
1418 {
1419 // load default function with name <func>_en_US
1420 pSymbol = rLookupTable.getFunctionSymbolByName("en_US", pFunction, oCachedItem);
1421 }
1422
1423 if (!pSymbol)
1424 // Appropriate symbol could not be found. Give up.
1425 throw RuntimeException();
1426
1427 if (oCachedItem)
1428 moCachedItem = std::move(oCachedItem);
1429 if (moCachedItem)
1430 moCachedItem->aLocale = rLocale;
1431
1432 return pSymbol;
1433}
1434
1435Sequence< Locale > SAL_CALL
1437{
1439 auto seqRange = asNonConstRange(seq);
1440 sal_Int16 nInstalled = 0;
1441
1442 for(const auto & i : aLibTable) {
1443 OUString name = OUString::createFromAscii( i.pLocale );
1444
1445 // Check if the locale is really available and not just in the table,
1446 // don't allow fall backs.
1447 std::optional<LocaleDataLookupTableItem> oCachedItem;
1448 if (lcl_LookupTableStatic().getFunctionSymbolByName( name, "getLocaleItem", oCachedItem )) {
1449 if( oCachedItem )
1450 moCachedItem = std::move( oCachedItem );
1451 seqRange[nInstalled++] = LanguageTag::convertToLocale( name.replace( cUnder, cHyphen), false);
1452 }
1453 }
1454 if ( nInstalled < nbOfLocales )
1455 seq.realloc( nInstalled ); // reflect reality
1456
1457 return seq;
1458}
1459
1460using namespace ::com::sun::star::container;
1461using namespace ::com::sun::star::beans;
1462
1463OutlineNumbering::OutlineNumbering(std::unique_ptr<const OutlineNumberingLevel_Impl[]> pOutlnLevels, int nLevels) :
1464 m_pOutlineLevels(std::move(pOutlnLevels)),
1465 m_nCount(sal::static_int_cast<sal_Int16>(nLevels))
1466{
1467}
1468
1469sal_Int32 OutlineNumbering::getCount( )
1470{
1471 return m_nCount;
1472}
1473
1474Any OutlineNumbering::getByIndex( sal_Int32 nIndex )
1475{
1476 if(nIndex < 0 || nIndex >= m_nCount)
1477 throw IndexOutOfBoundsException();
1478 const OutlineNumberingLevel_Impl* pTemp = m_pOutlineLevels.get();
1479 pTemp += nIndex;
1480 Any aRet;
1481
1482 Sequence<PropertyValue> aOutlineNumbering(12);
1483 PropertyValue* pValues = aOutlineNumbering.getArray();
1484 pValues[0].Name = "Prefix";
1485 pValues[0].Value <<= pTemp->sPrefix;
1486 pValues[1].Name = "NumberingType";
1487 pValues[1].Value <<= pTemp->nNumType;
1488 pValues[2].Name = "Suffix";
1489 pValues[2].Value <<= pTemp->sSuffix;
1490 pValues[3].Name = "BulletChar";
1491 pValues[3].Value <<= OUString(&pTemp->cBulletChar, 1);
1492 pValues[4].Name = "BulletFontName";
1493 pValues[4].Value <<= pTemp->sBulletFontName;
1494 pValues[5].Name = "ParentNumbering";
1495 pValues[5].Value <<= pTemp->nParentNumbering;
1496 pValues[6].Name = "LeftMargin";
1497 pValues[6].Value <<= pTemp->nLeftMargin;
1498 pValues[7].Name = "SymbolTextDistance";
1499 pValues[7].Value <<= pTemp->nSymbolTextDistance;
1500 pValues[8].Name = "FirstLineOffset";
1501 pValues[8].Value <<= pTemp->nFirstLineOffset;
1502 pValues[9].Name = "Adjust";
1503 pValues[9].Value <<= pTemp->nAdjust;
1504 pValues[10].Name = "Transliteration";
1505 pValues[10].Value <<= pTemp->sTransliteration;
1506 pValues[11].Name = "NatNum";
1507 pValues[11].Value <<= pTemp->nNatNum;
1508 aRet <<= aOutlineNumbering;
1509 return aRet;
1510}
1511
1512Type OutlineNumbering::getElementType( )
1513{
1515}
1516
1517sal_Bool OutlineNumbering::hasElements( )
1518{
1519 return m_nCount > 0;
1520}
1521
1522OUString SAL_CALL
1524{
1525 return "com.sun.star.i18n.LocaleDataImpl";
1526}
1527
1528sal_Bool SAL_CALL LocaleDataImpl::supportsService(const OUString& rServiceName)
1529{
1530 return cppu::supportsService(this, rServiceName);
1531}
1532
1533Sequence< OUString > SAL_CALL
1535{
1537 "com.sun.star.i18n.LocaleData",
1538 "com.sun.star.i18n.LocaleData2"
1539 };
1540 return aRet;
1541}
1542
1543// static
1544OUString LocaleDataImpl::getFirstLocaleServiceName( const css::lang::Locale & rLocale )
1545{
1546 if (rLocale.Language == I18NLANGTAG_QLT)
1547 return rLocale.Variant.replace( cHyphen, cUnder);
1548 else if (!rLocale.Country.isEmpty())
1549 return rLocale.Language + "_" + rLocale.Country;
1550 else
1551 return rLocale.Language;
1552}
1553
1554// static
1555::std::vector< OUString > LocaleDataImpl::getFallbackLocaleServiceNames( const css::lang::Locale & rLocale )
1556{
1557 ::std::vector< OUString > aVec;
1558 if (rLocale.Language == I18NLANGTAG_QLT)
1559 {
1560 aVec = LanguageTag( rLocale).getFallbackStrings( false);
1561 for (auto& rItem : aVec)
1562 {
1563 rItem = rItem.replace(cHyphen, cUnder);
1564 }
1565 }
1566 else if (!rLocale.Country.isEmpty())
1567 {
1568 aVec.push_back( rLocale.Language);
1569 }
1570 // else nothing, language-only was the first
1571 return aVec;
1572}
1573
1574}
1575
1576extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1578 css::uno::XComponentContext *,
1579 css::uno::Sequence<css::uno::Any> const &)
1580{
1581 return cppu::acquire(new i18npool::LocaleDataImpl());
1582}
1583
1584/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const PropertyValue * pValues
const char * pName
UBlockCode from
UBlockCode to
static css::lang::Locale convertToLocale(LanguageType nLangID, bool bResolveSystem=true)
::std::vector< OUString > getFallbackStrings(bool bIncludeFullBcp47) const
static css::lang::Locale getFallbackLocale(const css::lang::Locale &rLocale)
virtual OUString SAL_CALL getImplementationName() override
virtual css::i18n::LanguageCountryInfo SAL_CALL getLanguageCountryInfo(const css::lang::Locale &rLocale) override
virtual css::uno::Sequence< css::i18n::FormatElement > SAL_CALL getAllFormats(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:824
css::uno::Sequence< css::uno::Reference< css::container::XIndexAccess > > getOutlineNumberingLevels(const css::lang::Locale &rLocale)
static css::uno::Sequence< css::i18n::CalendarItem > downcastCalendarItems(const css::uno::Sequence< css::i18n::CalendarItem2 > &rCi)
Definition: localedata.cxx:358
css::uno::Sequence< css::i18n::CalendarItem2 > & getCalendarItemByName(const OUString &name, const css::lang::Locale &rLocale, const css::uno::Sequence< css::i18n::Calendar2 > &calendarsSeq, sal_Int16 item)
Definition: localedata.cxx:629
bool hasPhonetic(const css::lang::Locale &rLocale)
virtual css::uno::Sequence< css::i18n::Currency2 > SAL_CALL getAllCurrencies2(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:786
virtual css::uno::Sequence< OUString > SAL_CALL getDateAcceptancePatterns(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:875
virtual css::uno::Sequence< OUString > SAL_CALL getReservedWord(const css::lang::Locale &rLocale) override
css::i18n::Calendar2 ref_cal
Definition: localedata.hxx:147
virtual ~LocaleDataImpl() override
Definition: localedata.cxx:383
virtual css::uno::Sequence< OUString > SAL_CALL getSearchOptions(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:961
css::uno::Sequence< OUString > getBreakIteratorRules(const css::lang::Locale &rLocale)
virtual css::uno::Sequence< css::i18n::Currency > SAL_CALL getAllCurrencies(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:817
virtual css::i18n::LocaleDataItem SAL_CALL getLocaleItem(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:389
virtual css::uno::Sequence< OUString > SAL_CALL getTransliterations(const css::lang::Locale &rLocale) override
css::uno::Sequence< OUString > getFollowPageWords(const css::lang::Locale &rLocale)
static ::std::vector< OUString > getFallbackLocaleServiceNames(const css::lang::Locale &rLocale)
Generates fallback strings suitable as parts of service names, excluding the one obtained via getFirs...
virtual css::uno::Sequence< css::i18n::Calendar > SAL_CALL getAllCalendars(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:774
virtual css::i18n::LocaleDataItem2 SAL_CALL getLocaleItem2(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:427
css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > getContinuousNumberingLevels(const css::lang::Locale &rLocale)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
OUString getIndexModuleByAlgorithm(const css::lang::Locale &rLocale, std::u16string_view algorithm)
static OUString getFirstLocaleServiceName(const css::lang::Locale &rLocale)
Generates a <Language>_<Country> or <Variant> (if Language=="qlt") string suitable as part of service...
bool isPhonetic(const css::lang::Locale &rLocale, std::u16string_view algorithm)
virtual css::uno::Sequence< OUString > SAL_CALL getCollationOptions(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:941
css::uno::Sequence< css::i18n::UnicodeScript > getUnicodeScripts(const css::lang::Locale &rLocale)
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
OUString const * getIndexArrayForAlgorithm(const css::lang::Locale &rLocale, std::u16string_view rAlgorithm)
css::uno::Sequence< css::i18n::CalendarItem2 > getCalendarItems(OUString const *allCalendars, sal_Int16 &rnOffset, const sal_Int16 nWhichItem, const sal_Int16 nCalendar, const css::lang::Locale &rLocale, const css::uno::Sequence< css::i18n::Calendar2 > &calendarsSeq)
Helper to obtain a sequence of days, months, gmonths or eras.
Definition: localedata.cxx:681
virtual css::uno::Sequence< css::lang::Locale > SAL_CALL getAllInstalledLocaleNames() override
css::uno::Sequence< OUString > getIndexAlgorithm(const css::lang::Locale &rLocale)
Definition: localedata.cxx:986
virtual css::uno::Sequence< css::i18n::Implementation > SAL_CALL getCollatorImplementations(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:919
OUString getHangingCharacters(const css::lang::Locale &rLocale)
OUString getCollatorRuleByAlgorithm(const css::lang::Locale &rLocale, std::u16string_view algorithm)
Definition: localedata.cxx:904
OUString const * getIndexArray(const css::lang::Locale &rLocale, sal_Int16 &indexCount)
Definition: localedata.cxx:976
oslGenericFunction getFunctionSymbol(const css::lang::Locale &rLocale, const char *pFunction)
OUString getDefaultIndexAlgorithm(const css::lang::Locale &rLocale)
virtual css::i18n::ForbiddenCharacters SAL_CALL getForbiddenCharacters(const css::lang::Locale &rLocale) override
virtual css::uno::Sequence< css::i18n::Calendar2 > SAL_CALL getAllCalendars2(const css::lang::Locale &rLocale) override
Definition: localedata.cxx:728
OUString getIndexKeysByAlgorithm(const css::lang::Locale &rLocale, std::u16string_view algorithm)
static css::i18n::Calendar downcastCalendar(const css::i18n::Calendar2 &rC)
Definition: localedata.cxx:365
::std::optional< LocaleDataLookupTableItem > moCachedItem
Definition: localedata.hxx:146
#define SAL_DLLEXTENSION
float u
const char * name
sal_Int32 nIndex
constexpr OUStringLiteral I18NLANGTAG_QLT
sal_Int32 nLeftMargin
sal_Int32 nSymbolTextDistance
std::mutex maMutex
Definition: localedata.cxx:487
static const char * lcl_DATA_OTHERS
Definition: localedata.cxx:55
OUString sTransliteration
const char * pLib
Definition: localedata.cxx:59
const sal_Unicode cUnder
Definition: localedata.cxx:350
sal_Int32 nNatNum
const char * pLocale
Definition: localedata.cxx:58
OUString sSuffix
sal_Int16 nNumType
sal_Int32 nFirstLineOffset
#define REF_PMONTHS
Definition: localedata.cxx:625
OUString const ***(* MyFunc_Type3)(sal_Int16 &, sal_Int16 &, sal_Int16 &)
Definition: localedata.cxx:47
const struct @0 aLibTable[]
#define REF_MONTHS
Definition: localedata.cxx:623
#define REF_DAYS
Definition: localedata.cxx:622
OUString sPrefix
OUString sBulletFontName
const sal_Unicode cHyphen
Definition: localedata.cxx:351
#define REF_OFFSET_COUNT
Definition: localedata.cxx:627
#define COLLATOR_OFFSET_RULE
Definition: localedata.cxx:900
sal_Unicode cBulletChar
OUString const **(* MyFunc_Type2)(sal_Int16 &, sal_Int16 &)
Definition: localedata.cxx:46
sal_Int16 nParentNumbering
std::unique_ptr< const OutlineNumberingLevel_Impl[]> m_pOutlineLevels
#define COLLATOR_ELEMENTS
Definition: localedata.cxx:901
static const char * lcl_DATA_ES
Definition: localedata.cxx:53
#define REF_GMONTHS
Definition: localedata.cxx:624
const sal_Int16 nbOfLocales
Definition: localedata.cxx:353
OUString const *(* MyFuncOUString_Type)(sal_Int16 &)
Definition: localedata.cxx:45
#define REF_ERAS
Definition: localedata.cxx:626
sal_Int16 nAdjust
static const char * lcl_DATA_EURO
Definition: localedata.cxx:54
::std::vector< LocaleDataLookupTableItem > maLookupTable
Definition: localedata.cxx:488
static const char * lcl_DATA_EN
Definition: localedata.cxx:52
#define COLLATOR_OFFSET_DEFAULT
Definition: localedata.cxx:899
sal_Int16 m_nCount
#define COLLATOR_OFFSET_ALGO
Definition: localedata.cxx:898
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_i18n_LocaleDataImpl_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)
OUString const *(* MyFunc_FormatCode)(sal_Int16 &, sal_Unicode const *&, sal_Unicode const *&)
Definition: localedata.cxx:48
#define SAL_WARN_IF(condition, area, stream)
#define SAL_N_ELEMENTS(arr)
@ section
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
Type
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
Constant values shared between i18npool and, for example, the number formatter.
static void thisModule()
Definition: xdictionary.cxx:41
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
module
sal_Int16 nAttributes
unsigned char sal_Bool
sal_uInt16 sal_Unicode