1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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>
26 #include <comphelper/sequence.hxx>
27 #include <cppuhelper/implbase.hxx>
28 #include <cppuhelper/supportsservice.hxx>
29 #include <editeng/svxenum.hxx>
30 #include <localedata.hxx>
31 #include <i18nlangtag/mslangid.hxx>
32 #include <i18nlangtag/languagetag.hxx>
33 #include <sal/log.hxx>
34 #include <osl/diagnose.h>
35 #include <sal/macros.h>
36 #include <o3tl/string_view.hxx>
38 namespace com::sun::star::uno
{ class XComponentContext
; }
40 using namespace com::sun::star::i18n
;
41 using namespace com::sun::star::uno
;
42 using namespace com::sun::star::lang
;
43 using namespace com::sun::star
;
44 using i18npool::DataLocaleLibrary
;
46 typedef OUString
const * (* MyFuncOUString_Type
)( sal_Int16
&);
47 typedef OUString
const ** (* MyFunc_Type2
)( sal_Int16
&, sal_Int16
& );
48 typedef OUString
const *** (* MyFunc_Type3
)( sal_Int16
&, sal_Int16
&, sal_Int16
& );
49 typedef OUString
const * (* MyFunc_FormatCode
)( sal_Int16
&, sal_Unicode
const *&, sal_Unicode
const *& );
51 #ifndef DISABLE_DYNLOADING
55 constexpr const char* lcl_DATA_EN
= SAL_DLLPREFIX
"localedata_en" SAL_DLLEXTENSION
;
56 constexpr const char* lcl_DATA_ES
= SAL_DLLPREFIX
"localedata_es" SAL_DLLEXTENSION
;
57 constexpr const char* lcl_DATA_EURO
= SAL_DLLPREFIX
"localedata_euro" SAL_DLLEXTENSION
;
58 constexpr const char* lcl_DATA_OTHERS
= SAL_DLLPREFIX
"localedata_others" SAL_DLLEXTENSION
;
61 constexpr const char* lcl_DATA_EN
= "localedata_en" SAL_DLLEXTENSION
;
62 constexpr const char* lcl_DATA_ES
= "localedata_es" SAL_DLLEXTENSION
;
63 constexpr const char* lcl_DATA_EURO
= "localedata_euro" SAL_DLLEXTENSION
;
64 constexpr const char* lcl_DATA_OTHERS
= "localedata_others" SAL_DLLEXTENSION
;
67 static const char* getLibraryName(DataLocaleLibrary aLib
) {
69 case DataLocaleLibrary::EN
:
71 case DataLocaleLibrary::ES
:
73 case DataLocaleLibrary::EURO
:
75 case DataLocaleLibrary::OTHERS
:
76 return lcl_DATA_OTHERS
;
83 i18npool::DataLocaleLibrary pLib
;
85 { "en_US", DataLocaleLibrary::EN
},
86 { "en_AU", DataLocaleLibrary::EN
},
87 { "en_BZ", DataLocaleLibrary::EN
},
88 { "en_CA", DataLocaleLibrary::EN
},
89 { "en_GB", DataLocaleLibrary::EN
},
90 { "en_IE", DataLocaleLibrary::EN
},
91 { "en_JM", DataLocaleLibrary::EN
},
92 { "en_NZ", DataLocaleLibrary::EN
},
93 { "en_PH", DataLocaleLibrary::EN
},
94 { "en_TT", DataLocaleLibrary::EN
},
95 { "en_ZA", DataLocaleLibrary::EN
},
96 { "en_ZW", DataLocaleLibrary::EN
},
97 { "en_NA", DataLocaleLibrary::EN
},
98 { "en_GH", DataLocaleLibrary::EN
},
99 { "en_MW", DataLocaleLibrary::EN
},
100 { "en_GM", DataLocaleLibrary::EN
},
101 { "en_BW", DataLocaleLibrary::EN
},
102 { "en_ZM", DataLocaleLibrary::EN
},
103 { "en_LK", DataLocaleLibrary::EN
},
104 { "en_NG", DataLocaleLibrary::EN
},
105 { "en_KE", DataLocaleLibrary::EN
},
106 { "en_DK", DataLocaleLibrary::EN
},
107 { "en_MU", DataLocaleLibrary::EN
},
109 { "es_ES", DataLocaleLibrary::ES
},
110 { "es_AR", DataLocaleLibrary::ES
},
111 { "es_BO", DataLocaleLibrary::ES
},
112 { "es_CL", DataLocaleLibrary::ES
},
113 { "es_CO", DataLocaleLibrary::ES
},
114 { "es_CR", DataLocaleLibrary::ES
},
115 { "es_DO", DataLocaleLibrary::ES
},
116 { "es_EC", DataLocaleLibrary::ES
},
117 { "es_GT", DataLocaleLibrary::ES
},
118 { "es_HN", DataLocaleLibrary::ES
},
119 { "es_MX", DataLocaleLibrary::ES
},
120 { "es_NI", DataLocaleLibrary::ES
},
121 { "es_PA", DataLocaleLibrary::ES
},
122 { "es_PE", DataLocaleLibrary::ES
},
123 { "es_PR", DataLocaleLibrary::ES
},
124 { "es_PY", DataLocaleLibrary::ES
},
125 { "es_SV", DataLocaleLibrary::ES
},
126 { "es_UY", DataLocaleLibrary::ES
},
127 { "es_VE", DataLocaleLibrary::ES
},
128 { "gl_ES", DataLocaleLibrary::ES
},
129 { "oc_ES_aranes", DataLocaleLibrary::ES
},
131 { "de_DE", DataLocaleLibrary::EURO
},
132 { "de_AT", DataLocaleLibrary::EURO
},
133 { "de_CH", DataLocaleLibrary::EURO
},
134 { "de_LI", DataLocaleLibrary::EURO
},
135 { "de_LU", DataLocaleLibrary::EURO
},
136 { "fr_FR", DataLocaleLibrary::EURO
},
137 { "fr_BE", DataLocaleLibrary::EURO
},
138 { "fr_CA", DataLocaleLibrary::EURO
},
139 { "fr_CH", DataLocaleLibrary::EURO
},
140 { "fr_LU", DataLocaleLibrary::EURO
},
141 { "fr_MC", DataLocaleLibrary::EURO
},
142 { "fr_BF", DataLocaleLibrary::EURO
},
143 { "fr_CI", DataLocaleLibrary::EURO
},
144 { "fr_ML", DataLocaleLibrary::EURO
},
145 { "fr_SN", DataLocaleLibrary::EURO
},
146 { "fr_BJ", DataLocaleLibrary::EURO
},
147 { "fr_NE", DataLocaleLibrary::EURO
},
148 { "fr_TG", DataLocaleLibrary::EURO
},
149 { "fr_GN", DataLocaleLibrary::EURO
},
150 { "it_IT", DataLocaleLibrary::EURO
},
151 { "it_CH", DataLocaleLibrary::EURO
},
152 { "sl_SI", DataLocaleLibrary::EURO
},
153 { "sv_SE", DataLocaleLibrary::EURO
},
154 { "sv_FI", DataLocaleLibrary::EURO
},
155 { "ca_ES", DataLocaleLibrary::EURO
},
156 { "ca_ES_valencia", DataLocaleLibrary::EURO
},
157 { "cs_CZ", DataLocaleLibrary::EURO
},
158 { "sk_SK", DataLocaleLibrary::EURO
},
159 { "da_DK", DataLocaleLibrary::EURO
},
160 { "el_GR", DataLocaleLibrary::EURO
},
161 { "fi_FI", DataLocaleLibrary::EURO
},
162 { "is_IS", DataLocaleLibrary::EURO
},
163 { "nl_BE", DataLocaleLibrary::EURO
},
164 { "nl_NL", DataLocaleLibrary::EURO
},
165 { "no_NO", DataLocaleLibrary::EURO
},
166 { "nn_NO", DataLocaleLibrary::EURO
},
167 { "nb_NO", DataLocaleLibrary::EURO
},
168 { "nds_DE", DataLocaleLibrary::EURO
},
169 { "pl_PL", DataLocaleLibrary::EURO
},
170 { "pt_PT", DataLocaleLibrary::EURO
},
171 { "pt_BR", DataLocaleLibrary::EURO
}, // needs to be in EURO because inherits from pt_PT
172 { "pt_MZ", DataLocaleLibrary::EURO
}, // needs to be in EURO because inherits from pt_PT
173 { "ru_RU", DataLocaleLibrary::EURO
},
174 { "tr_TR", DataLocaleLibrary::EURO
},
175 { "tt_RU", DataLocaleLibrary::EURO
},
176 { "et_EE", DataLocaleLibrary::EURO
},
177 { "vro_EE", DataLocaleLibrary::EURO
},
178 { "lb_LU", DataLocaleLibrary::EURO
},
179 { "lt_LT", DataLocaleLibrary::EURO
},
180 { "lv_LV", DataLocaleLibrary::EURO
},
181 { "uk_UA", DataLocaleLibrary::EURO
},
182 { "ro_RO", DataLocaleLibrary::EURO
},
183 { "cy_GB", DataLocaleLibrary::EURO
},
184 { "bg_BG", DataLocaleLibrary::EURO
},
185 { "sr_Latn_ME", DataLocaleLibrary::EURO
},
186 { "sr_Latn_RS", DataLocaleLibrary::EURO
},
187 { "sr_Latn_CS", DataLocaleLibrary::EURO
},
188 { "sr_ME", DataLocaleLibrary::EURO
},
189 { "sr_RS", DataLocaleLibrary::EURO
},
190 { "sr_CS", DataLocaleLibrary::EURO
},
191 { "hr_HR", DataLocaleLibrary::EURO
},
192 { "bs_BA", DataLocaleLibrary::EURO
},
193 { "eu_ES", DataLocaleLibrary::EURO
},
194 { "fo_FO", DataLocaleLibrary::EURO
},
195 { "ga_IE", DataLocaleLibrary::EURO
},
196 { "gd_GB", DataLocaleLibrary::EURO
},
197 { "ka_GE", DataLocaleLibrary::EURO
},
198 { "be_BY", DataLocaleLibrary::EURO
},
199 { "kl_GL", DataLocaleLibrary::EURO
},
200 { "mk_MK", DataLocaleLibrary::EURO
},
201 { "br_FR", DataLocaleLibrary::EURO
},
202 { "la_VA", DataLocaleLibrary::EURO
},
203 { "cv_RU", DataLocaleLibrary::EURO
},
204 { "wa_BE", DataLocaleLibrary::EURO
},
205 { "fur_IT", DataLocaleLibrary::EURO
},
206 { "gsc_FR", DataLocaleLibrary::EURO
},
207 { "fy_NL", DataLocaleLibrary::EURO
},
208 { "oc_FR_lengadoc", DataLocaleLibrary::EURO
},
209 { "mt_MT", DataLocaleLibrary::EURO
},
210 { "sc_IT", DataLocaleLibrary::EURO
},
211 { "ast_ES", DataLocaleLibrary::EURO
},
212 { "ltg_LV", DataLocaleLibrary::EURO
},
213 { "hsb_DE", DataLocaleLibrary::EURO
},
214 { "dsb_DE", DataLocaleLibrary::EURO
},
215 { "rue_SK", DataLocaleLibrary::EURO
},
216 { "an_ES", DataLocaleLibrary::EURO
},
217 { "myv_RU", DataLocaleLibrary::EURO
},
218 { "lld_IT", DataLocaleLibrary::EURO
},
219 { "cu_RU", DataLocaleLibrary::EURO
},
220 { "vec_IT", DataLocaleLibrary::EURO
},
221 { "szl_PL", DataLocaleLibrary::EURO
},
222 { "lij_IT", DataLocaleLibrary::EURO
},
224 { "ja_JP", DataLocaleLibrary::OTHERS
},
225 { "ko_KR", DataLocaleLibrary::OTHERS
},
226 { "zh_CN", DataLocaleLibrary::OTHERS
},
227 { "zh_HK", DataLocaleLibrary::OTHERS
},
228 { "zh_SG", DataLocaleLibrary::OTHERS
},
229 { "zh_TW", DataLocaleLibrary::OTHERS
},
230 { "zh_MO", DataLocaleLibrary::OTHERS
},
231 { "en_HK", DataLocaleLibrary::OTHERS
}, // needs to be in OTHERS instead of EN because currency inherited from zh_HK
233 { "ar_EG", DataLocaleLibrary::OTHERS
},
234 { "ar_DZ", DataLocaleLibrary::OTHERS
},
235 { "ar_LB", DataLocaleLibrary::OTHERS
},
236 { "ar_SA", DataLocaleLibrary::OTHERS
},
237 { "ar_TN", DataLocaleLibrary::OTHERS
},
238 { "he_IL", DataLocaleLibrary::OTHERS
},
239 { "hi_IN", DataLocaleLibrary::OTHERS
},
240 { "kn_IN", DataLocaleLibrary::OTHERS
},
241 { "ta_IN", DataLocaleLibrary::OTHERS
},
242 { "te_IN", DataLocaleLibrary::OTHERS
},
243 { "gu_IN", DataLocaleLibrary::OTHERS
},
244 { "mr_IN", DataLocaleLibrary::OTHERS
},
245 { "pa_IN", DataLocaleLibrary::OTHERS
},
246 { "bn_IN", DataLocaleLibrary::OTHERS
},
247 { "or_IN", DataLocaleLibrary::OTHERS
},
248 { "en_IN", DataLocaleLibrary::OTHERS
}, // keep in OTHERS for IN
249 { "ml_IN", DataLocaleLibrary::OTHERS
},
250 { "bn_BD", DataLocaleLibrary::OTHERS
},
251 { "th_TH", DataLocaleLibrary::OTHERS
},
253 { "af_ZA", DataLocaleLibrary::OTHERS
},
254 { "hu_HU", DataLocaleLibrary::OTHERS
},
255 { "id_ID", DataLocaleLibrary::OTHERS
},
256 { "ms_MY", DataLocaleLibrary::OTHERS
},
257 { "en_MY", DataLocaleLibrary::OTHERS
}, // needs to be in OTHERS instead of EN because currency inherited from ms_MY
258 { "ia", DataLocaleLibrary::OTHERS
},
259 { "mn_Cyrl_MN", DataLocaleLibrary::OTHERS
},
260 { "az_AZ", DataLocaleLibrary::OTHERS
},
261 { "sw_TZ", DataLocaleLibrary::OTHERS
},
262 { "km_KH", DataLocaleLibrary::OTHERS
},
263 { "lo_LA", DataLocaleLibrary::OTHERS
},
264 { "rw_RW", DataLocaleLibrary::OTHERS
},
265 { "eo", DataLocaleLibrary::OTHERS
},
266 { "dz_BT", DataLocaleLibrary::OTHERS
},
267 { "ne_NP", DataLocaleLibrary::OTHERS
},
268 { "zu_ZA", DataLocaleLibrary::OTHERS
},
269 { "nso_ZA", DataLocaleLibrary::OTHERS
},
270 { "vi_VN", DataLocaleLibrary::OTHERS
},
271 { "tn_ZA", DataLocaleLibrary::OTHERS
},
272 { "xh_ZA", DataLocaleLibrary::OTHERS
},
273 { "st_ZA", DataLocaleLibrary::OTHERS
},
274 { "ss_ZA", DataLocaleLibrary::OTHERS
},
275 { "ve_ZA", DataLocaleLibrary::OTHERS
},
276 { "nr_ZA", DataLocaleLibrary::OTHERS
},
277 { "ts_ZA", DataLocaleLibrary::OTHERS
},
278 { "kmr_Latn_TR", DataLocaleLibrary::OTHERS
},
279 { "ak_GH", DataLocaleLibrary::OTHERS
},
280 { "af_NA", DataLocaleLibrary::OTHERS
},
281 { "am_ET", DataLocaleLibrary::OTHERS
},
282 { "ti_ER", DataLocaleLibrary::OTHERS
},
283 { "tg_TJ", DataLocaleLibrary::OTHERS
},
284 { "ky_KG", DataLocaleLibrary::OTHERS
},
285 { "kk_KZ", DataLocaleLibrary::OTHERS
},
286 { "fa_IR", DataLocaleLibrary::OTHERS
},
287 { "ha_Latn_GH", DataLocaleLibrary::OTHERS
},
288 { "ee_GH", DataLocaleLibrary::OTHERS
},
289 { "sg_CF", DataLocaleLibrary::OTHERS
},
290 { "lg_UG", DataLocaleLibrary::OTHERS
},
291 { "uz_UZ", DataLocaleLibrary::OTHERS
},
292 { "ln_CD", DataLocaleLibrary::OTHERS
},
293 { "hy_AM", DataLocaleLibrary::OTHERS
},
294 { "hil_PH", DataLocaleLibrary::OTHERS
},
295 { "so_SO", DataLocaleLibrary::OTHERS
},
296 { "gug_PY", DataLocaleLibrary::OTHERS
},
297 { "tk_TM", DataLocaleLibrary::OTHERS
},
298 { "my_MM", DataLocaleLibrary::OTHERS
},
299 { "shs_CA", DataLocaleLibrary::OTHERS
},
300 { "tpi_PG", DataLocaleLibrary::OTHERS
},
301 { "ar_OM", DataLocaleLibrary::OTHERS
},
302 { "ug_CN", DataLocaleLibrary::OTHERS
},
303 { "om_ET", DataLocaleLibrary::OTHERS
},
304 { "plt_MG", DataLocaleLibrary::OTHERS
},
305 { "mai_IN", DataLocaleLibrary::OTHERS
},
306 { "yi_US", DataLocaleLibrary::OTHERS
},
307 { "haw_US", DataLocaleLibrary::OTHERS
},
308 { "lif_NP", DataLocaleLibrary::OTHERS
},
309 { "ur_PK", DataLocaleLibrary::OTHERS
},
310 { "ht_HT", DataLocaleLibrary::OTHERS
},
311 { "jbo", DataLocaleLibrary::OTHERS
},
312 { "kab_DZ", DataLocaleLibrary::OTHERS
},
313 { "pt_AO", DataLocaleLibrary::OTHERS
},
314 { "pjt_AU", DataLocaleLibrary::OTHERS
},
315 { "pap_BQ", DataLocaleLibrary::OTHERS
},
316 { "pap_CW", DataLocaleLibrary::OTHERS
},
317 { "ebo_CG", DataLocaleLibrary::OTHERS
},
318 { "tyx_CG", DataLocaleLibrary::OTHERS
},
319 { "axk_CG", DataLocaleLibrary::OTHERS
},
320 { "beq_CG", DataLocaleLibrary::OTHERS
},
321 { "bkw_CG", DataLocaleLibrary::OTHERS
},
322 { "bvx_CG", DataLocaleLibrary::OTHERS
},
323 { "dde_CG", DataLocaleLibrary::OTHERS
},
324 { "iyx_CG", DataLocaleLibrary::OTHERS
},
325 { "kkw_CG", DataLocaleLibrary::OTHERS
},
326 { "kng_CG", DataLocaleLibrary::OTHERS
},
327 { "ldi_CG", DataLocaleLibrary::OTHERS
},
328 { "mdw_CG", DataLocaleLibrary::OTHERS
},
329 { "mkw_CG", DataLocaleLibrary::OTHERS
},
330 { "njx_CG", DataLocaleLibrary::OTHERS
},
331 { "ngz_CG", DataLocaleLibrary::OTHERS
},
332 { "njy_CG", DataLocaleLibrary::OTHERS
},
333 { "puu_CG", DataLocaleLibrary::OTHERS
},
334 { "sdj_CG", DataLocaleLibrary::OTHERS
},
335 { "tek_CG", DataLocaleLibrary::OTHERS
},
336 { "tsa_CG", DataLocaleLibrary::OTHERS
},
337 { "vif_CG", DataLocaleLibrary::OTHERS
},
338 { "xku_CG", DataLocaleLibrary::OTHERS
},
339 { "yom_CG", DataLocaleLibrary::OTHERS
},
340 { "sid_ET", DataLocaleLibrary::OTHERS
},
341 { "bo_CN", DataLocaleLibrary::OTHERS
},
342 { "bo_IN", DataLocaleLibrary::OTHERS
},
343 { "ar_AE", DataLocaleLibrary::OTHERS
},
344 { "ar_KW", DataLocaleLibrary::OTHERS
},
345 { "bm_ML", DataLocaleLibrary::OTHERS
},
346 { "pui_CO", DataLocaleLibrary::OTHERS
},
347 { "lgr_SB", DataLocaleLibrary::OTHERS
},
348 { "mos_BF", DataLocaleLibrary::OTHERS
},
349 { "ny_MW", DataLocaleLibrary::OTHERS
},
350 { "ar_BH", DataLocaleLibrary::OTHERS
},
351 { "ar_IQ", DataLocaleLibrary::OTHERS
},
352 { "ar_JO", DataLocaleLibrary::OTHERS
},
353 { "ar_LY", DataLocaleLibrary::OTHERS
},
354 { "ar_MA", DataLocaleLibrary::OTHERS
},
355 { "ar_QA", DataLocaleLibrary::OTHERS
},
356 { "ar_SY", DataLocaleLibrary::OTHERS
},
357 { "ar_YE", DataLocaleLibrary::OTHERS
},
358 { "ilo_PH", DataLocaleLibrary::OTHERS
},
359 { "ha_Latn_NG", DataLocaleLibrary::OTHERS
},
360 { "min_ID", DataLocaleLibrary::OTHERS
},
361 { "sun_ID", DataLocaleLibrary::OTHERS
},
362 { "en_IL", DataLocaleLibrary::OTHERS
}, // needs to be in OTHERS instead of EN because inherits from he_IL
363 { "pdc_US", DataLocaleLibrary::OTHERS
},
364 { "dv_MV", DataLocaleLibrary::OTHERS
},
365 { "mfe_MU", DataLocaleLibrary::OTHERS
},
366 { "sat_IN", DataLocaleLibrary::OTHERS
},
367 { "sat_Olck_IN", DataLocaleLibrary::OTHERS
}
372 #include "localedata_static.hxx"
376 const sal_Unicode cUnder
= '_';
377 const sal_Unicode cHyphen
= '-';
379 const sal_Int16 nbOfLocales
= SAL_N_ELEMENTS(aLibTable
);
384 Sequence
< CalendarItem
> LocaleDataImpl::downcastCalendarItems( const Sequence
< CalendarItem2
> & rCi
)
386 return comphelper::containerToSequence
<CalendarItem
>(rCi
);
391 Calendar
LocaleDataImpl::downcastCalendar( const Calendar2
& rC
)
394 downcastCalendarItems( rC
.Days
),
395 downcastCalendarItems( rC
.Months
),
396 downcastCalendarItems( rC
.Eras
),
398 rC
.MinimumNumberOfDaysForFirstWeek
,
406 LocaleDataImpl::LocaleDataImpl()
409 LocaleDataImpl::~LocaleDataImpl()
414 LocaleDataItem SAL_CALL
415 LocaleDataImpl::getLocaleItem( const Locale
& rLocale
)
417 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getLocaleItem" ));
420 sal_Int16 dataItemCount
= 0;
421 OUString
const *dataItem
= func(dataItemCount
);
446 LocaleDataItem item1
;
452 LocaleDataItem2 SAL_CALL
453 LocaleDataImpl::getLocaleItem2( const Locale
& rLocale
)
455 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getLocaleItem" ));
458 sal_Int16 dataItemCount
= 0;
459 OUString
const *dataItem
= func(dataItemCount
);
461 assert(dataItemCount
>= 18);
463 LocaleDataItem2 item
{
482 dataItemCount
>= 19 ? dataItem
[18] : OUString()
487 LocaleDataItem2 item1
;
492 #ifndef DISABLE_DYNLOADING
494 extern "C" { static void thisModule() {} }
501 // implement the lookup table as a safe static object
502 class lcl_LookupTableHelper
505 lcl_LookupTableHelper();
506 ~lcl_LookupTableHelper();
508 oslGenericFunction
getFunctionSymbolByName(
509 const OUString
& localeName
, const char* pFunction
,
510 std::optional
<LocaleDataLookupTableItem
>& rOutCachedItem
);
514 ::std::vector
< LocaleDataLookupTableItem
> maLookupTable
;
517 // from instance.hxx: Helper base class for a late-initialized
518 // (default-constructed) static variable, implementing the double-checked
519 // locking pattern correctly.
520 // usage: lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get();
521 // retrieves the singleton lookup table instance
522 lcl_LookupTableHelper
& lcl_LookupTableStatic()
524 static lcl_LookupTableHelper SINGLETON
;
528 lcl_LookupTableHelper::lcl_LookupTableHelper()
532 lcl_LookupTableHelper::~lcl_LookupTableHelper()
534 for ( const LocaleDataLookupTableItem
& item
: maLookupTable
) {
539 oslGenericFunction
lcl_LookupTableHelper::getFunctionSymbolByName(
540 const OUString
& localeName
, const char* pFunction
,
541 std::optional
<LocaleDataLookupTableItem
>& rOutCachedItem
)
544 bool bFallback
= (localeName
.indexOf( cUnder
) < 0);
548 aLocale
.Language
= localeName
;
549 Locale aFbLocale
= MsLangId::getFallbackLocale( aLocale
);
550 if (aFbLocale
== aLocale
)
551 bFallback
= false; // may be a "language-only-locale" like Interlingua (ia)
553 aFallback
= LocaleDataImpl::getFirstLocaleServiceName( aFbLocale
);
556 for (const auto & i
: aLibTable
)
558 if (localeName
.equalsAscii(i
.pLocale
) ||
559 (bFallback
&& aFallback
.equalsAscii(i
.pLocale
)))
561 #ifndef DISABLE_DYNLOADING
563 std::unique_lock
aGuard( maMutex
);
564 for (LocaleDataLookupTableItem
& rCurrent
: maLookupTable
)
566 if (rCurrent
.dllName
== i
.pLib
)
568 rOutCachedItem
.emplace( rCurrent
);
569 rOutCachedItem
->localeName
= i
.pLocale
;
570 OString sSymbolName
= OString::Concat(pFunction
) + "_" +
571 rOutCachedItem
->localeName
;
572 return rOutCachedItem
->module
->getFunctionSymbol(
573 sSymbolName
.getStr());
577 // Library not loaded, load it and add it to the list.
578 std::unique_ptr
<osl::Module
> module(new osl::Module());
579 if ( module
->loadRelative(&thisModule
, getLibraryName(i
.pLib
)) )
581 std::unique_lock
aGuard( maMutex
);
582 auto pTmpModule
= module
.get();
583 maLookupTable
.emplace_back(i
.pLib
, module
.release(), i
.pLocale
);
584 rOutCachedItem
.emplace( maLookupTable
.back() );
585 OString sSymbolName
= OString::Concat(pFunction
) + "_" + rOutCachedItem
->localeName
;
586 return pTmpModule
->getFunctionSymbol(sSymbolName
.getStr());
591 (void) rOutCachedItem
;
593 if( strcmp(pFunction
, "getAllCalendars") == 0 )
594 return i
.getAllCalendars
;
595 else if( strcmp(pFunction
, "getAllCurrencies") == 0 )
596 return i
.getAllCurrencies
;
597 else if( strcmp(pFunction
, "getAllFormats0") == 0 )
598 return i
.getAllFormats0
;
599 else if( strcmp(pFunction
, "getBreakIteratorRules") == 0 )
600 return i
.getBreakIteratorRules
;
601 else if( strcmp(pFunction
, "getCollationOptions") == 0 )
602 return i
.getCollationOptions
;
603 else if( strcmp(pFunction
, "getCollatorImplementation") == 0 )
604 return i
.getCollatorImplementation
;
605 else if( strcmp(pFunction
, "getContinuousNumberingLevels") == 0 )
606 return i
.getContinuousNumberingLevels
;
607 else if( strcmp(pFunction
, "getDateAcceptancePatterns") == 0 )
608 return i
.getDateAcceptancePatterns
;
609 else if( strcmp(pFunction
, "getFollowPageWords") == 0 )
610 return i
.getFollowPageWords
;
611 else if( strcmp(pFunction
, "getForbiddenCharacters") == 0 )
612 return i
.getForbiddenCharacters
;
613 else if( strcmp(pFunction
, "getIndexAlgorithm") == 0 )
614 return i
.getIndexAlgorithm
;
615 else if( strcmp(pFunction
, "getLCInfo") == 0 )
617 else if( strcmp(pFunction
, "getLocaleItem") == 0 )
618 return i
.getLocaleItem
;
619 else if( strcmp(pFunction
, "getOutlineNumberingLevels") == 0 )
620 return i
.getOutlineNumberingLevels
;
621 else if( strcmp(pFunction
, "getReservedWords") == 0 )
622 return i
.getReservedWords
;
623 else if( strcmp(pFunction
, "getSearchOptions") == 0 )
624 return i
.getSearchOptions
;
625 else if( strcmp(pFunction
, "getTransliterations") == 0 )
626 return i
.getTransliterations
;
627 else if( strcmp(pFunction
, "getUnicodeScripts") == 0 )
628 return i
.getUnicodeScripts
;
629 else if( strcmp(pFunction
, "getAllFormats1") == 0 )
630 return i
.getAllFormats1
;
637 } // anonymous namespace
640 // REF values equal offsets of counts within getAllCalendars() data structure!
643 #define REF_GMONTHS 2
644 #define REF_PMONTHS 3
646 #define REF_OFFSET_COUNT 5
648 Sequence
< CalendarItem2
> &LocaleDataImpl::getCalendarItemByName(const OUString
& name
,
649 const Locale
& rLocale
, const Sequence
< Calendar2
>& calendarsSeq
, sal_Int16 item
)
651 if (ref_name
!= name
) {
652 OUString aLocStr
, id
;
653 sal_Int32 nLastUnder
= name
.lastIndexOf( cUnder
);
654 SAL_WARN_IF( nLastUnder
< 1, "i18npool",
655 "LocaleDataImpl::getCalendarItemByName - no '_' or first in name can't be right: " << name
);
658 aLocStr
= name
.copy( 0, nLastUnder
);
659 if (nLastUnder
+ 1 < name
.getLength())
660 id
= name
.copy( nLastUnder
+ 1);
662 Locale
loc( LanguageTag::convertToLocale( aLocStr
.replace( cUnder
, cHyphen
)));
663 Sequence
< Calendar2
> cals
;
664 if (loc
== rLocale
) {
667 cals
= getAllCalendars2(loc
);
669 auto pCal
= std::find_if(std::cbegin(cals
), std::cend(cals
),
670 [&id
](const Calendar2
& rCal
) { return id
== rCal
.Name
; });
671 if (pCal
!= std::cend(cals
))
674 // Referred locale not found, return name for en_US locale.
675 cals
= getAllCalendars2( Locale(u
"en"_ustr
, u
"US"_ustr
, OUString()) );
676 if (!cals
.hasElements())
677 throw RuntimeException();
678 ref_cal
= cals
.getConstArray()[0];
687 return ref_cal
.Months
;
689 return ref_cal
.GenitiveMonths
;
691 return ref_cal
.PartitiveMonths
;
693 OSL_FAIL( "LocaleDataImpl::getCalendarItemByName: unhandled REF_* case");
700 Sequence
< CalendarItem2
> LocaleDataImpl::getCalendarItems(
701 OUString
const * allCalendars
, sal_Int16
& rnOffset
,
702 const sal_Int16 nWhichItem
, const sal_Int16 nCalendar
,
703 const Locale
& rLocale
, const Sequence
< Calendar2
> & calendarsSeq
)
705 Sequence
< CalendarItem2
> aItems
;
706 if ( allCalendars
[rnOffset
] == std::u16string_view(u
"ref") )
708 aItems
= getCalendarItemByName( allCalendars
[rnOffset
+1], rLocale
, calendarsSeq
, nWhichItem
);
713 const sal_Int32 nSize
= allCalendars
[nWhichItem
][nCalendar
];
714 aItems
.realloc( nSize
);
721 for (CalendarItem2
& rItem
: asNonConstRange(aItems
))
723 rItem
= CalendarItem2
{ allCalendars
[rnOffset
],
724 allCalendars
[rnOffset
+1],
725 allCalendars
[rnOffset
+2], allCalendars
[rnOffset
+3]};
730 // Absent narrow name.
731 for (CalendarItem2
& rItem
: asNonConstRange(aItems
))
733 rItem
= CalendarItem2
{ allCalendars
[rnOffset
],
734 allCalendars
[rnOffset
+1],
735 allCalendars
[rnOffset
+2], OUString()};
740 OSL_FAIL( "LocaleDataImpl::getCalendarItems: unhandled REF_* case");
746 Sequence
< Calendar2
> SAL_CALL
747 LocaleDataImpl::getAllCalendars2( const Locale
& rLocale
)
750 OUString
const * allCalendars
= nullptr;
752 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getAllCalendars" ));
755 sal_Int16 calendarsCount
= 0;
756 allCalendars
= func(calendarsCount
);
758 Sequence
< Calendar2
> calendarsSeq(calendarsCount
);
759 auto calendarsSeqRange
= asNonConstRange(calendarsSeq
);
760 sal_Int16 offset
= REF_OFFSET_COUNT
;
761 for(sal_Int16 i
= 0; i
< calendarsCount
; i
++) {
762 OUString
calendarID(allCalendars
[offset
]);
764 bool defaultCalendar
= allCalendars
[offset
][0] != 0;
766 Sequence
< CalendarItem2
> days
= getCalendarItems( allCalendars
, offset
, REF_DAYS
, i
,
767 rLocale
, calendarsSeq
);
768 Sequence
< CalendarItem2
> months
= getCalendarItems( allCalendars
, offset
, REF_MONTHS
, i
,
769 rLocale
, calendarsSeq
);
770 Sequence
< CalendarItem2
> gmonths
= getCalendarItems( allCalendars
, offset
, REF_GMONTHS
, i
,
771 rLocale
, calendarsSeq
);
772 Sequence
< CalendarItem2
> pmonths
= getCalendarItems( allCalendars
, offset
, REF_PMONTHS
, i
,
773 rLocale
, calendarsSeq
);
774 Sequence
< CalendarItem2
> eras
= getCalendarItems( allCalendars
, offset
, REF_ERAS
, i
,
775 rLocale
, calendarsSeq
);
776 OUString
startOfWeekDay(allCalendars
[offset
]);
778 sal_Int16 minimalDaysInFirstWeek
= allCalendars
[offset
][0];
780 calendarsSeqRange
[i
] = Calendar2(days
, months
, gmonths
, pmonths
, eras
, startOfWeekDay
,
781 minimalDaysInFirstWeek
, defaultCalendar
, calendarID
);
791 Sequence
< Calendar
> SAL_CALL
792 LocaleDataImpl::getAllCalendars( const Locale
& rLocale
)
794 const Sequence
< Calendar2
> aCal2( getAllCalendars2( rLocale
));
795 std::vector
<Calendar
> aCal1
;
796 aCal1
.reserve(aCal2
.getLength());
797 std::transform(aCal2
.begin(), aCal2
.end(), std::back_inserter(aCal1
),
798 [](const Calendar2
& rCal2
) { return downcastCalendar(rCal2
); });
799 return comphelper::containerToSequence(aCal1
);
803 Sequence
< Currency2
> SAL_CALL
804 LocaleDataImpl::getAllCurrencies2( const Locale
& rLocale
)
806 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getAllCurrencies" ));
809 sal_Int16 currencyCount
= 0;
810 OUString
const *allCurrencies
= func(currencyCount
);
812 Sequence
< Currency2
> seq(currencyCount
);
813 auto seqRange
= asNonConstRange(seq
);
814 for(int i
= 0, nOff
= 0; i
< currencyCount
; i
++, nOff
+= 8 ) {
815 seqRange
[i
] = Currency2(
816 allCurrencies
[nOff
], // string ID
817 allCurrencies
[nOff
+1], // string Symbol
818 allCurrencies
[nOff
+2], // string BankSymbol
819 allCurrencies
[nOff
+3], // string Name
820 allCurrencies
[nOff
+4][0] != 0, // boolean Default
821 allCurrencies
[nOff
+5][0] != 0, // boolean UsedInCompatibleFormatCodes
822 allCurrencies
[nOff
+6][0], // short DecimalPlaces
823 allCurrencies
[nOff
+7][0] != 0 // boolean LegacyOnly
834 Sequence
< Currency
> SAL_CALL
835 LocaleDataImpl::getAllCurrencies( const Locale
& rLocale
)
837 return comphelper::containerToSequence
<Currency
>(getAllCurrencies2(rLocale
));
841 Sequence
< FormatElement
> SAL_CALL
842 LocaleDataImpl::getAllFormats( const Locale
& rLocale
)
844 const int SECTIONS
= 2;
847 MyFunc_FormatCode func
;
848 sal_Unicode
const *from
;
849 sal_Unicode
const *to
;
850 OUString
const *formatArray
;
851 sal_Int16 formatCount
;
853 FormatSection() : func(nullptr), from(nullptr), to(nullptr), formatArray(nullptr), formatCount(0) {}
854 sal_Int16
getFunc( LocaleDataImpl
& rLocaleData
, const Locale
& rL
, const char* pName
)
856 func
= reinterpret_cast<MyFunc_FormatCode
>( rLocaleData
.getFunctionSymbol( rL
, pName
));
858 formatArray
= func( formatCount
, from
, to
);
863 sal_Int32 formatCount
;
864 formatCount
= section
[0].getFunc( *this, rLocale
, "getAllFormats0");
865 formatCount
+= section
[1].getFunc( *this, rLocale
, "getAllFormats1");
867 Sequence
< FormatElement
> seq(formatCount
);
868 auto seqRange
= asNonConstRange(seq
);
870 for (const FormatSection
& s
: section
)
872 OUString
const * const formatArray
= s
.formatArray
;
875 for (int i
= 0, nOff
= 0; i
< s
.formatCount
; ++i
, nOff
+= 7, ++f
)
877 seqRange
[f
] = FormatElement(
878 formatArray
[nOff
].replaceAll(s
.from
, s
.to
),
879 formatArray
[nOff
+ 1],
880 formatArray
[nOff
+ 2],
881 formatArray
[nOff
+ 3],
882 formatArray
[nOff
+ 4],
883 formatArray
[nOff
+ 5][0],
884 formatArray
[nOff
+ 6][0] != 0);
892 Sequence
< OUString
> SAL_CALL
893 LocaleDataImpl::getDateAcceptancePatterns( const Locale
& rLocale
)
895 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getDateAcceptancePatterns" ));
899 sal_Int16 patternsCount
= 0;
900 OUString
const *patternsArray
= func( patternsCount
);
901 Sequence
< OUString
> seq( patternsCount
);
902 auto seqRange
= asNonConstRange(seq
);
903 for (sal_Int16 i
= 0; i
< patternsCount
; ++i
)
905 seqRange
[i
] = patternsArray
[i
];
916 #define COLLATOR_OFFSET_ALGO 0
917 #define COLLATOR_OFFSET_DEFAULT 1
918 #define COLLATOR_OFFSET_RULE 2
919 #define COLLATOR_ELEMENTS 3
922 LocaleDataImpl::getCollatorRuleByAlgorithm( const Locale
& rLocale
, std::u16string_view algorithm
)
924 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getCollatorImplementation" ));
926 sal_Int16 collatorCount
= 0;
927 OUString
const *collatorArray
= func(collatorCount
);
928 for(sal_Int16 i
= 0; i
< collatorCount
; i
++)
929 if (algorithm
== collatorArray
[i
* COLLATOR_ELEMENTS
+ COLLATOR_OFFSET_ALGO
])
930 return collatorArray
[i
* COLLATOR_ELEMENTS
+ COLLATOR_OFFSET_RULE
];
936 Sequence
< Implementation
> SAL_CALL
937 LocaleDataImpl::getCollatorImplementations( const Locale
& rLocale
)
939 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getCollatorImplementation" ));
942 sal_Int16 collatorCount
= 0;
943 OUString
const *collatorArray
= func(collatorCount
);
944 Sequence
< Implementation
> seq(collatorCount
);
945 auto seqRange
= asNonConstRange(seq
);
946 for(sal_Int16 i
= 0; i
< collatorCount
; i
++) {
947 seqRange
[i
] = Implementation(
948 collatorArray
[i
* COLLATOR_ELEMENTS
+ COLLATOR_OFFSET_ALGO
],
949 collatorArray
[i
* COLLATOR_ELEMENTS
+ COLLATOR_OFFSET_DEFAULT
][0] != 0);
958 Sequence
< OUString
> SAL_CALL
959 LocaleDataImpl::getCollationOptions( const Locale
& rLocale
)
961 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getCollationOptions" ));
964 sal_Int16 optionsCount
= 0;
965 OUString
const *optionsArray
= func(optionsCount
);
966 Sequence
< OUString
> seq(optionsCount
);
967 auto seqRange
= asNonConstRange(seq
);
968 for(sal_Int16 i
= 0; i
< optionsCount
; i
++) {
969 seqRange
[i
] = optionsArray
[i
];
978 Sequence
< OUString
> SAL_CALL
979 LocaleDataImpl::getSearchOptions( const Locale
& rLocale
)
981 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getSearchOptions" ));
984 sal_Int16 optionsCount
= 0;
985 OUString
const *optionsArray
= func(optionsCount
);
986 return Sequence
< OUString
>(optionsArray
, optionsCount
);
994 LocaleDataImpl::getIndexArray(const Locale
& rLocale
, sal_Int16
& indexCount
)
996 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getIndexAlgorithm" ));
999 return func(indexCount
);
1003 Sequence
< OUString
>
1004 LocaleDataImpl::getIndexAlgorithm( const Locale
& rLocale
)
1006 sal_Int16 indexCount
= 0;
1007 OUString
const *indexArray
= getIndexArray(rLocale
, indexCount
);
1010 Sequence
< OUString
> seq(indexCount
);
1011 auto seqRange
= asNonConstRange(seq
);
1012 for(sal_Int16 i
= 0; i
< indexCount
; i
++) {
1013 seqRange
[i
] = indexArray
[i
*5];
1023 LocaleDataImpl::getDefaultIndexAlgorithm( const Locale
& rLocale
)
1025 sal_Int16 indexCount
= 0;
1026 OUString
const *indexArray
= getIndexArray(rLocale
, indexCount
);
1029 for(sal_Int16 i
= 0; i
< indexCount
; i
++) {
1030 if (indexArray
[i
*5 + 3][0])
1031 return indexArray
[i
*5];
1038 LocaleDataImpl::hasPhonetic( const Locale
& rLocale
)
1040 sal_Int16 indexCount
= 0;
1041 OUString
const *indexArray
= getIndexArray(rLocale
, indexCount
);
1044 for(sal_Int16 i
= 0; i
< indexCount
; i
++) {
1045 if (indexArray
[i
*5 + 4][0])
1053 LocaleDataImpl::getIndexArrayForAlgorithm(const Locale
& rLocale
, std::u16string_view algorithm
)
1055 sal_Int16 indexCount
= 0;
1056 OUString
const *indexArray
= getIndexArray(rLocale
, indexCount
);
1058 for(sal_Int16 i
= 0; i
< indexCount
; i
++) {
1059 if (algorithm
== indexArray
[i
*5])
1060 return indexArray
+i
*5;
1067 LocaleDataImpl::isPhonetic( const Locale
& rLocale
, std::u16string_view algorithm
)
1069 OUString
const *indexArray
= getIndexArrayForAlgorithm(rLocale
, algorithm
);
1070 return indexArray
&& indexArray
[4][0];
1074 LocaleDataImpl::getIndexKeysByAlgorithm( const Locale
& rLocale
, std::u16string_view algorithm
)
1076 OUString
const *indexArray
= getIndexArrayForAlgorithm(rLocale
, algorithm
);
1077 return indexArray
? (OUString::Concat(u
"0-9") + indexArray
[2]) : OUString();
1081 LocaleDataImpl::getIndexModuleByAlgorithm( const Locale
& rLocale
, std::u16string_view algorithm
)
1083 OUString
const *indexArray
= getIndexArrayForAlgorithm(rLocale
, algorithm
);
1084 return indexArray
? indexArray
[1] : OUString();
1087 Sequence
< UnicodeScript
>
1088 LocaleDataImpl::getUnicodeScripts( const Locale
& rLocale
)
1090 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getUnicodeScripts" ));
1093 sal_Int16 scriptCount
= 0;
1094 OUString
const *scriptArray
= func(scriptCount
);
1095 Sequence
< UnicodeScript
> seq(scriptCount
);
1096 auto seqRange
= asNonConstRange(seq
);
1097 for(sal_Int16 i
= 0; i
< scriptCount
; i
++) {
1098 seqRange
[i
] = UnicodeScript( o3tl::toInt32(scriptArray
[i
].subView(0, 1)) );
1107 Sequence
< OUString
>
1108 LocaleDataImpl::getFollowPageWords( const Locale
& rLocale
)
1110 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getFollowPageWords" ));
1113 sal_Int16 wordCount
= 0;
1114 OUString
const *wordArray
= func(wordCount
);
1115 return Sequence
< OUString
>(wordArray
, wordCount
);
1122 Sequence
< OUString
> SAL_CALL
1123 LocaleDataImpl::getTransliterations( const Locale
& rLocale
)
1125 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getTransliterations" ));
1128 sal_Int16 transliterationsCount
= 0;
1129 const OUString
*transliterationsArray
= func(transliterationsCount
);
1130 return Sequence
< OUString
>(transliterationsArray
, transliterationsCount
);
1140 LanguageCountryInfo SAL_CALL
1141 LocaleDataImpl::getLanguageCountryInfo( const Locale
& rLocale
)
1143 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getLCInfo" ));
1146 sal_Int16 LCInfoCount
= 0;
1147 OUString
const *LCInfoArray
= func(LCInfoCount
);
1148 LanguageCountryInfo info
{LCInfoArray
[0],
1156 LanguageCountryInfo info1
;
1163 ForbiddenCharacters SAL_CALL
1164 LocaleDataImpl::getForbiddenCharacters( const Locale
& rLocale
)
1166 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getForbiddenCharacters" ));
1169 sal_Int16 LCForbiddenCharactersCount
= 0;
1170 OUString
const *LCForbiddenCharactersArray
= func(LCForbiddenCharactersCount
);
1171 assert(LCForbiddenCharactersCount
== 3);
1172 ForbiddenCharacters chars
{
1173 LCForbiddenCharactersArray
[0], LCForbiddenCharactersArray
[1]};
1177 ForbiddenCharacters chars1
;
1183 LocaleDataImpl::getHangingCharacters( const Locale
& rLocale
)
1185 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getForbiddenCharacters" ));
1188 sal_Int16 LCForbiddenCharactersCount
= 0;
1189 const OUString
*LCForbiddenCharactersArray
= func(LCForbiddenCharactersCount
);
1190 assert(LCForbiddenCharactersCount
== 3);
1191 return LCForbiddenCharactersArray
[2];
1197 Sequence
< OUString
>
1198 LocaleDataImpl::getBreakIteratorRules( const Locale
& rLocale
)
1200 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getBreakIteratorRules" ));
1203 sal_Int16 LCBreakIteratorRuleCount
= 0;
1204 OUString
const *LCBreakIteratorRulesArray
= func(LCBreakIteratorRuleCount
);
1205 return Sequence
< OUString
>(LCBreakIteratorRulesArray
, LCBreakIteratorRuleCount
);
1213 Sequence
< OUString
> SAL_CALL
1214 LocaleDataImpl::getReservedWord( const Locale
& rLocale
)
1216 MyFuncOUString_Type func
= reinterpret_cast<MyFuncOUString_Type
>(getFunctionSymbol( rLocale
, "getReservedWords" ));
1219 sal_Int16 LCReservedWordsCount
= 0;
1220 OUString
const *LCReservedWordsArray
= func(LCReservedWordsCount
);
1221 return Sequence
< OUString
>(LCReservedWordsArray
, LCReservedWordsCount
);
1229 Sequence
< Sequence
<beans::PropertyValue
> >
1230 LocaleDataImpl::getContinuousNumberingLevels( const lang::Locale
& rLocale
)
1233 MyFunc_Type2 func
= reinterpret_cast<MyFunc_Type2
>(getFunctionSymbol( rLocale
, "getContinuousNumberingLevels" ));
1239 sal_Int16 nAttributes
;
1240 OUString
const ** p0
= func( nStyles
, nAttributes
);
1242 // allocate memory for nAttributes attributes for each of the nStyles styles.
1243 Sequence
< Sequence
<beans::PropertyValue
> > pv( nStyles
);
1244 auto pvRange
= asNonConstRange(pv
);
1245 for( auto& i
: pvRange
) {
1246 i
= Sequence
<beans::PropertyValue
>( nAttributes
);
1249 OUString
const ** pStyle
= p0
;
1250 for( int i
=0; i
<nStyles
; i
++ ) {
1251 OUString
const * pAttribute
= pStyle
[i
];
1252 auto pvElementRange
= asNonConstRange(pvRange
[i
]);
1253 for( int j
=0; j
<nAttributes
; j
++ ) { // prefix, numberingtype, ...
1254 OUString
const & pString
= pAttribute
[j
];
1255 beans::PropertyValue
& rVal
= pvElementRange
[j
];
1257 if( 0 != j
&& 2 != j
)
1259 else if( !pString
.isEmpty() )
1260 sVal
= pString
.copy( 0, 1 );
1265 rVal
.Name
= "Prefix";
1266 rVal
.Value
<<= sVal
;
1269 rVal
.Name
= "NumberingType";
1270 rVal
.Value
<<= static_cast<sal_Int16
>(sVal
.toInt32());
1273 rVal
.Name
= "Suffix";
1274 rVal
.Value
<<= sVal
;
1277 rVal
.Name
= "Transliteration";
1278 rVal
.Value
<<= sVal
;
1281 rVal
.Name
= "NatNum";
1282 rVal
.Value
<<= static_cast<sal_Int16
>(sVal
.toInt32());
1292 return Sequence
< Sequence
<beans::PropertyValue
> >();
1295 // OutlineNumbering helper class
1299 struct OutlineNumberingLevel_Impl
1302 sal_Int16 nNumType
; //css::style::NumberingType
1304 sal_Unicode cBulletChar
;
1305 OUString sBulletFontName
;
1306 sal_Int16 nParentNumbering
;
1307 sal_Int32 nLeftMargin
;
1308 sal_Int32 nSymbolTextDistance
;
1309 sal_Int32 nFirstLineOffset
;
1311 OUString sTransliteration
;
1315 class OutlineNumbering
: public cppu::WeakImplHelper
< container::XIndexAccess
>
1317 // OutlineNumbering helper class
1319 std::unique_ptr
<const OutlineNumberingLevel_Impl
[]> m_pOutlineLevels
;
1322 OutlineNumbering(std::unique_ptr
<const OutlineNumberingLevel_Impl
[]> pOutlineLevels
, int nLevels
);
1325 virtual sal_Int32 SAL_CALL
getCount( ) override
;
1326 virtual Any SAL_CALL
getByIndex( sal_Int32 Index
) override
;
1329 virtual Type SAL_CALL
getElementType( ) override
;
1330 virtual sal_Bool SAL_CALL
hasElements( ) override
;
1335 Sequence
< Reference
<container::XIndexAccess
> >
1336 LocaleDataImpl::getOutlineNumberingLevels( const lang::Locale
& rLocale
)
1339 MyFunc_Type3 func
= reinterpret_cast<MyFunc_Type3
>(getFunctionSymbol( rLocale
, "getOutlineNumberingLevels" ));
1347 sal_Int16 nAttributes
;
1348 OUString
const *** p0
= func( nStyles
, nLevels
, nAttributes
);
1350 Sequence
< Reference
<container::XIndexAccess
> > aRet( nStyles
);
1351 auto aRetRange
= asNonConstRange(aRet
);
1352 OUString
const *** pStyle
= p0
;
1353 for( i
=0; i
<nStyles
; i
++ )
1357 std::unique_ptr
<OutlineNumberingLevel_Impl
[]> level(new OutlineNumberingLevel_Impl
[ nLevels
+1 ]);
1358 OUString
const ** pLevel
= pStyle
[i
];
1359 for( j
= 0; j
< nLevels
; j
++ )
1361 OUString
const * pAttribute
= pLevel
[j
];
1362 for( int k
=0; k
<nAttributes
; k
++ )
1364 OUString
tmp( pAttribute
[k
] );
1367 case 0: level
[j
].sPrefix
= tmp
; break;
1368 case 1: level
[j
].nNumType
= sal::static_int_cast
<sal_Int16
>(tmp
.toInt32()); break;
1369 case 2: level
[j
].sSuffix
= tmp
; break;
1370 case 3: level
[j
].cBulletChar
= sal::static_int_cast
<sal_Unicode
>(tmp
.toUInt32(16)); break; // base 16
1371 case 4: level
[j
].sBulletFontName
= tmp
; break;
1372 case 5: level
[j
].nParentNumbering
= sal::static_int_cast
<sal_Int16
>(tmp
.toInt32()); break;
1373 case 6: level
[j
].nLeftMargin
= tmp
.toInt32(); break;
1374 case 7: level
[j
].nSymbolTextDistance
= tmp
.toInt32(); break;
1375 case 8: level
[j
].nFirstLineOffset
= tmp
.toInt32(); break;
1376 case 9: level
[j
].nAdjust
= sal::static_int_cast
<sal_Int16
>(tmp
.toInt32()); break;
1377 case 10: level
[j
].sTransliteration
= tmp
; break;
1378 case 11: level
[j
].nNatNum
= tmp
.toInt32(); break;
1384 level
[j
].sPrefix
.clear();
1385 level
[j
].nNumType
= 0;
1386 level
[j
].sSuffix
.clear();
1387 level
[j
].nAdjust
= 0;
1388 level
[j
].cBulletChar
= 0;
1389 level
[j
].sBulletFontName
.clear();
1390 level
[j
].nParentNumbering
= 0;
1391 level
[j
].nLeftMargin
= 0;
1392 level
[j
].nSymbolTextDistance
= 0;
1393 level
[j
].nFirstLineOffset
= 0;
1394 level
[j
].sTransliteration
.clear();
1395 level
[j
].nNatNum
= 0;
1396 aRetRange
[i
] = new OutlineNumbering( std::move(level
), nLevels
);
1407 oslGenericFunction
LocaleDataImpl::getFunctionSymbol( const Locale
& rLocale
, const char* pFunction
)
1409 lcl_LookupTableHelper
& rLookupTable
= lcl_LookupTableStatic();
1411 if (moCachedItem
&& moCachedItem
->equals(rLocale
))
1413 OString sSymbolName
= OString::Concat(pFunction
) + "_" +
1414 moCachedItem
->localeName
;
1415 return moCachedItem
->module
->getFunctionSymbol(sSymbolName
.getStr());
1418 oslGenericFunction pSymbol
= nullptr;
1419 std::optional
<LocaleDataLookupTableItem
> oCachedItem
;
1421 // Load function with name <func>_<lang>_<country> or <func>_<bcp47> and
1423 pSymbol
= rLookupTable
.getFunctionSymbolByName( LocaleDataImpl::getFirstLocaleServiceName( rLocale
),
1424 pFunction
, oCachedItem
);
1427 ::std::vector
< OUString
> aFallbacks( LocaleDataImpl::getFallbackLocaleServiceNames( rLocale
));
1428 for (const auto& rFallback
: aFallbacks
)
1430 pSymbol
= rLookupTable
.getFunctionSymbolByName(rFallback
, pFunction
, oCachedItem
);
1437 // load default function with name <func>_en_US
1438 pSymbol
= rLookupTable
.getFunctionSymbolByName(u
"en_US"_ustr
, pFunction
, oCachedItem
);
1442 // Appropriate symbol could not be found. Give up.
1443 throw RuntimeException();
1446 moCachedItem
= std::move(oCachedItem
);
1448 moCachedItem
->aLocale
= rLocale
;
1453 Sequence
< Locale
> SAL_CALL
1454 LocaleDataImpl::getAllInstalledLocaleNames()
1456 Sequence
< lang::Locale
> seq( nbOfLocales
);
1457 auto seqRange
= asNonConstRange(seq
);
1458 sal_Int16 nInstalled
= 0;
1460 for(const auto & i
: aLibTable
) {
1461 OUString name
= OUString::createFromAscii( i
.pLocale
);
1463 // Check if the locale is really available and not just in the table,
1464 // don't allow fall backs.
1465 std::optional
<LocaleDataLookupTableItem
> oCachedItem
;
1466 if (lcl_LookupTableStatic().getFunctionSymbolByName( name
, "getLocaleItem", oCachedItem
)) {
1468 moCachedItem
= std::move( oCachedItem
);
1469 seqRange
[nInstalled
++] = LanguageTag::convertToLocale( name
.replace( cUnder
, cHyphen
), false);
1472 if ( nInstalled
< nbOfLocales
)
1473 seq
.realloc( nInstalled
); // reflect reality
1478 using namespace ::com::sun::star::container
;
1479 using namespace ::com::sun::star::beans
;
1481 OutlineNumbering::OutlineNumbering(std::unique_ptr
<const OutlineNumberingLevel_Impl
[]> pOutlnLevels
, int nLevels
) :
1482 m_pOutlineLevels(std::move(pOutlnLevels
)),
1483 m_nCount(sal::static_int_cast
<sal_Int16
>(nLevels
))
1487 sal_Int32
OutlineNumbering::getCount( )
1492 Any
OutlineNumbering::getByIndex( sal_Int32 nIndex
)
1494 if(nIndex
< 0 || nIndex
>= m_nCount
)
1495 throw IndexOutOfBoundsException();
1496 const OutlineNumberingLevel_Impl
* pTemp
= m_pOutlineLevels
.get();
1500 Sequence
<PropertyValue
> aOutlineNumbering(12);
1501 PropertyValue
* pValues
= aOutlineNumbering
.getArray();
1502 pValues
[0].Name
= "Prefix";
1503 pValues
[0].Value
<<= pTemp
->sPrefix
;
1504 pValues
[1].Name
= "NumberingType";
1505 pValues
[1].Value
<<= pTemp
->nNumType
;
1506 pValues
[2].Name
= "Suffix";
1507 pValues
[2].Value
<<= pTemp
->sSuffix
;
1508 pValues
[3].Name
= "BulletChar";
1509 pValues
[3].Value
<<= OUString(&pTemp
->cBulletChar
, 1);
1510 pValues
[4].Name
= "BulletFontName";
1511 pValues
[4].Value
<<= pTemp
->sBulletFontName
;
1512 pValues
[5].Name
= "ParentNumbering";
1513 pValues
[5].Value
<<= pTemp
->nParentNumbering
;
1514 pValues
[6].Name
= "LeftMargin";
1515 pValues
[6].Value
<<= pTemp
->nLeftMargin
;
1516 pValues
[7].Name
= "SymbolTextDistance";
1517 pValues
[7].Value
<<= pTemp
->nSymbolTextDistance
;
1518 pValues
[8].Name
= "FirstLineOffset";
1519 pValues
[8].Value
<<= pTemp
->nFirstLineOffset
;
1520 pValues
[9].Name
= "Adjust";
1521 pValues
[9].Value
<<= pTemp
->nAdjust
;
1522 pValues
[10].Name
= "Transliteration";
1523 pValues
[10].Value
<<= pTemp
->sTransliteration
;
1524 pValues
[11].Name
= "NatNum";
1525 pValues
[11].Value
<<= pTemp
->nNatNum
;
1526 aRet
<<= aOutlineNumbering
;
1530 Type
OutlineNumbering::getElementType( )
1532 return cppu::UnoType
<Sequence
<PropertyValue
>>::get();
1535 sal_Bool
OutlineNumbering::hasElements( )
1537 return m_nCount
> 0;
1541 LocaleDataImpl::getImplementationName()
1543 return u
"com.sun.star.i18n.LocaleDataImpl"_ustr
;
1546 sal_Bool SAL_CALL
LocaleDataImpl::supportsService(const OUString
& rServiceName
)
1548 return cppu::supportsService(this, rServiceName
);
1551 Sequence
< OUString
> SAL_CALL
1552 LocaleDataImpl::getSupportedServiceNames()
1554 Sequence
< OUString
> aRet
{
1555 u
"com.sun.star.i18n.LocaleData"_ustr
,
1556 u
"com.sun.star.i18n.LocaleData2"_ustr
1562 OUString
LocaleDataImpl::getFirstLocaleServiceName( const css::lang::Locale
& rLocale
)
1564 if (rLocale
.Language
== I18NLANGTAG_QLT
)
1565 return rLocale
.Variant
.replace( cHyphen
, cUnder
);
1566 else if (!rLocale
.Country
.isEmpty())
1567 return rLocale
.Language
+ "_" + rLocale
.Country
;
1569 return rLocale
.Language
;
1573 ::std::vector
< OUString
> LocaleDataImpl::getFallbackLocaleServiceNames( const css::lang::Locale
& rLocale
)
1575 ::std::vector
< OUString
> aVec
;
1576 if (rLocale
.Language
== I18NLANGTAG_QLT
)
1578 aVec
= LanguageTag( rLocale
).getFallbackStrings( false);
1579 for (auto& rItem
: aVec
)
1581 rItem
= rItem
.replace(cHyphen
, cUnder
);
1584 else if (!rLocale
.Country
.isEmpty())
1586 aVec
.push_back( rLocale
.Language
);
1588 // else nothing, language-only was the first
1594 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1595 com_sun_star_i18n_LocaleDataImpl_get_implementation(
1596 css::uno::XComponentContext
*,
1597 css::uno::Sequence
<css::uno::Any
> const &)
1599 return cppu::acquire(new i18npool::LocaleDataImpl());
1602 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */