Bump version to 4.3-4
[LibreOffice.git] / i18npool / source / localedata / localedata.cxx
blobb3a8dea493331763e995e75cb08d5069968aa59d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #include <cppuhelper/supportsservice.hxx>
21 #include <localedata.hxx>
22 #include <i18nlangtag/mslangid.hxx>
23 #include <i18nlangtag/languagetag.hxx>
24 #include <rtl/ustrbuf.hxx>
25 #include <string.h>
26 #include <stdio.h>
27 #include "rtl/instance.hxx"
28 #include <sal/macros.h>
30 using namespace com::sun::star::i18n;
31 using namespace com::sun::star::uno;
32 using namespace com::sun::star::lang;
33 using namespace com::sun::star;
35 typedef sal_Unicode** (SAL_CALL * MyFunc_Type)( sal_Int16&);
36 typedef sal_Unicode*** (SAL_CALL * MyFunc_Type2)( sal_Int16&, sal_Int16& );
37 typedef sal_Unicode**** (SAL_CALL * MyFunc_Type3)( sal_Int16&, sal_Int16&, sal_Int16& );
38 typedef sal_Unicode const * const * (SAL_CALL * MyFunc_FormatCode)( sal_Int16&, sal_Unicode const *&, sal_Unicode const *& );
40 #ifndef DISABLE_DYNLOADING
42 static const char *lcl_DATA_EN = "localedata_en";
43 static const char *lcl_DATA_ES = "localedata_es";
44 static const char *lcl_DATA_EURO = "localedata_euro";
45 static const char *lcl_DATA_OTHERS = "localedata_others";
47 #endif
49 #ifndef DISABLE_DYNLOADING
51 static const struct {
52 const char* pLocale;
53 const char* pLib;
54 } aLibTable[] = {
55 { "en_US", lcl_DATA_EN },
56 { "en_AU", lcl_DATA_EN },
57 { "en_BZ", lcl_DATA_EN },
58 { "en_CA", lcl_DATA_EN },
59 { "en_GB", lcl_DATA_EN },
60 { "en_IE", lcl_DATA_EN },
61 { "en_JM", lcl_DATA_EN },
62 { "en_NZ", lcl_DATA_EN },
63 { "en_PH", lcl_DATA_EN },
64 { "en_TT", lcl_DATA_EN },
65 { "en_ZA", lcl_DATA_EN },
66 { "en_ZW", lcl_DATA_EN },
67 { "en_NA", lcl_DATA_EN },
68 { "en_GH", lcl_DATA_EN },
69 { "en_MW", lcl_DATA_EN },
71 { "es_ES", lcl_DATA_ES },
72 { "es_AR", lcl_DATA_ES },
73 { "es_BO", lcl_DATA_ES },
74 { "es_CL", lcl_DATA_ES },
75 { "es_CO", lcl_DATA_ES },
76 { "es_CR", lcl_DATA_ES },
77 { "es_DO", lcl_DATA_ES },
78 { "es_EC", lcl_DATA_ES },
79 { "es_GT", lcl_DATA_ES },
80 { "es_HN", lcl_DATA_ES },
81 { "es_MX", lcl_DATA_ES },
82 { "es_NI", lcl_DATA_ES },
83 { "es_PA", lcl_DATA_ES },
84 { "es_PE", lcl_DATA_ES },
85 { "es_PR", lcl_DATA_ES },
86 { "es_PY", lcl_DATA_ES },
87 { "es_SV", lcl_DATA_ES },
88 { "es_UY", lcl_DATA_ES },
89 { "es_VE", lcl_DATA_ES },
90 { "gl_ES", lcl_DATA_ES },
92 { "de_DE", lcl_DATA_EURO },
93 { "de_AT", lcl_DATA_EURO },
94 { "de_CH", lcl_DATA_EURO },
95 { "de_LI", lcl_DATA_EURO },
96 { "de_LU", lcl_DATA_EURO },
97 { "fr_FR", lcl_DATA_EURO },
98 { "fr_BE", lcl_DATA_EURO },
99 { "fr_CA", lcl_DATA_EURO },
100 { "fr_CH", lcl_DATA_EURO },
101 { "fr_LU", lcl_DATA_EURO },
102 { "fr_MC", lcl_DATA_EURO },
103 { "fr_BF", lcl_DATA_EURO },
104 { "fr_CI", lcl_DATA_EURO },
105 { "fr_ML", lcl_DATA_EURO },
106 { "fr_SN", lcl_DATA_EURO },
107 { "fr_BJ", lcl_DATA_EURO },
108 { "fr_NE", lcl_DATA_EURO },
109 { "fr_TG", lcl_DATA_EURO },
110 { "it_IT", lcl_DATA_EURO },
111 { "it_CH", lcl_DATA_EURO },
112 { "sl_SI", lcl_DATA_EURO },
113 { "sv_SE", lcl_DATA_EURO },
114 { "sv_FI", lcl_DATA_EURO },
115 { "ca_ES", lcl_DATA_EURO },
116 { "ca_ES_valencia", lcl_DATA_EURO },
117 { "cs_CZ", lcl_DATA_EURO },
118 { "sk_SK", lcl_DATA_EURO },
119 { "da_DK", lcl_DATA_EURO },
120 { "el_GR", lcl_DATA_EURO },
121 { "fi_FI", lcl_DATA_EURO },
122 { "is_IS", lcl_DATA_EURO },
123 { "nl_BE", lcl_DATA_EURO },
124 { "nl_NL", lcl_DATA_EURO },
125 { "no_NO", lcl_DATA_EURO },
126 { "nn_NO", lcl_DATA_EURO },
127 { "nb_NO", lcl_DATA_EURO },
128 { "nds_DE", lcl_DATA_EURO },
129 { "pl_PL", lcl_DATA_EURO },
130 { "pt_BR", lcl_DATA_EURO },
131 { "pt_PT", lcl_DATA_EURO },
132 { "ru_RU", lcl_DATA_EURO },
133 { "tr_TR", lcl_DATA_EURO },
134 { "tt_RU", lcl_DATA_EURO },
135 { "et_EE", lcl_DATA_EURO },
136 { "lb_LU", lcl_DATA_EURO },
137 { "lt_LT", lcl_DATA_EURO },
138 { "lv_LV", lcl_DATA_EURO },
139 { "uk_UA", lcl_DATA_EURO },
140 { "ro_RO", lcl_DATA_EURO },
141 { "cy_GB", lcl_DATA_EURO },
142 { "bg_BG", lcl_DATA_EURO },
143 { "sr_Latn_ME", lcl_DATA_EURO },
144 { "sr_Latn_RS", lcl_DATA_EURO },
145 { "sr_Latn_CS", lcl_DATA_EURO },
146 { "sr_ME", lcl_DATA_EURO },
147 { "sr_RS", lcl_DATA_EURO },
148 { "sr_CS", lcl_DATA_EURO },
149 { "hr_HR", lcl_DATA_EURO },
150 { "bs_BA", lcl_DATA_EURO },
151 { "eu", lcl_DATA_EURO },
152 { "fo_FO", lcl_DATA_EURO },
153 { "ga_IE", lcl_DATA_EURO },
154 { "gd_GB", lcl_DATA_EURO },
155 { "ka_GE", lcl_DATA_EURO },
156 { "be_BY", lcl_DATA_EURO },
157 { "kl_GL", lcl_DATA_EURO },
158 { "mk_MK", lcl_DATA_EURO },
159 { "br_FR", lcl_DATA_EURO },
160 { "la_VA", lcl_DATA_EURO },
161 { "cv_RU", lcl_DATA_EURO },
162 { "wa_BE", lcl_DATA_EURO },
163 { "fur_IT", lcl_DATA_EURO },
164 { "gsc_FR", lcl_DATA_EURO },
165 { "fy_NL", lcl_DATA_EURO },
166 { "oc_FR", lcl_DATA_EURO },
167 { "mt_MT", lcl_DATA_EURO },
168 { "sc_IT", lcl_DATA_EURO },
169 { "ast_ES", lcl_DATA_EURO },
170 { "ltg_LV", lcl_DATA_EURO },
171 { "hsb_DE", lcl_DATA_EURO },
172 { "dsb_DE", lcl_DATA_EURO },
173 { "rue_SK", lcl_DATA_EURO },
174 { "an_ES", lcl_DATA_EURO },
175 { "myv_RU", lcl_DATA_EURO },
176 { "lld_IT", lcl_DATA_EURO },
178 { "ja_JP", lcl_DATA_OTHERS },
179 { "ko_KR", lcl_DATA_OTHERS },
180 { "zh_CN", lcl_DATA_OTHERS },
181 { "zh_HK", lcl_DATA_OTHERS },
182 { "zh_SG", lcl_DATA_OTHERS },
183 { "zh_TW", lcl_DATA_OTHERS },
184 { "zh_MO", lcl_DATA_OTHERS },
186 { "ar_EG", lcl_DATA_OTHERS },
187 { "ar_DZ", lcl_DATA_OTHERS },
188 { "ar_LB", lcl_DATA_OTHERS },
189 { "ar_SA", lcl_DATA_OTHERS },
190 { "ar_TN", lcl_DATA_OTHERS },
191 { "he_IL", lcl_DATA_OTHERS },
192 { "hi_IN", lcl_DATA_OTHERS },
193 { "kn_IN", lcl_DATA_OTHERS },
194 { "ta_IN", lcl_DATA_OTHERS },
195 { "te_IN", lcl_DATA_OTHERS },
196 { "gu_IN", lcl_DATA_OTHERS },
197 { "mr_IN", lcl_DATA_OTHERS },
198 { "pa_IN", lcl_DATA_OTHERS },
199 { "bn_IN", lcl_DATA_OTHERS },
200 { "or_IN", lcl_DATA_OTHERS },
201 { "en_IN", lcl_DATA_OTHERS },
202 { "ml_IN", lcl_DATA_OTHERS },
203 { "bn_BD", lcl_DATA_OTHERS },
204 { "th_TH", lcl_DATA_OTHERS },
206 { "af_ZA", lcl_DATA_OTHERS },
207 { "hu_HU", lcl_DATA_OTHERS },
208 { "id_ID", lcl_DATA_OTHERS },
209 { "ms_MY", lcl_DATA_OTHERS },
210 { "ia", lcl_DATA_OTHERS },
211 { "mn_Cyrl_MN", lcl_DATA_OTHERS },
212 { "az_AZ", lcl_DATA_OTHERS },
213 { "sw_TZ", lcl_DATA_OTHERS },
214 { "km_KH", lcl_DATA_OTHERS },
215 { "lo_LA", lcl_DATA_OTHERS },
216 { "rw_RW", lcl_DATA_OTHERS },
217 { "eo", lcl_DATA_OTHERS },
218 { "dz_BT", lcl_DATA_OTHERS },
219 { "ne_NP", lcl_DATA_OTHERS },
220 { "zu_ZA", lcl_DATA_OTHERS },
221 { "nso_ZA", lcl_DATA_OTHERS },
222 { "vi_VN", lcl_DATA_OTHERS },
223 { "tn_ZA", lcl_DATA_OTHERS },
224 { "xh_ZA", lcl_DATA_OTHERS },
225 { "st_ZA", lcl_DATA_OTHERS },
226 { "ss_ZA", lcl_DATA_OTHERS },
227 { "ve_ZA", lcl_DATA_OTHERS },
228 { "nr_ZA", lcl_DATA_OTHERS },
229 { "ts_ZA", lcl_DATA_OTHERS },
230 { "kmr_Latn_TR", lcl_DATA_OTHERS },
231 { "ak_GH", lcl_DATA_OTHERS },
232 { "af_NA", lcl_DATA_OTHERS },
233 { "am_ET", lcl_DATA_OTHERS },
234 { "ti_ER", lcl_DATA_OTHERS },
235 { "tg_TJ", lcl_DATA_OTHERS },
236 { "ky_KG", lcl_DATA_OTHERS },
237 { "kk_KZ", lcl_DATA_OTHERS },
238 { "fa_IR", lcl_DATA_OTHERS },
239 { "ha_Latn_GH", lcl_DATA_OTHERS },
240 { "ee_GH", lcl_DATA_OTHERS },
241 { "sg_CF", lcl_DATA_OTHERS },
242 { "lg_UG", lcl_DATA_OTHERS },
243 { "uz_UZ", lcl_DATA_OTHERS },
244 { "ln_CD", lcl_DATA_OTHERS },
245 { "hy_AM", lcl_DATA_OTHERS },
246 { "hil_PH", lcl_DATA_OTHERS },
247 { "so_SO", lcl_DATA_OTHERS },
248 { "gug_PY", lcl_DATA_OTHERS },
249 { "tk_TM", lcl_DATA_OTHERS },
250 { "my_MM", lcl_DATA_OTHERS },
251 { "shs_CA", lcl_DATA_OTHERS },
252 { "tpi_PG", lcl_DATA_OTHERS },
253 { "ar_OM", lcl_DATA_OTHERS },
254 { "ug_CN", lcl_DATA_OTHERS },
255 { "om_ET", lcl_DATA_OTHERS },
256 { "plt_MG", lcl_DATA_OTHERS },
257 { "mai_IN", lcl_DATA_OTHERS },
258 { "yi_US", lcl_DATA_OTHERS },
259 { "haw_US", lcl_DATA_OTHERS },
260 { "lif_NP", lcl_DATA_OTHERS },
261 { "ur_PK", lcl_DATA_OTHERS },
262 { "ht_HT", lcl_DATA_OTHERS },
263 { "jbo", lcl_DATA_OTHERS },
264 { "kab_DZ", lcl_DATA_OTHERS },
265 { "pt_AO", lcl_DATA_OTHERS },
266 { "pjt_AU", lcl_DATA_OTHERS },
267 { "pap_CW", lcl_DATA_OTHERS },
268 { "ebo_CG", lcl_DATA_OTHERS },
269 { "tyx_CG", lcl_DATA_OTHERS },
270 { "axk_CG", lcl_DATA_OTHERS },
271 { "beq_CG", lcl_DATA_OTHERS },
272 { "bkw_CG", lcl_DATA_OTHERS },
273 { "bvx_CG", lcl_DATA_OTHERS },
274 { "dde_CG", lcl_DATA_OTHERS },
275 { "iyx_CG", lcl_DATA_OTHERS },
276 { "kkw_CG", lcl_DATA_OTHERS },
277 { "kng_CG", lcl_DATA_OTHERS },
278 { "ldi_CG", lcl_DATA_OTHERS },
279 { "mdw_CG", lcl_DATA_OTHERS },
280 { "mkw_CG", lcl_DATA_OTHERS },
281 { "njx_CG", lcl_DATA_OTHERS },
282 { "ngz_CG", lcl_DATA_OTHERS },
283 { "njy_CG", lcl_DATA_OTHERS },
284 { "puu_CG", lcl_DATA_OTHERS },
285 { "sdj_CG", lcl_DATA_OTHERS },
286 { "tek_CG", lcl_DATA_OTHERS },
287 { "tsa_CG", lcl_DATA_OTHERS },
288 { "vif_CG", lcl_DATA_OTHERS },
289 { "xku_CG", lcl_DATA_OTHERS },
290 { "yom_CG", lcl_DATA_OTHERS },
291 { "sid_ET", lcl_DATA_OTHERS },
292 { "bo_CN", lcl_DATA_OTHERS },
293 { "bo_IN", lcl_DATA_OTHERS },
294 { "ar_AE", lcl_DATA_OTHERS },
295 { "ar_KW", lcl_DATA_OTHERS },
296 { "bm_ML", lcl_DATA_OTHERS },
297 { "pui_CO", lcl_DATA_OTHERS },
298 { "lgr_SB", lcl_DATA_OTHERS },
299 { "mos_BF", lcl_DATA_OTHERS }
302 #else
304 #include "localedata_static.hxx"
306 #endif
308 static const sal_Unicode cUnder = '_';
309 static const sal_Unicode cHyphen = '-';
311 static const sal_Int16 nbOfLocales = SAL_N_ELEMENTS(aLibTable);
313 struct LocaleDataLookupTableItem
315 LocaleDataLookupTableItem(const sal_Char *name, osl::Module* m, const sal_Char* lname) : dllName(name), module(m), localeName(lname)
318 const sal_Char* dllName;
319 osl::Module *module;
320 const sal_Char* localeName;
322 com::sun::star::lang::Locale aLocale;
323 bool equals(const com::sun::star::lang::Locale& rLocale)
325 return (rLocale == aLocale);
330 // static
331 Sequence< CalendarItem > LocaleDataImpl::downcastCalendarItems( const Sequence< CalendarItem2 > & rCi )
333 sal_Int32 nSize = rCi.getLength();
334 Sequence< CalendarItem > aCi( nSize);
335 CalendarItem* p1 = aCi.getArray();
336 const CalendarItem2* p2 = rCi.getConstArray();
337 for (sal_Int32 i=0; i < nSize; ++i, ++p1, ++p2)
338 *p1 = *p2;
339 return aCi;
343 // static
344 Calendar LocaleDataImpl::downcastCalendar( const Calendar2 & rC )
346 Calendar aCal(
347 downcastCalendarItems( rC.Days),
348 downcastCalendarItems( rC.Months),
349 downcastCalendarItems( rC.Eras),
350 rC.StartOfWeek,
351 rC.MinimumNumberOfDaysForFirstWeek,
352 rC.Default,
353 rC.Name
355 return aCal;
359 LocaleDataImpl::LocaleDataImpl()
362 LocaleDataImpl::~LocaleDataImpl()
367 LocaleDataItem SAL_CALL
368 LocaleDataImpl::getLocaleItem( const Locale& rLocale ) throw(RuntimeException, std::exception)
370 sal_Unicode **dataItem = NULL;
372 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getLocaleItem" );
374 if ( func ) {
375 sal_Int16 dataItemCount = 0;
376 dataItem = func(dataItemCount);
378 LocaleDataItem item(
379 dataItem[0],
380 dataItem[1],
381 dataItem[2],
382 dataItem[3],
383 dataItem[4],
384 dataItem[5],
385 dataItem[6],
386 dataItem[7],
387 dataItem[8],
388 dataItem[9],
389 dataItem[10],
390 dataItem[11],
391 dataItem[12],
392 dataItem[13],
393 dataItem[14],
394 dataItem[15],
395 dataItem[16],
396 dataItem[17]
398 return item;
400 else {
401 LocaleDataItem item1;
402 return item1;
406 #ifndef DISABLE_DYNLOADING
408 extern "C" { static void SAL_CALL thisModule() {} }
410 #endif
412 namespace
415 // implement the lookup table as a safe static object
416 class lcl_LookupTableHelper
418 public:
419 lcl_LookupTableHelper();
420 ~lcl_LookupTableHelper();
422 oslGenericFunction SAL_CALL getFunctionSymbolByName(
423 const OUString& localeName, const sal_Char* pFunction,
424 LocaleDataLookupTableItem** pOutCachedItem );
426 private:
427 ::osl::Mutex maMutex;
428 ::std::vector< LocaleDataLookupTableItem* > maLookupTable;
431 // from instance.hxx: Helper base class for a late-initialized
432 // (default-constructed) static variable, implementing the double-checked
433 // locking pattern correctly.
434 // usage: lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get();
435 // retrieves the singleton lookup table instance
436 struct lcl_LookupTableStatic : public ::rtl::Static< lcl_LookupTableHelper, lcl_LookupTableStatic >
439 lcl_LookupTableHelper::lcl_LookupTableHelper()
443 lcl_LookupTableHelper::~lcl_LookupTableHelper()
445 LocaleDataLookupTableItem* pItem = 0;
447 std::vector<LocaleDataLookupTableItem*>::const_iterator aEnd(maLookupTable.end());
448 std::vector<LocaleDataLookupTableItem*>::iterator aIter(maLookupTable.begin());
450 for ( ; aIter != aEnd; ++aIter ) {
451 pItem = *aIter;
452 delete pItem->module;
453 delete pItem;
455 maLookupTable.clear();
458 oslGenericFunction SAL_CALL lcl_LookupTableHelper::getFunctionSymbolByName(
459 const OUString& localeName, const sal_Char* pFunction,
460 LocaleDataLookupTableItem** pOutCachedItem )
462 OUString aFallback;
463 bool bFallback = (localeName.indexOf( cUnder) < 0);
464 if (bFallback)
466 Locale aLocale;
467 aLocale.Language = localeName;
468 Locale aFbLocale = MsLangId::getFallbackLocale( aLocale);
469 if (aFbLocale == aLocale)
470 bFallback = false; // may be a "language-only-locale" like Interlingua (ia)
471 else
472 aFallback = LocaleDataImpl::getFirstLocaleServiceName( aFbLocale);
475 for ( sal_Int16 i = 0; i < nbOfLocales; i++)
477 if (localeName.equalsAscii(aLibTable[i].pLocale) ||
478 (bFallback && aFallback.equalsAscii(aLibTable[i].pLocale)))
480 #ifndef DISABLE_DYNLOADING
481 LocaleDataLookupTableItem* pCurrent = 0;
482 OUStringBuffer aBuf(strlen(aLibTable[i].pLocale) + 1 + strlen(pFunction));
484 ::osl::MutexGuard aGuard( maMutex );
485 for (size_t l = 0; l < maLookupTable.size(); l++)
487 pCurrent = maLookupTable[l];
488 if (pCurrent->dllName == aLibTable[i].pLib)
490 OSL_ASSERT( pOutCachedItem );
491 if( pOutCachedItem )
493 (*pOutCachedItem) = new LocaleDataLookupTableItem( *pCurrent );
494 (*pOutCachedItem)->localeName = aLibTable[i].pLocale;
495 return (*pOutCachedItem)->module->getFunctionSymbol(
496 aBuf.appendAscii( pFunction).append( cUnder).
497 appendAscii( (*pOutCachedItem)->localeName).makeStringAndClear());
499 else
500 return NULL;
504 // Library not loaded, load it and add it to the list.
505 #ifdef SAL_DLLPREFIX
506 aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 6); // mostly "lib*.so"
507 aBuf.appendAscii( SAL_DLLPREFIX ).appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION );
508 #else
509 aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 4); // mostly "*.dll"
510 aBuf.appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION );
511 #endif
512 osl::Module *module = new osl::Module();
513 if ( module->loadRelative(&thisModule, aBuf.makeStringAndClear()) )
515 ::osl::MutexGuard aGuard( maMutex );
516 LocaleDataLookupTableItem* pNewItem = new LocaleDataLookupTableItem(aLibTable[i].pLib, module, aLibTable[i].pLocale);
517 maLookupTable.push_back(pNewItem);
518 OSL_ASSERT( pOutCachedItem );
519 if( pOutCachedItem )
521 (*pOutCachedItem) = new LocaleDataLookupTableItem( *pNewItem );
522 return module->getFunctionSymbol(
523 aBuf.appendAscii(pFunction).append(cUnder).
524 appendAscii((*pOutCachedItem)->localeName).makeStringAndClear());
526 else
527 return NULL;
529 else
530 delete module;
531 #else
532 (void) pOutCachedItem;
534 if( strcmp(pFunction, "getAllCalendars") == 0 )
535 return aLibTable[i].getAllCalendars;
536 else if( strcmp(pFunction, "getAllCurrencies") == 0 )
537 return aLibTable[i].getAllCurrencies;
538 else if( strcmp(pFunction, "getAllFormats0") == 0 )
539 return aLibTable[i].getAllFormats0;
540 else if( strcmp(pFunction, "getBreakIteratorRules") == 0 )
541 return aLibTable[i].getBreakIteratorRules;
542 else if( strcmp(pFunction, "getCollationOptions") == 0 )
543 return aLibTable[i].getCollationOptions;
544 else if( strcmp(pFunction, "getCollatorImplementation") == 0 )
545 return aLibTable[i].getCollatorImplementation;
546 else if( strcmp(pFunction, "getContinuousNumberingLevels") == 0 )
547 return aLibTable[i].getContinuousNumberingLevels;
548 else if( strcmp(pFunction, "getDateAcceptancePatterns") == 0 )
549 return aLibTable[i].getDateAcceptancePatterns;
550 else if( strcmp(pFunction, "getFollowPageWords") == 0 )
551 return aLibTable[i].getFollowPageWords;
552 else if( strcmp(pFunction, "getForbiddenCharacters") == 0 )
553 return aLibTable[i].getForbiddenCharacters;
554 else if( strcmp(pFunction, "getIndexAlgorithm") == 0 )
555 return aLibTable[i].getIndexAlgorithm;
556 else if( strcmp(pFunction, "getLCInfo") == 0 )
557 return aLibTable[i].getLCInfo;
558 else if( strcmp(pFunction, "getLocaleItem") == 0 )
559 return aLibTable[i].getLocaleItem;
560 else if( strcmp(pFunction, "getOutlineNumberingLevels") == 0 )
561 return aLibTable[i].getOutlineNumberingLevels;
562 else if( strcmp(pFunction, "getReservedWords") == 0 )
563 return aLibTable[i].getReservedWords;
564 else if( strcmp(pFunction, "getSearchOptions") == 0 )
565 return aLibTable[i].getSearchOptions;
566 else if( strcmp(pFunction, "getTransliterations") == 0 )
567 return aLibTable[i].getTransliterations;
568 else if( strcmp(pFunction, "getUnicodeScripts") == 0 )
569 return aLibTable[i].getUnicodeScripts;
570 else if( strcmp(pFunction, "getAllFormats1") == 0 )
571 return aLibTable[i].getAllFormats1;
572 #endif
575 return NULL;
578 } // anonymous namespace
581 // REF values equal offsets of counts within getAllCalendars() data structure!
582 #define REF_DAYS 0
583 #define REF_MONTHS 1
584 #define REF_GMONTHS 2
585 #define REF_PMONTHS 3
586 #define REF_ERAS 4
587 #define REF_OFFSET_COUNT 5
589 Sequence< CalendarItem2 > &LocaleDataImpl::getCalendarItemByName(const OUString& name,
590 const Locale& rLocale, const Sequence< Calendar2 >& calendarsSeq, sal_Int16 item)
591 throw(RuntimeException)
593 if (!ref_name.equals(name)) {
594 OUString aLocStr, id;
595 sal_Int32 nLastUnder = name.lastIndexOf( cUnder);
596 SAL_WARN_IF( nLastUnder < 1, "i18npool",
597 "LocaleDataImpl::getCalendarItemByName - no '_' or first in name can't be right: " << name);
598 if (nLastUnder >= 0)
600 aLocStr = name.copy( 0, nLastUnder);
601 if (nLastUnder + 1 < name.getLength())
602 id = name.copy( nLastUnder + 1);
604 Locale loc( LanguageTag::convertToLocale( aLocStr.replace( cUnder, cHyphen)));
605 Sequence < Calendar2 > cals;
606 if (loc == rLocale) {
607 cals = calendarsSeq;
608 } else {
609 cals = getAllCalendars2(loc);
611 sal_Int32 index;
612 for (index = 0; index < cals.getLength(); index++) {
613 if (id.equals(cals[index].Name)) {
614 ref_cal = cals[index];
615 break;
618 // Referred locale not found, return name for en_US locale.
619 if (index == cals.getLength()) {
620 cals = getAllCalendars2(
621 Locale(OUString("en"), OUString("US"), OUString()));
622 if (cals.getLength() > 0)
623 ref_cal = cals[0];
624 else
625 throw RuntimeException();
627 ref_name = name;
629 switch (item)
631 case REF_DAYS:
632 return ref_cal.Days;
633 case REF_MONTHS:
634 return ref_cal.Months;
635 case REF_GMONTHS:
636 return ref_cal.GenitiveMonths;
637 case REF_PMONTHS:
638 return ref_cal.PartitiveMonths;
639 default:
640 OSL_FAIL( "LocaleDataImpl::getCalendarItemByName: unhandled REF_* case");
641 // fallthru
642 case REF_ERAS:
643 return ref_cal.Eras;
648 Sequence< CalendarItem2 > LocaleDataImpl::getCalendarItems(
649 sal_Unicode const * const * const allCalendars, sal_Int16 & rnOffset,
650 const sal_Int16 nWhichItem, const sal_Int16 nCalendar,
651 const Locale & rLocale, const Sequence< Calendar2 > & calendarsSeq )
652 throw(RuntimeException)
654 Sequence< CalendarItem2 > aItems;
655 if ( OUString( allCalendars[rnOffset] ) == "ref" )
657 aItems = getCalendarItemByName( OUString( allCalendars[rnOffset+1]), rLocale, calendarsSeq, nWhichItem);
658 rnOffset += 2;
660 else
662 sal_Int32 nSize = allCalendars[nWhichItem][nCalendar];
663 aItems.realloc( nSize);
664 CalendarItem2* pItem = aItems.getArray();
665 switch (nWhichItem)
667 case REF_DAYS:
668 case REF_MONTHS:
669 case REF_GMONTHS:
670 case REF_PMONTHS:
671 for (sal_Int16 j = 0; j < nSize; ++j, ++pItem)
673 CalendarItem2 item( allCalendars[rnOffset], allCalendars[rnOffset+1],
674 allCalendars[rnOffset+2], allCalendars[rnOffset+3]);
675 *pItem = item;
676 rnOffset += 4;
678 break;
679 case REF_ERAS:
680 // Absent narrow name.
681 for (sal_Int16 j = 0; j < nSize; ++j, ++pItem)
683 CalendarItem2 item( allCalendars[rnOffset], allCalendars[rnOffset+1],
684 allCalendars[rnOffset+2], OUString());
685 *pItem = item;
686 rnOffset += 3;
688 break;
689 default:
690 OSL_FAIL( "LocaleDataImpl::getCalendarItems: unhandled REF_* case");
693 return aItems;
697 Sequence< Calendar2 > SAL_CALL
698 LocaleDataImpl::getAllCalendars2( const Locale& rLocale ) throw(RuntimeException, std::exception)
701 sal_Unicode const * const * allCalendars = NULL;
703 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getAllCalendars" );
705 if ( func ) {
706 sal_Int16 calendarsCount = 0;
707 allCalendars = func(calendarsCount);
709 Sequence< Calendar2 > calendarsSeq(calendarsCount);
710 sal_Int16 offset = REF_OFFSET_COUNT;
711 for(sal_Int16 i = 0; i < calendarsCount; i++) {
712 OUString calendarID(allCalendars[offset]);
713 offset++;
714 bool defaultCalendar = sal::static_int_cast<sal_Bool>( allCalendars[offset][0] );
715 offset++;
716 Sequence< CalendarItem2 > days = getCalendarItems( allCalendars, offset, REF_DAYS, i,
717 rLocale, calendarsSeq);
718 Sequence< CalendarItem2 > months = getCalendarItems( allCalendars, offset, REF_MONTHS, i,
719 rLocale, calendarsSeq);
720 Sequence< CalendarItem2 > gmonths = getCalendarItems( allCalendars, offset, REF_GMONTHS, i,
721 rLocale, calendarsSeq);
722 Sequence< CalendarItem2 > pmonths = getCalendarItems( allCalendars, offset, REF_PMONTHS, i,
723 rLocale, calendarsSeq);
724 Sequence< CalendarItem2 > eras = getCalendarItems( allCalendars, offset, REF_ERAS, i,
725 rLocale, calendarsSeq);
726 OUString startOfWeekDay(allCalendars[offset]);
727 offset++;
728 sal_Int16 minimalDaysInFirstWeek = allCalendars[offset][0];
729 offset++;
730 Calendar2 aCalendar(days, months, gmonths, pmonths, eras, startOfWeekDay,
731 minimalDaysInFirstWeek, defaultCalendar, calendarID);
732 calendarsSeq[i] = aCalendar;
734 return calendarsSeq;
736 else {
737 Sequence< Calendar2 > seq1(0);
738 return seq1;
743 Sequence< Calendar > SAL_CALL
744 LocaleDataImpl::getAllCalendars( const Locale& rLocale ) throw(RuntimeException, std::exception)
746 const Sequence< Calendar2 > aCal2( getAllCalendars2( rLocale));
747 sal_Int32 nLen = aCal2.getLength();
748 Sequence< Calendar > aCal1( nLen);
749 const Calendar2* p2 = aCal2.getConstArray();
750 Calendar* p1 = aCal1.getArray();
751 for (sal_Int32 i=0; i < nLen; ++i, ++p1, ++p2)
753 *p1 = downcastCalendar( *p2);
755 return aCal1;
759 Sequence< Currency2 > SAL_CALL
760 LocaleDataImpl::getAllCurrencies2( const Locale& rLocale ) throw(RuntimeException, std::exception)
762 sal_Unicode **allCurrencies = NULL;
764 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getAllCurrencies" );
766 if ( func ) {
767 sal_Int16 currencyCount = 0;
768 allCurrencies = func(currencyCount);
770 Sequence< Currency2 > seq(currencyCount);
771 for(int i = 0, nOff = 0; i < currencyCount; i++, nOff += 8 ) {
772 Currency2 cur(
773 allCurrencies[nOff], // string ID
774 allCurrencies[nOff+1], // string Symbol
775 allCurrencies[nOff+2], // string BankSymbol
776 allCurrencies[nOff+3], // string Name
777 allCurrencies[nOff+4][0] != 0, // boolean Default
778 allCurrencies[nOff+5][0] != 0, // boolean UsedInCompatibleFormatCodes
779 allCurrencies[nOff+6][0], // short DecimalPlaces
780 allCurrencies[nOff+7][0] != 0 // boolean LegacyOnly
782 seq[i] = cur;
784 return seq;
786 else {
787 Sequence< Currency2 > seq1(0);
788 return seq1;
793 Sequence< Currency > SAL_CALL
794 LocaleDataImpl::getAllCurrencies( const Locale& rLocale ) throw(RuntimeException, std::exception)
796 Sequence< Currency2 > aCur2( getAllCurrencies2( rLocale));
797 sal_Int32 nLen = aCur2.getLength();
798 Sequence< Currency > aCur1( nLen);
799 const Currency2* p2 = aCur2.getArray();
800 Currency* p1 = aCur1.getArray();
801 for (sal_Int32 i=0; i < nLen; ++i, ++p1, ++p2)
803 *p1 = *p2;
805 return aCur1;
809 // return a static (!) string resulting from replacing all occurrences of
810 // 'oldStr' string in 'formatCode' string with 'newStr' string
811 static const sal_Unicode * replace( sal_Unicode const * const formatCode, sal_Unicode const * const oldStr, sal_Unicode const * const newStr)
813 // make reasonable assumption of maximum length of formatCode.
814 #define MAX_FORMATCODE_LENTH 512
815 static sal_Unicode str[MAX_FORMATCODE_LENTH];
817 if (oldStr[0] == 0) // no replacement requires
818 return formatCode;
820 sal_Int32 i = 0, k = 0;
821 while (formatCode[i] > 0 && k < MAX_FORMATCODE_LENTH) {
822 sal_Int32 j = 0, last = k;
823 // search oldStr in formatCode
824 while (formatCode[i] > 0 && oldStr[j] > 0 && k < MAX_FORMATCODE_LENTH) {
825 str[k++] = formatCode[i];
826 if (formatCode[i++] != oldStr[j++])
827 break;
829 if (oldStr[j] == 0) {
830 // matched string found, do replacement
831 k = last; j = 0;
832 while (newStr[j] > 0 && k < MAX_FORMATCODE_LENTH)
833 str[k++] = newStr[j++];
836 if (k >= MAX_FORMATCODE_LENTH) // could not complete replacement, return original formatCode
837 return formatCode;
839 str[k] = 0;
840 return str;
843 Sequence< FormatElement > SAL_CALL
844 LocaleDataImpl::getAllFormats( const Locale& rLocale ) throw(RuntimeException, std::exception)
846 const int SECTIONS = 2;
847 struct FormatSection
849 MyFunc_FormatCode func;
850 sal_Unicode const *from;
851 sal_Unicode const *to;
852 sal_Unicode const *const *formatArray;
853 sal_Int16 formatCount;
855 FormatSection() : func(0), from(0), to(0), formatArray(0), formatCount(0) {}
856 sal_Int16 getFunc( LocaleDataImpl& rLocaleData, const Locale& rL, const char* pName )
858 func = reinterpret_cast<MyFunc_FormatCode>( rLocaleData.getFunctionSymbol( rL, pName));
859 if (func)
860 formatArray = func( formatCount, from, to);
861 return formatCount;
863 } section[SECTIONS];
865 sal_Int32 formatCount;
866 formatCount = section[0].getFunc( *this, rLocale, "getAllFormats0");
867 formatCount += section[1].getFunc( *this, rLocale, "getAllFormats1");
869 Sequence< FormatElement > seq(formatCount);
870 sal_Int32 f = 0;
871 for (int s = 0; s < SECTIONS; ++s)
873 sal_Unicode const * const * const formatArray = section[s].formatArray;
874 if ( formatArray )
876 for (int i = 0, nOff = 0; i < section[s].formatCount; ++i, nOff += 7, ++f)
878 FormatElement elem(
879 replace( formatArray[nOff], section[s].from, section[s].to),
880 formatArray[nOff + 1],
881 formatArray[nOff + 2],
882 formatArray[nOff + 3],
883 formatArray[nOff + 4],
884 formatArray[nOff + 5][0],
885 sal::static_int_cast<sal_Bool>(formatArray[nOff + 6][0]));
886 seq[f] = elem;
890 return seq;
894 Sequence< OUString > SAL_CALL
895 LocaleDataImpl::getDateAcceptancePatterns( const Locale& rLocale ) throw(RuntimeException, std::exception)
897 sal_Unicode **patternsArray = NULL;
899 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getDateAcceptancePatterns" );
901 if (func)
903 sal_Int16 patternsCount = 0;
904 patternsArray = func( patternsCount );
905 Sequence< OUString > seq( patternsCount );
906 for (sal_Int16 i = 0; i < patternsCount; ++i)
908 seq[i] = OUString( patternsArray[i] );
910 return seq;
912 else
914 Sequence< OUString > seq(0);
915 return seq;
920 #define COLLATOR_OFFSET_ALGO 0
921 #define COLLATOR_OFFSET_DEFAULT 1
922 #define COLLATOR_OFFSET_RULE 2
923 #define COLLATOR_ELEMENTS 3
925 OUString SAL_CALL
926 LocaleDataImpl::getCollatorRuleByAlgorithm( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException)
928 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getCollatorImplementation" );
929 if ( func ) {
930 sal_Int16 collatorCount = 0;
931 sal_Unicode **collatorArray = func(collatorCount);
932 for(sal_Int16 i = 0; i < collatorCount; i++)
933 if (algorithm.equals(collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_ALGO]))
934 return OUString(collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_RULE]);
936 return OUString();
940 Sequence< Implementation > SAL_CALL
941 LocaleDataImpl::getCollatorImplementations( const Locale& rLocale ) throw(RuntimeException, std::exception)
943 sal_Unicode **collatorArray = NULL;
945 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getCollatorImplementation" );
947 if ( func ) {
948 sal_Int16 collatorCount = 0;
949 collatorArray = func(collatorCount);
950 Sequence< Implementation > seq(collatorCount);
951 for(sal_Int16 i = 0; i < collatorCount; i++) {
952 Implementation impl(collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_ALGO],
953 sal::static_int_cast<sal_Bool>(
954 collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_DEFAULT][0]));
955 seq[i] = impl;
957 return seq;
959 else {
960 Sequence< Implementation > seq1(0);
961 return seq1;
965 Sequence< OUString > SAL_CALL
966 LocaleDataImpl::getCollationOptions( const Locale& rLocale ) throw(RuntimeException, std::exception)
968 sal_Unicode **optionsArray = NULL;
970 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getCollationOptions" );
972 if ( func ) {
973 sal_Int16 optionsCount = 0;
974 optionsArray = func(optionsCount);
975 Sequence< OUString > seq(optionsCount);
976 for(sal_Int16 i = 0; i < optionsCount; i++) {
977 seq[i] = OUString( optionsArray[i] );
979 return seq;
981 else {
982 Sequence< OUString > seq1(0);
983 return seq1;
987 Sequence< OUString > SAL_CALL
988 LocaleDataImpl::getSearchOptions( const Locale& rLocale ) throw(RuntimeException, std::exception)
990 sal_Unicode **optionsArray = NULL;
992 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getSearchOptions" );
994 if ( func ) {
995 sal_Int16 optionsCount = 0;
996 optionsArray = func(optionsCount);
997 Sequence< OUString > seq(optionsCount);
998 for(sal_Int16 i = 0; i < optionsCount; i++) {
999 seq[i] = OUString( optionsArray[i] );
1001 return seq;
1003 else {
1004 Sequence< OUString > seq1(0);
1005 return seq1;
1009 sal_Unicode ** SAL_CALL
1010 LocaleDataImpl::getIndexArray(const Locale& rLocale, sal_Int16& indexCount)
1012 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getIndexAlgorithm" );
1014 if (func)
1015 return func(indexCount);
1016 return NULL;
1019 Sequence< OUString > SAL_CALL
1020 LocaleDataImpl::getIndexAlgorithm( const Locale& rLocale ) throw(RuntimeException)
1022 sal_Int16 indexCount = 0;
1023 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount);
1025 if ( indexArray ) {
1026 Sequence< OUString > seq(indexCount);
1027 for(sal_Int16 i = 0; i < indexCount; i++) {
1028 seq[i] = indexArray[i*5];
1030 return seq;
1032 else {
1033 Sequence< OUString > seq1(0);
1034 return seq1;
1038 OUString SAL_CALL
1039 LocaleDataImpl::getDefaultIndexAlgorithm( const Locale& rLocale ) throw(RuntimeException)
1041 sal_Int16 indexCount = 0;
1042 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount);
1044 if ( indexArray ) {
1045 for(sal_Int16 i = 0; i < indexCount; i++) {
1046 if (indexArray[i*5 + 3][0])
1047 return OUString(indexArray[i*5]);
1050 return OUString();
1053 bool SAL_CALL
1054 LocaleDataImpl::hasPhonetic( const Locale& rLocale ) throw(RuntimeException)
1056 sal_Int16 indexCount = 0;
1057 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount);
1059 if ( indexArray ) {
1060 for(sal_Int16 i = 0; i < indexCount; i++) {
1061 if (indexArray[i*5 + 4][0])
1062 return true;
1065 return false;
1068 sal_Unicode ** SAL_CALL
1069 LocaleDataImpl::getIndexArrayForAlgorithm(const Locale& rLocale, const OUString& algorithm)
1071 sal_Int16 indexCount = 0;
1072 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount);
1073 if ( indexArray ) {
1074 for(sal_Int16 i = 0; i < indexCount; i++) {
1075 if (algorithm.equals(indexArray[i*5]))
1076 return indexArray+i*5;
1079 return NULL;
1082 bool SAL_CALL
1083 LocaleDataImpl::isPhonetic( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException)
1085 sal_Unicode **indexArray = getIndexArrayForAlgorithm(rLocale, algorithm);
1086 return (indexArray && indexArray[4][0]) ? sal_True : sal_False;
1089 OUString SAL_CALL
1090 LocaleDataImpl::getIndexKeysByAlgorithm( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException)
1092 sal_Unicode **indexArray = getIndexArrayForAlgorithm(rLocale, algorithm);
1093 return indexArray ? OUString("0-9")+OUString(indexArray[2]) : OUString();
1096 OUString SAL_CALL
1097 LocaleDataImpl::getIndexModuleByAlgorithm( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException)
1099 sal_Unicode **indexArray = getIndexArrayForAlgorithm(rLocale, algorithm);
1100 return indexArray ? OUString(indexArray[1]) : OUString();
1103 Sequence< UnicodeScript > SAL_CALL
1104 LocaleDataImpl::getUnicodeScripts( const Locale& rLocale ) throw(RuntimeException)
1106 sal_Unicode **scriptArray = NULL;
1108 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getUnicodeScripts" );
1110 if ( func ) {
1111 sal_Int16 scriptCount = 0;
1112 scriptArray = func(scriptCount);
1113 Sequence< UnicodeScript > seq(scriptCount);
1114 for(sal_Int16 i = 0; i < scriptCount; i++) {
1115 seq[i] = UnicodeScript( OUString(scriptArray[i]).toInt32() );
1117 return seq;
1119 else {
1120 Sequence< UnicodeScript > seq1(0);
1121 return seq1;
1125 Sequence< OUString > SAL_CALL
1126 LocaleDataImpl::getFollowPageWords( const Locale& rLocale ) throw(RuntimeException)
1128 sal_Unicode **wordArray = NULL;
1130 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getFollowPageWords" );
1132 if ( func ) {
1133 sal_Int16 wordCount = 0;
1134 wordArray = func(wordCount);
1135 Sequence< OUString > seq(wordCount);
1136 for(sal_Int16 i = 0; i < wordCount; i++) {
1137 seq[i] = OUString(wordArray[i]);
1139 return seq;
1141 else {
1142 Sequence< OUString > seq1(0);
1143 return seq1;
1147 Sequence< OUString > SAL_CALL
1148 LocaleDataImpl::getTransliterations( const Locale& rLocale ) throw(RuntimeException, std::exception)
1151 sal_Unicode **transliterationsArray = NULL;
1153 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getTransliterations" );
1155 if ( func ) {
1156 sal_Int16 transliterationsCount = 0;
1157 transliterationsArray = func(transliterationsCount);
1159 Sequence< OUString > seq(transliterationsCount);
1160 for(int i = 0; i < transliterationsCount; i++) {
1161 OUString elem(transliterationsArray[i]);
1162 seq[i] = elem;
1164 return seq;
1166 else {
1167 Sequence< OUString > seq1(0);
1168 return seq1;
1175 LanguageCountryInfo SAL_CALL
1176 LocaleDataImpl::getLanguageCountryInfo( const Locale& rLocale ) throw(RuntimeException, std::exception)
1179 sal_Unicode **LCInfoArray = NULL;
1181 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getLCInfo" );
1183 if ( func ) {
1184 sal_Int16 LCInfoCount = 0;
1185 LCInfoArray = func(LCInfoCount);
1186 LanguageCountryInfo info(LCInfoArray[0],
1187 LCInfoArray[1],
1188 LCInfoArray[2],
1189 LCInfoArray[3],
1190 LCInfoArray[4]);
1191 return info;
1193 else {
1194 LanguageCountryInfo info1;
1195 return info1;
1201 ForbiddenCharacters SAL_CALL
1202 LocaleDataImpl::getForbiddenCharacters( const Locale& rLocale ) throw(RuntimeException, std::exception)
1204 sal_Unicode **LCForbiddenCharactersArray = NULL;
1206 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getForbiddenCharacters" );
1208 if ( func ) {
1209 sal_Int16 LCForbiddenCharactersCount = 0;
1210 LCForbiddenCharactersArray = func(LCForbiddenCharactersCount);
1211 ForbiddenCharacters chars(LCForbiddenCharactersArray[0], LCForbiddenCharactersArray[1]);
1212 return chars;
1214 else {
1215 ForbiddenCharacters chars1;
1216 return chars1;
1220 OUString SAL_CALL
1221 LocaleDataImpl::getHangingCharacters( const Locale& rLocale ) throw(RuntimeException)
1223 sal_Unicode **LCForbiddenCharactersArray = NULL;
1225 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getForbiddenCharacters" );
1227 if ( func ) {
1228 sal_Int16 LCForbiddenCharactersCount = 0;
1229 LCForbiddenCharactersArray = func(LCForbiddenCharactersCount);
1230 return OUString(LCForbiddenCharactersArray[2]);
1233 return OUString();
1236 Sequence< OUString > SAL_CALL
1237 LocaleDataImpl::getBreakIteratorRules( const Locale& rLocale ) throw(RuntimeException)
1239 sal_Unicode **LCBreakIteratorRulesArray = NULL;
1241 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getBreakIteratorRules" );
1243 if ( func ) {
1244 sal_Int16 LCBreakIteratorRuleCount = 0;
1245 LCBreakIteratorRulesArray = func(LCBreakIteratorRuleCount);
1246 Sequence< OUString > seq(LCBreakIteratorRuleCount);
1247 for(int i = 0; i < (LCBreakIteratorRuleCount); i++) {
1248 OUString elem(LCBreakIteratorRulesArray[i]);
1249 seq[i] = elem;
1251 return seq;
1253 else {
1254 Sequence< OUString > seq1(0);
1255 return seq1;
1260 Sequence< OUString > SAL_CALL
1261 LocaleDataImpl::getReservedWord( const Locale& rLocale ) throw(RuntimeException, std::exception)
1263 sal_Unicode **LCReservedWordsArray = NULL;
1265 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getReservedWords" );
1267 if ( func ) {
1268 sal_Int16 LCReservedWordsCount = 0;
1269 LCReservedWordsArray = func(LCReservedWordsCount);
1270 Sequence< OUString > seq(LCReservedWordsCount);
1271 for(int i = 0; i < (LCReservedWordsCount); i++) {
1272 OUString elem(LCReservedWordsArray[i]);
1273 seq[i] = elem;
1275 return seq;
1277 else {
1278 Sequence< OUString > seq1(0);
1279 return seq1;
1284 Sequence< Sequence<beans::PropertyValue> > SAL_CALL
1285 LocaleDataImpl::getContinuousNumberingLevels( const lang::Locale& rLocale ) throw(RuntimeException)
1287 // load symbol
1288 MyFunc_Type2 func = (MyFunc_Type2) getFunctionSymbol( rLocale, "getContinuousNumberingLevels" );
1290 if ( func )
1292 int i;
1293 // invoke function
1294 sal_Int16 nStyles;
1295 sal_Int16 nAttributes;
1296 sal_Unicode*** p0 = func( nStyles, nAttributes );
1298 // allocate memory for nAttributes attributes for each of the nStyles styles.
1299 Sequence< Sequence<beans::PropertyValue> > pv( nStyles );
1300 for( i=0; i<pv.getLength(); i++ ) {
1301 pv[i] = Sequence<beans::PropertyValue>( nAttributes );
1304 sal_Unicode*** pStyle = p0;
1305 for( i=0; i<nStyles; i++ ) {
1306 sal_Unicode** pAttribute = pStyle[i];
1307 for( int j=0; j<nAttributes; j++ ) { // prefix, numberingtype, ...
1308 sal_Unicode* pString = pAttribute[j];
1309 beans::PropertyValue& rVal = pv[i][j];
1310 OUString sVal;
1311 if( pString ) {
1312 if( 0 != j && 2 != j )
1313 sVal = pString;
1314 else if( *pString )
1315 sVal = OUString( pString, 1 );
1318 switch( j )
1320 case 0:
1321 rVal.Name = "Prefix";
1322 rVal.Value <<= sVal;
1323 break;
1324 case 1:
1325 rVal.Name = "NumberingType";
1326 rVal.Value <<= (sal_Int16) sVal.toInt32();
1327 break;
1328 case 2:
1329 rVal.Name = "Suffix";
1330 rVal.Value <<= sVal;
1331 break;
1332 case 3:
1333 rVal.Name = "Transliteration";
1334 rVal.Value <<= sVal;
1335 break;
1336 case 4:
1337 rVal.Name = "NatNum";
1338 rVal.Value <<= (sal_Int16) sVal.toInt32();
1339 break;
1340 default:
1341 OSL_ASSERT(false);
1345 return pv;
1348 Sequence< Sequence<beans::PropertyValue> > seq1(0);
1349 return seq1;
1352 // OutlineNumbering helper class
1354 #include <com/sun/star/container/XIndexAccess.hpp>
1355 #include <cppuhelper/implbase1.hxx>
1357 namespace com{ namespace sun{ namespace star{ namespace lang {
1358 struct Locale;
1359 }}}}
1361 struct OutlineNumberingLevel_Impl
1363 OUString sPrefix;
1364 sal_Int16 nNumType; //com::sun::star::style::NumberingType
1365 OUString sSuffix;
1366 sal_Unicode cBulletChar;
1367 OUString sBulletFontName;
1368 sal_Int16 nParentNumbering;
1369 sal_Int32 nLeftMargin;
1370 sal_Int32 nSymbolTextDistance;
1371 sal_Int32 nFirstLineOffset;
1372 OUString sTransliteration;
1373 sal_Int32 nNatNum;
1376 class OutlineNumbering : public cppu::WeakImplHelper1 < container::XIndexAccess >
1378 // OutlineNumbering helper class
1380 const OutlineNumberingLevel_Impl* m_pOutlineLevels;
1381 sal_Int16 m_nCount;
1382 public:
1383 OutlineNumbering(const OutlineNumberingLevel_Impl* pOutlineLevels, int nLevels);
1384 virtual ~OutlineNumbering();
1386 //XIndexAccess
1387 virtual sal_Int32 SAL_CALL getCount( ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
1388 virtual Any SAL_CALL getByIndex( sal_Int32 Index )
1389 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception) SAL_OVERRIDE;
1391 //XElementAccess
1392 virtual Type SAL_CALL getElementType( ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
1393 virtual sal_Bool SAL_CALL hasElements( ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
1396 Sequence< Reference<container::XIndexAccess> > SAL_CALL
1397 LocaleDataImpl::getOutlineNumberingLevels( const lang::Locale& rLocale ) throw(RuntimeException)
1399 // load symbol
1400 MyFunc_Type3 func = (MyFunc_Type3) getFunctionSymbol( rLocale, "getOutlineNumberingLevels" );
1402 if ( func )
1404 int i;
1405 // invoke function
1406 sal_Int16 nStyles;
1407 sal_Int16 nLevels;
1408 sal_Int16 nAttributes;
1409 sal_Unicode**** p0 = func( nStyles, nLevels, nAttributes );
1411 Sequence< Reference<container::XIndexAccess> > aRet( nStyles );
1413 OUString aEmptyStr;
1415 sal_Unicode**** pStyle = p0;
1416 for( i=0; i<nStyles; i++ )
1418 int j;
1420 OutlineNumberingLevel_Impl* level = new OutlineNumberingLevel_Impl[ nLevels+1 ];
1421 sal_Unicode*** pLevel = pStyle[i];
1422 for( j = 0; j < nLevels; j++ )
1424 sal_Unicode** pAttribute = pLevel[j];
1425 for( int k=0; k<nAttributes; k++ )
1427 OUString tmp( pAttribute[k] );
1428 switch( k )
1430 case 0: level[j].sPrefix = tmp; break;
1431 case 1: level[j].nNumType = sal::static_int_cast<sal_Int16>(tmp.toInt32()); break;
1432 case 2: level[j].sSuffix = tmp; break;
1433 case 3: level[j].cBulletChar = sal::static_int_cast<sal_Unicode>(tmp.toUInt32(16)); break; // base 16
1434 case 4: level[j].sBulletFontName = tmp; break;
1435 case 5: level[j].nParentNumbering = sal::static_int_cast<sal_Int16>(tmp.toInt32()); break;
1436 case 6: level[j].nLeftMargin = tmp.toInt32(); break;
1437 case 7: level[j].nSymbolTextDistance = tmp.toInt32(); break;
1438 case 8: level[j].nFirstLineOffset = tmp.toInt32(); break;
1439 case 9: break;
1440 case 10: level[j].sTransliteration = tmp; break;
1441 case 11: level[j].nNatNum = tmp.toInt32(); break;
1442 default:
1443 OSL_ASSERT(false);
1447 level[j].sPrefix = aEmptyStr;
1448 level[j].nNumType = 0;
1449 level[j].sSuffix = aEmptyStr;
1450 level[j].cBulletChar = 0;
1451 level[j].sBulletFontName = aEmptyStr;
1452 level[j].nParentNumbering = 0;
1453 level[j].nLeftMargin = 0;
1454 level[j].nSymbolTextDistance = 0;
1455 level[j].nFirstLineOffset = 0;
1456 level[j].sTransliteration = aEmptyStr;
1457 level[j].nNatNum = 0;
1458 aRet[i] = new OutlineNumbering( level, nLevels );
1460 return aRet;
1462 else {
1463 Sequence< Reference<container::XIndexAccess> > seq1(0);
1464 return seq1;
1468 // helper functions
1470 oslGenericFunction SAL_CALL LocaleDataImpl::getFunctionSymbol( const Locale& rLocale, const sal_Char* pFunction )
1471 throw(RuntimeException)
1473 lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get();
1475 OUStringBuffer aBuf(1);
1476 if (cachedItem.get() && cachedItem->equals(rLocale))
1478 aBuf.ensureCapacity(strlen(pFunction) + 1 + strlen(cachedItem->localeName));
1479 return cachedItem->module->getFunctionSymbol(aBuf.appendAscii(pFunction).append(cUnder).
1480 appendAscii(cachedItem->localeName).makeStringAndClear());
1483 oslGenericFunction pSymbol = 0;
1484 LocaleDataLookupTableItem *pCachedItem = 0;
1486 // Load function with name <func>_<lang>_<country> or <func>_<bcp47> and
1487 // fallbacks.
1488 pSymbol = rLookupTable.getFunctionSymbolByName( LocaleDataImpl::getFirstLocaleServiceName( rLocale),
1489 pFunction, &pCachedItem);
1490 if (!pSymbol)
1492 ::std::vector< OUString > aFallbacks( LocaleDataImpl::getFallbackLocaleServiceNames( rLocale));
1493 for (::std::vector< OUString >::const_iterator it( aFallbacks.begin()); it != aFallbacks.end(); ++it)
1495 pSymbol = rLookupTable.getFunctionSymbolByName( *it, pFunction, &pCachedItem);
1496 if (pSymbol)
1497 break;
1500 if (!pSymbol)
1502 // load default function with name <func>_en_US
1503 pSymbol = rLookupTable.getFunctionSymbolByName(OUString("en_US"), pFunction, &pCachedItem);
1506 if (!pSymbol)
1507 // Appropriate symbol could not be found. Give up.
1508 throw RuntimeException();
1510 if (pCachedItem)
1511 cachedItem.reset(pCachedItem);
1512 if (cachedItem.get())
1513 cachedItem->aLocale = rLocale;
1515 return pSymbol;
1518 Sequence< Locale > SAL_CALL
1519 LocaleDataImpl::getAllInstalledLocaleNames() throw(RuntimeException, std::exception)
1521 Sequence< lang::Locale > seq( nbOfLocales );
1522 sal_Int16 nInstalled = 0;
1524 for( sal_Int16 i=0; i<nbOfLocales; i++ ) {
1525 OUString name = OUString::createFromAscii( aLibTable[i].pLocale );
1527 // Check if the locale is really available and not just in the table,
1528 // don't allow fall backs.
1529 LocaleDataLookupTableItem *pCachedItem = 0;
1530 if (lcl_LookupTableStatic::get().getFunctionSymbolByName( name, "getLocaleItem", &pCachedItem )) {
1531 if( pCachedItem )
1532 cachedItem.reset( pCachedItem );
1533 seq[nInstalled++] = LanguageTag::convertToLocale( name.replace( cUnder, cHyphen), false);
1535 else
1537 delete pCachedItem;
1540 if ( nInstalled < nbOfLocales )
1541 seq.realloc( nInstalled ); // reflect reality
1543 return seq;
1546 using namespace ::com::sun::star::container;
1547 using namespace ::com::sun::star::beans;
1548 using namespace ::com::sun::star::style;
1549 using namespace ::com::sun::star::text;
1551 OutlineNumbering::OutlineNumbering(const OutlineNumberingLevel_Impl* pOutlnLevels, int nLevels) :
1552 m_pOutlineLevels(pOutlnLevels),
1553 m_nCount(sal::static_int_cast<sal_Int16>(nLevels))
1557 OutlineNumbering::~OutlineNumbering()
1559 delete [] m_pOutlineLevels;
1562 sal_Int32 OutlineNumbering::getCount( ) throw(RuntimeException, std::exception)
1564 return m_nCount;
1567 Any OutlineNumbering::getByIndex( sal_Int32 nIndex )
1568 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
1570 if(nIndex < 0 || nIndex >= m_nCount)
1571 throw IndexOutOfBoundsException();
1572 const OutlineNumberingLevel_Impl* pTemp = m_pOutlineLevels;
1573 pTemp += nIndex;
1574 Any aRet;
1576 Sequence<PropertyValue> aOutlineNumbering(12);
1577 PropertyValue* pValues = aOutlineNumbering.getArray();
1578 pValues[0].Name = "Prefix";
1579 pValues[0].Value <<= pTemp->sPrefix;
1580 pValues[1].Name = "NumberingType";
1581 pValues[1].Value <<= pTemp->nNumType;
1582 pValues[2].Name = "Suffix";
1583 pValues[2].Value <<= pTemp->sSuffix;
1584 pValues[3].Name = "BulletChar";
1585 pValues[3].Value <<= OUString(&pTemp->cBulletChar, 1);
1586 pValues[4].Name = "BulletFontName";
1587 pValues[4].Value <<= pTemp->sBulletFontName;
1588 pValues[5].Name = "ParentNumbering";
1589 pValues[5].Value <<= pTemp->nParentNumbering;
1590 pValues[6].Name = "LeftMargin";
1591 pValues[6].Value <<= pTemp->nLeftMargin;
1592 pValues[7].Name = "SymbolTextDistance";
1593 pValues[7].Value <<= pTemp->nSymbolTextDistance;
1594 pValues[8].Name = "FirstLineOffset";
1595 pValues[8].Value <<= pTemp->nFirstLineOffset;
1596 pValues[9].Name = "Adjust";
1597 pValues[9].Value <<= (sal_Int16)HoriOrientation::LEFT;
1598 pValues[10].Name = "Transliteration";
1599 pValues[10].Value <<= pTemp->sTransliteration;
1600 pValues[11].Name = "NatNum";
1601 pValues[11].Value <<= pTemp->nNatNum;
1602 aRet <<= aOutlineNumbering;
1603 return aRet;
1606 Type OutlineNumbering::getElementType( ) throw(RuntimeException, std::exception)
1608 return ::getCppuType((Sequence<PropertyValue>*)0);
1611 sal_Bool OutlineNumbering::hasElements( ) throw(RuntimeException, std::exception)
1613 return m_nCount > 0;
1616 OUString SAL_CALL
1617 LocaleDataImpl::getImplementationName() throw( RuntimeException, std::exception )
1619 return OUString("com.sun.star.i18n.LocaleDataImpl");
1622 sal_Bool SAL_CALL LocaleDataImpl::supportsService(const OUString& rServiceName)
1623 throw( RuntimeException, std::exception )
1625 return cppu::supportsService(this, rServiceName);
1628 Sequence< OUString > SAL_CALL
1629 LocaleDataImpl::getSupportedServiceNames() throw( RuntimeException, std::exception )
1631 Sequence< OUString > aRet(1);
1632 aRet[0] = "com.sun.star.i18n.LocaleData";
1633 return aRet;
1636 // static
1637 OUString LocaleDataImpl::getFirstLocaleServiceName( const com::sun::star::lang::Locale & rLocale )
1639 if (rLocale.Language == I18NLANGTAG_QLT)
1640 return rLocale.Variant.replace( cHyphen, cUnder);
1641 else if (!rLocale.Country.isEmpty())
1642 return rLocale.Language + "_" + rLocale.Country;
1643 else
1644 return rLocale.Language;
1647 // static
1648 ::std::vector< OUString > LocaleDataImpl::getFallbackLocaleServiceNames( const com::sun::star::lang::Locale & rLocale )
1650 ::std::vector< OUString > aVec;
1651 if (rLocale.Language == I18NLANGTAG_QLT)
1653 aVec = LanguageTag( rLocale).getFallbackStrings( false);
1654 for (::std::vector< OUString >::iterator it(aVec.begin()); it != aVec.end(); ++it)
1656 *it = (*it).replace( cHyphen, cUnder);
1659 else if (!rLocale.Country.isEmpty())
1661 aVec.push_back( rLocale.Language);
1663 // else nothing, language-only was the first
1664 return aVec;
1667 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1668 com_sun_star_i18n_LocaleDataImpl_get_implementation(
1669 css::uno::XComponentContext *,
1670 css::uno::Sequence<css::uno::Any> const &)
1672 return cppu::acquire(new LocaleDataImpl());
1675 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */