Coverage Report

Created: 2025-11-16 09:57

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