Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / i18npool / source / localedata / localedata.cxx
blob2c54372a8b4f3cff3d7084fbe10db51014397717
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 .
21 #include <localedata.hxx>
22 #include <i18npool/mslangid.hxx>
23 #include <rtl/ustrbuf.hxx>
24 #include <string.h>
25 #include <stdio.h>
26 #include "rtl/instance.hxx"
27 #include <sal/macros.h>
29 using namespace com::sun::star::i18n;
30 using namespace com::sun::star::uno;
31 using namespace com::sun::star::lang;
32 using namespace com::sun::star;
34 using ::rtl::OUString;
35 using ::rtl::OUStringBuffer;
37 static const sal_Char clocaledata[] = "com.sun.star.i18n.LocaleData";
39 typedef sal_Unicode** (SAL_CALL * MyFunc_Type)( sal_Int16&);
40 typedef sal_Unicode*** (SAL_CALL * MyFunc_Type2)( sal_Int16&, sal_Int16& );
41 typedef sal_Unicode**** (SAL_CALL * MyFunc_Type3)( sal_Int16&, sal_Int16&, sal_Int16& );
42 typedef sal_Unicode const * const * (SAL_CALL * MyFunc_FormatCode)( sal_Int16&, sal_Unicode const *&, sal_Unicode const *& );
44 #ifndef DISABLE_DYNLOADING
46 static const char *lcl_DATA_EN = "localedata_en";
47 static const char *lcl_DATA_ES = "localedata_es";
48 static const char *lcl_DATA_EURO = "localedata_euro";
49 static const char *lcl_DATA_OTHERS = "localedata_others";
51 #endif
53 #ifndef DISABLE_DYNLOADING
55 static const struct {
56 const char* pLocale;
57 const char* pLib;
58 } aLibTable[] = {
59 { "en_US", lcl_DATA_EN },
60 { "en_AU", lcl_DATA_EN },
61 { "en_BZ", lcl_DATA_EN },
62 { "en_CA", lcl_DATA_EN },
63 { "en_GB", lcl_DATA_EN },
64 { "en_IE", lcl_DATA_EN },
65 { "en_JM", lcl_DATA_EN },
66 { "en_NZ", lcl_DATA_EN },
67 { "en_PH", lcl_DATA_EN },
68 { "en_TT", lcl_DATA_EN },
69 { "en_ZA", lcl_DATA_EN },
70 { "en_ZW", lcl_DATA_EN },
71 { "en_NA", lcl_DATA_EN },
72 { "en_GH", lcl_DATA_EN },
73 { "en_MW", lcl_DATA_EN },
75 { "es_ES", lcl_DATA_ES },
76 { "es_AR", lcl_DATA_ES },
77 { "es_BO", lcl_DATA_ES },
78 { "es_CL", lcl_DATA_ES },
79 { "es_CO", lcl_DATA_ES },
80 { "es_CR", lcl_DATA_ES },
81 { "es_DO", lcl_DATA_ES },
82 { "es_EC", lcl_DATA_ES },
83 { "es_GT", lcl_DATA_ES },
84 { "es_HN", lcl_DATA_ES },
85 { "es_MX", lcl_DATA_ES },
86 { "es_NI", lcl_DATA_ES },
87 { "es_PA", lcl_DATA_ES },
88 { "es_PE", lcl_DATA_ES },
89 { "es_PR", lcl_DATA_ES },
90 { "es_PY", lcl_DATA_ES },
91 { "es_SV", lcl_DATA_ES },
92 { "es_UY", lcl_DATA_ES },
93 { "es_VE", lcl_DATA_ES },
94 { "gl_ES", lcl_DATA_ES },
96 { "de_DE", lcl_DATA_EURO },
97 { "de_AT", lcl_DATA_EURO },
98 { "de_CH", lcl_DATA_EURO },
99 { "de_LI", lcl_DATA_EURO },
100 { "de_LU", lcl_DATA_EURO },
101 { "fr_FR", lcl_DATA_EURO },
102 { "fr_BE", lcl_DATA_EURO },
103 { "fr_CA", lcl_DATA_EURO },
104 { "fr_CH", lcl_DATA_EURO },
105 { "fr_LU", lcl_DATA_EURO },
106 { "fr_MC", lcl_DATA_EURO },
107 { "it_IT", lcl_DATA_EURO },
108 { "it_CH", lcl_DATA_EURO },
109 { "sl_SI", lcl_DATA_EURO },
110 { "sv_SE", lcl_DATA_EURO },
111 { "sv_FI", lcl_DATA_EURO },
112 { "ca_ES", lcl_DATA_EURO },
113 { "cs_CZ", lcl_DATA_EURO },
114 { "sk_SK", lcl_DATA_EURO },
115 { "da_DK", lcl_DATA_EURO },
116 { "el_GR", lcl_DATA_EURO },
117 { "fi_FI", lcl_DATA_EURO },
118 { "is_IS", lcl_DATA_EURO },
119 { "nl_BE", lcl_DATA_EURO },
120 { "nl_NL", lcl_DATA_EURO },
121 { "no_NO", lcl_DATA_EURO },
122 { "nn_NO", lcl_DATA_EURO },
123 { "nb_NO", lcl_DATA_EURO },
124 { "pl_PL", lcl_DATA_EURO },
125 { "pt_BR", lcl_DATA_EURO },
126 { "pt_PT", lcl_DATA_EURO },
127 { "ru_RU", lcl_DATA_EURO },
128 { "tr_TR", lcl_DATA_EURO },
129 { "et_EE", lcl_DATA_EURO },
130 { "lb_LU", lcl_DATA_EURO },
131 { "lt_LT", lcl_DATA_EURO },
132 { "lv_LV", lcl_DATA_EURO },
133 { "uk_UA", lcl_DATA_EURO },
134 { "ro_RO", lcl_DATA_EURO },
135 { "cy_GB", lcl_DATA_EURO },
136 { "bg_BG", lcl_DATA_EURO },
137 { "sh_ME", lcl_DATA_EURO },
138 { "sh_RS", lcl_DATA_EURO },
139 { "sh_YU", lcl_DATA_EURO },
140 { "sr_ME", lcl_DATA_EURO },
141 { "sr_RS", lcl_DATA_EURO },
142 { "sr_YU", lcl_DATA_EURO },
143 { "hr_HR", lcl_DATA_EURO },
144 { "bs_BA", lcl_DATA_EURO },
145 { "eu", lcl_DATA_EURO },
146 { "fo_FO", lcl_DATA_EURO },
147 { "ga_IE", lcl_DATA_EURO },
148 { "gd_GB", lcl_DATA_EURO },
149 { "ka_GE", lcl_DATA_EURO },
150 { "be_BY", lcl_DATA_EURO },
151 { "kl_GL", lcl_DATA_EURO },
152 { "mk_MK", lcl_DATA_EURO },
153 { "br_FR", lcl_DATA_EURO },
154 { "la_VA", lcl_DATA_EURO },
155 { "cv_RU", lcl_DATA_EURO },
156 { "wa_BE", lcl_DATA_EURO },
157 { "fur_IT", lcl_DATA_EURO },
158 { "gsc_FR", lcl_DATA_EURO },
159 { "fy_NL", lcl_DATA_EURO },
160 { "oc_FR", lcl_DATA_EURO },
161 { "mt_MT", lcl_DATA_EURO },
162 { "sc_IT", lcl_DATA_EURO },
163 { "ast_ES", lcl_DATA_EURO },
164 { "ltg_LV", lcl_DATA_EURO },
165 { "hsb_DE", lcl_DATA_EURO },
166 { "dsb_DE", lcl_DATA_EURO },
167 { "rue_SK", lcl_DATA_EURO },
168 { "an_ES", lcl_DATA_EURO },
169 { "myv_RU", lcl_DATA_EURO },
171 { "ja_JP", lcl_DATA_OTHERS },
172 { "ko_KR", lcl_DATA_OTHERS },
173 { "zh_CN", lcl_DATA_OTHERS },
174 { "zh_HK", lcl_DATA_OTHERS },
175 { "zh_SG", lcl_DATA_OTHERS },
176 { "zh_TW", lcl_DATA_OTHERS },
177 { "zh_MO", lcl_DATA_OTHERS },
179 { "ar_EG", lcl_DATA_OTHERS },
180 { "ar_DZ", lcl_DATA_OTHERS },
181 { "ar_LB", lcl_DATA_OTHERS },
182 { "ar_SA", lcl_DATA_OTHERS },
183 { "ar_TN", lcl_DATA_OTHERS },
184 { "he_IL", lcl_DATA_OTHERS },
185 { "hi_IN", lcl_DATA_OTHERS },
186 { "kn_IN", lcl_DATA_OTHERS },
187 { "ta_IN", lcl_DATA_OTHERS },
188 { "te_IN", lcl_DATA_OTHERS },
189 { "gu_IN", lcl_DATA_OTHERS },
190 { "mr_IN", lcl_DATA_OTHERS },
191 { "pa_IN", lcl_DATA_OTHERS },
192 { "bn_IN", lcl_DATA_OTHERS },
193 { "or_IN", lcl_DATA_OTHERS },
194 { "en_IN", lcl_DATA_OTHERS },
195 { "ml_IN", lcl_DATA_OTHERS },
196 { "bn_BD", lcl_DATA_OTHERS },
197 { "th_TH", lcl_DATA_OTHERS },
199 { "af_ZA", lcl_DATA_OTHERS },
200 { "hu_HU", lcl_DATA_OTHERS },
201 { "id_ID", lcl_DATA_OTHERS },
202 { "ms_MY", lcl_DATA_OTHERS },
203 { "ia", lcl_DATA_OTHERS },
204 { "mn_MN", lcl_DATA_OTHERS },
205 { "az_AZ", lcl_DATA_OTHERS },
206 { "sw_TZ", lcl_DATA_OTHERS },
207 { "km_KH", lcl_DATA_OTHERS },
208 { "lo_LA", lcl_DATA_OTHERS },
209 { "rw_RW", lcl_DATA_OTHERS },
210 { "eo", lcl_DATA_OTHERS },
211 { "dz_BT", lcl_DATA_OTHERS },
212 { "ne_NP", lcl_DATA_OTHERS },
213 { "zu_ZA", lcl_DATA_OTHERS },
214 { "nso_ZA", lcl_DATA_OTHERS },
215 { "vi_VN", lcl_DATA_OTHERS },
216 { "tn_ZA", lcl_DATA_OTHERS },
217 { "xh_ZA", lcl_DATA_OTHERS },
218 { "st_ZA", lcl_DATA_OTHERS },
219 { "ss_ZA", lcl_DATA_OTHERS },
220 { "ve_ZA", lcl_DATA_OTHERS },
221 { "nr_ZA", lcl_DATA_OTHERS },
222 { "ts_ZA", lcl_DATA_OTHERS },
223 { "ku_TR", lcl_DATA_OTHERS },
224 { "ak_GH", lcl_DATA_OTHERS },
225 { "af_NA", lcl_DATA_OTHERS },
226 { "am_ET", lcl_DATA_OTHERS },
227 { "ti_ER", lcl_DATA_OTHERS },
228 { "tg_TJ", lcl_DATA_OTHERS },
229 { "ky_KG", lcl_DATA_OTHERS },
230 { "kk_KZ", lcl_DATA_OTHERS },
231 { "fa_IR", lcl_DATA_OTHERS },
232 { "ha_GH", lcl_DATA_OTHERS },
233 { "ee_GH", lcl_DATA_OTHERS },
234 { "sg_CF", lcl_DATA_OTHERS },
235 { "lg_UG", lcl_DATA_OTHERS },
236 { "uz_UZ", lcl_DATA_OTHERS },
237 { "ln_CD", lcl_DATA_OTHERS },
238 { "hy_AM", lcl_DATA_OTHERS },
239 { "hil_PH", lcl_DATA_OTHERS },
240 { "so_SO", lcl_DATA_OTHERS },
241 { "gug_PY", lcl_DATA_OTHERS },
242 { "tk_TM", lcl_DATA_OTHERS },
243 { "my_MM", lcl_DATA_OTHERS },
244 { "shs_CA", lcl_DATA_OTHERS },
245 { "tpi_PG", lcl_DATA_OTHERS },
246 { "ar_OM", lcl_DATA_OTHERS },
247 { "ug_CN", lcl_DATA_OTHERS },
248 { "om_ET", lcl_DATA_OTHERS },
249 { "plt_MG", lcl_DATA_OTHERS },
250 { "mai_IN", lcl_DATA_OTHERS },
251 { "yi_US", lcl_DATA_OTHERS },
252 { "haw_US", lcl_DATA_OTHERS },
253 { "lif_NP", lcl_DATA_OTHERS },
254 { "ur_PK", lcl_DATA_OTHERS },
255 { "ht_HT", lcl_DATA_OTHERS },
256 { "jbo", lcl_DATA_OTHERS },
257 { "kab_DZ", lcl_DATA_OTHERS },
258 { "pt_AO", lcl_DATA_OTHERS },
259 { "pjt_AU", lcl_DATA_OTHERS },
260 { "pap_CW", lcl_DATA_OTHERS },
261 { "ebo_CG", lcl_DATA_OTHERS },
262 { "tyx_CG", lcl_DATA_OTHERS },
263 { "axk_CG", lcl_DATA_OTHERS },
264 { "beq_CG", lcl_DATA_OTHERS },
265 { "bkw_CG", lcl_DATA_OTHERS },
266 { "bvx_CG", lcl_DATA_OTHERS },
267 { "dde_CG", lcl_DATA_OTHERS },
268 { "iyx_CG", lcl_DATA_OTHERS },
269 { "kkw_CG", lcl_DATA_OTHERS },
270 { "kng_CG", lcl_DATA_OTHERS },
271 { "ldi_CG", lcl_DATA_OTHERS },
272 { "mdw_CG", lcl_DATA_OTHERS },
273 { "mkw_CG", lcl_DATA_OTHERS },
274 { "njx_CG", lcl_DATA_OTHERS },
275 { "ngz_CG", lcl_DATA_OTHERS },
276 { "njy_CG", lcl_DATA_OTHERS },
277 { "puu_CG", lcl_DATA_OTHERS },
278 { "sdj_CG", lcl_DATA_OTHERS },
279 { "tek_CG", lcl_DATA_OTHERS },
280 { "tsa_CG", lcl_DATA_OTHERS },
281 { "vif_CG", lcl_DATA_OTHERS },
282 { "xku_CG", lcl_DATA_OTHERS },
283 { "yom_CG", lcl_DATA_OTHERS }
286 #else
288 #include "localedata_static.hxx"
290 #endif
292 static const sal_Unicode under = sal_Unicode('_');
294 static const sal_Int16 nbOfLocales = SAL_N_ELEMENTS(aLibTable);
296 struct LocaleDataLookupTableItem
298 LocaleDataLookupTableItem(const sal_Char *name, osl::Module* m, const sal_Char* lname) : dllName(name), module(m), localeName(lname)
301 const sal_Char* dllName;
302 osl::Module *module;
303 const sal_Char* localeName;
305 com::sun::star::lang::Locale aLocale;
306 sal_Bool equals(const com::sun::star::lang::Locale& rLocale)
308 return (rLocale == aLocale);
313 // static
314 Sequence< CalendarItem > LocaleData::downcastCalendarItems( const Sequence< CalendarItem2 > & rCi )
316 sal_Int32 nSize = rCi.getLength();
317 Sequence< CalendarItem > aCi( nSize);
318 CalendarItem* p1 = aCi.getArray();
319 const CalendarItem2* p2 = rCi.getConstArray();
320 for (sal_Int32 i=0; i < nSize; ++i, ++p1, ++p2)
321 *p1 = *p2;
322 return aCi;
326 // static
327 Calendar LocaleData::downcastCalendar( const Calendar2 & rC )
329 Calendar aCal(
330 downcastCalendarItems( rC.Days),
331 downcastCalendarItems( rC.Months),
332 downcastCalendarItems( rC.Eras),
333 rC.StartOfWeek,
334 rC.MinimumNumberOfDaysForFirstWeek,
335 rC.Default,
336 rC.Name
338 return aCal;
342 LocaleData::LocaleData()
345 LocaleData::~LocaleData()
350 LocaleDataItem SAL_CALL
351 LocaleData::getLocaleItem( const Locale& rLocale ) throw(RuntimeException)
353 sal_Unicode **dataItem = NULL;
355 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getLocaleItem" );
357 if ( func ) {
358 sal_Int16 dataItemCount = 0;
359 dataItem = func(dataItemCount);
361 LocaleDataItem item(
362 dataItem[0],
363 dataItem[1],
364 dataItem[2],
365 dataItem[3],
366 dataItem[4],
367 dataItem[5],
368 dataItem[6],
369 dataItem[7],
370 dataItem[8],
371 dataItem[9],
372 dataItem[10],
373 dataItem[11],
374 dataItem[12],
375 dataItem[13],
376 dataItem[14],
377 dataItem[15],
378 dataItem[16],
379 dataItem[17]
381 return item;
383 else {
384 LocaleDataItem item1;
385 return item1;
389 #ifndef DISABLE_DYNLOADING
391 extern "C" { static void SAL_CALL thisModule() {} }
393 #endif
395 namespace
398 // implement the lookup table as a safe static object
399 class lcl_LookupTableHelper
401 public:
402 lcl_LookupTableHelper();
403 ~lcl_LookupTableHelper();
405 oslGenericFunction SAL_CALL getFunctionSymbolByName(
406 const OUString& localeName, const sal_Char* pFunction,
407 LocaleDataLookupTableItem** pOutCachedItem );
409 private:
410 ::osl::Mutex maMutex;
411 ::std::vector< LocaleDataLookupTableItem* > maLookupTable;
414 // from instance.hxx: Helper base class for a late-initialized
415 // (default-constructed) static variable, implementing the double-checked
416 // locking pattern correctly.
417 // usage: lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get();
418 // retrieves the singleton lookup table instance
419 struct lcl_LookupTableStatic : public ::rtl::Static< lcl_LookupTableHelper, lcl_LookupTableStatic >
422 lcl_LookupTableHelper::lcl_LookupTableHelper()
426 lcl_LookupTableHelper::~lcl_LookupTableHelper()
428 LocaleDataLookupTableItem* pItem = 0;
430 std::vector<LocaleDataLookupTableItem*>::const_iterator aEnd(maLookupTable.end());
431 std::vector<LocaleDataLookupTableItem*>::iterator aIter(maLookupTable.begin());
433 for ( ; aIter != aEnd; ++aIter ) {
434 pItem = *aIter;
435 delete pItem->module;
436 delete pItem;
438 maLookupTable.clear();
441 oslGenericFunction SAL_CALL lcl_LookupTableHelper::getFunctionSymbolByName(
442 const OUString& localeName, const sal_Char* pFunction,
443 LocaleDataLookupTableItem** pOutCachedItem )
445 OUString aFallback;
446 bool bFallback = (localeName.indexOf( under) < 0);
447 if (bFallback)
449 Locale aLocale;
450 aLocale.Language = localeName;
451 Locale aFbLocale = MsLangId::getFallbackLocale( aLocale);
452 if (aFbLocale == aLocale)
453 bFallback = false; // may be a "language-only-locale" like Interlingua (ia)
454 else if (!aFbLocale.Country.isEmpty()) {
455 OUStringBuffer aBuf(5);
456 aFallback = aBuf.append(aFbLocale.Language).append( under).append(aFbLocale.Country).makeStringAndClear();
458 else
459 aFallback = aFbLocale.Language;
462 for ( sal_Int16 i = 0; i < nbOfLocales; i++)
464 if (localeName.equalsAscii(aLibTable[i].pLocale) ||
465 (bFallback && aFallback.equalsAscii(aLibTable[i].pLocale)))
467 #ifndef DISABLE_DYNLOADING
468 LocaleDataLookupTableItem* pCurrent = 0;
469 OUStringBuffer aBuf(strlen(aLibTable[i].pLocale) + 1 + strlen(pFunction));
471 ::osl::MutexGuard aGuard( maMutex );
472 for (size_t l = 0; l < maLookupTable.size(); l++)
474 pCurrent = maLookupTable[l];
475 if (pCurrent->dllName == aLibTable[i].pLib)
477 OSL_ASSERT( pOutCachedItem );
478 if( pOutCachedItem )
480 (*pOutCachedItem) = new LocaleDataLookupTableItem( *pCurrent );
481 (*pOutCachedItem)->localeName = aLibTable[i].pLocale;
482 return (*pOutCachedItem)->module->getFunctionSymbol(
483 aBuf.appendAscii( pFunction).append( under).
484 appendAscii( (*pOutCachedItem)->localeName).makeStringAndClear());
486 else
487 return NULL;
491 // Library not loaded, load it and add it to the list.
492 #ifdef SAL_DLLPREFIX
493 aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 6); // mostly "lib*.so"
494 aBuf.appendAscii( SAL_DLLPREFIX ).appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION );
495 #else
496 aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 4); // mostly "*.dll"
497 aBuf.appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION );
498 #endif
499 osl::Module *module = new osl::Module();
500 if ( module->loadRelative(&thisModule, aBuf.makeStringAndClear()) )
502 ::osl::MutexGuard aGuard( maMutex );
503 LocaleDataLookupTableItem* pNewItem = new LocaleDataLookupTableItem(aLibTable[i].pLib, module, aLibTable[i].pLocale);
504 maLookupTable.push_back(pNewItem);
505 OSL_ASSERT( pOutCachedItem );
506 if( pOutCachedItem )
508 (*pOutCachedItem) = new LocaleDataLookupTableItem( *pNewItem );
509 return module->getFunctionSymbol(
510 aBuf.appendAscii(pFunction).append(under).
511 appendAscii((*pOutCachedItem)->localeName).makeStringAndClear());
513 else
514 return NULL;
516 else
517 delete module;
518 #else
519 (void) pOutCachedItem;
521 if( strcmp(pFunction, "getAllCalendars") == 0 )
522 return aLibTable[i].getAllCalendars;
523 else if( strcmp(pFunction, "getAllCurrencies") == 0 )
524 return aLibTable[i].getAllCurrencies;
525 else if( strcmp(pFunction, "getAllFormats0") == 0 )
526 return aLibTable[i].getAllFormats0;
527 else if( strcmp(pFunction, "getBreakIteratorRules") == 0 )
528 return aLibTable[i].getBreakIteratorRules;
529 else if( strcmp(pFunction, "getCollationOptions") == 0 )
530 return aLibTable[i].getCollationOptions;
531 else if( strcmp(pFunction, "getCollatorImplementation") == 0 )
532 return aLibTable[i].getCollatorImplementation;
533 else if( strcmp(pFunction, "getContinuousNumberingLevels") == 0 )
534 return aLibTable[i].getContinuousNumberingLevels;
535 else if( strcmp(pFunction, "getDateAcceptancePatterns") == 0 )
536 return aLibTable[i].getDateAcceptancePatterns;
537 else if( strcmp(pFunction, "getFollowPageWords") == 0 )
538 return aLibTable[i].getFollowPageWords;
539 else if( strcmp(pFunction, "getForbiddenCharacters") == 0 )
540 return aLibTable[i].getForbiddenCharacters;
541 else if( strcmp(pFunction, "getIndexAlgorithm") == 0 )
542 return aLibTable[i].getIndexAlgorithm;
543 else if( strcmp(pFunction, "getLCInfo") == 0 )
544 return aLibTable[i].getLCInfo;
545 else if( strcmp(pFunction, "getLocaleItem") == 0 )
546 return aLibTable[i].getLocaleItem;
547 else if( strcmp(pFunction, "getOutlineNumberingLevels") == 0 )
548 return aLibTable[i].getOutlineNumberingLevels;
549 else if( strcmp(pFunction, "getReservedWords") == 0 )
550 return aLibTable[i].getReservedWords;
551 else if( strcmp(pFunction, "getSearchOptions") == 0 )
552 return aLibTable[i].getSearchOptions;
553 else if( strcmp(pFunction, "getTransliterations") == 0 )
554 return aLibTable[i].getTransliterations;
555 else if( strcmp(pFunction, "getUnicodeScripts") == 0 )
556 return aLibTable[i].getUnicodeScripts;
557 else if( strcmp(pFunction, "getAllFormats1") == 0 )
558 return aLibTable[i].getAllFormats1;
559 #endif
562 return NULL;
565 } // anonymous namespace
568 // REF values equal offsets of counts within getAllCalendars() data structure!
569 #define REF_DAYS 0
570 #define REF_MONTHS 1
571 #define REF_GMONTHS 2
572 #define REF_PMONTHS 3
573 #define REF_ERAS 4
574 #define REF_OFFSET_COUNT 5
576 Sequence< CalendarItem2 > &LocaleData::getCalendarItemByName(const OUString& name,
577 const Locale& rLocale, const Sequence< Calendar2 >& calendarsSeq, sal_Int16 item)
578 throw(RuntimeException)
580 if (!ref_name.equals(name)) {
581 sal_Int32 index = 0;
582 OUString language = name.getToken(0, under, index);
583 OUString country = name.getToken(0, under, index);
584 Locale loc(language, country, OUString());
585 Sequence < Calendar2 > cals;
586 if (loc == rLocale) {
587 cals = calendarsSeq;
588 } else {
589 cals = getAllCalendars2(loc);
591 const OUString& id = name.getToken(0, under, index);
592 for (index = 0; index < cals.getLength(); index++) {
593 if (id.equals(cals[index].Name)) {
594 ref_cal = cals[index];
595 break;
598 // Referred locale not found, return name for en_US locale.
599 if (index == cals.getLength()) {
600 cals = getAllCalendars2(
601 Locale(OUString("en"), OUString("US"), OUString()));
602 if (cals.getLength() > 0)
603 ref_cal = cals[0];
604 else
605 throw RuntimeException();
607 ref_name = name;
609 switch (item)
611 case REF_DAYS:
612 return ref_cal.Days;
613 case REF_MONTHS:
614 return ref_cal.Months;
615 case REF_GMONTHS:
616 return ref_cal.GenitiveMonths;
617 case REF_PMONTHS:
618 return ref_cal.PartitiveMonths;
619 default:
620 OSL_FAIL( "LocaleData::getCalendarItemByName: unhandled REF_* case");
621 // fallthru
622 case REF_ERAS:
623 return ref_cal.Eras;
628 Sequence< CalendarItem2 > LocaleData::getCalendarItems(
629 sal_Unicode const * const * const allCalendars, sal_Int16 & rnOffset,
630 const sal_Int16 nWhichItem, const sal_Int16 nCalendar,
631 const Locale & rLocale, const Sequence< Calendar2 > & calendarsSeq )
632 throw(RuntimeException)
634 Sequence< CalendarItem2 > aItems;
635 if ( OUString( allCalendars[rnOffset] ) == "ref" )
637 aItems = getCalendarItemByName( OUString( allCalendars[rnOffset+1]), rLocale, calendarsSeq, nWhichItem);
638 rnOffset += 2;
640 else
642 sal_Int32 nSize = allCalendars[nWhichItem][nCalendar];
643 aItems.realloc( nSize);
644 CalendarItem2* pItem = aItems.getArray();
645 switch (nWhichItem)
647 case REF_DAYS:
648 case REF_MONTHS:
649 case REF_GMONTHS:
650 case REF_PMONTHS:
651 for (sal_Int16 j = 0; j < nSize; ++j, ++pItem)
653 CalendarItem2 item( allCalendars[rnOffset], allCalendars[rnOffset+1],
654 allCalendars[rnOffset+2], allCalendars[rnOffset+3]);
655 *pItem = item;
656 rnOffset += 4;
658 break;
659 case REF_ERAS:
660 // Absent narrow name.
661 for (sal_Int16 j = 0; j < nSize; ++j, ++pItem)
663 CalendarItem2 item( allCalendars[rnOffset], allCalendars[rnOffset+1],
664 allCalendars[rnOffset+2], OUString());
665 *pItem = item;
666 rnOffset += 3;
668 break;
669 default:
670 OSL_FAIL( "LocaleData::getCalendarItems: unhandled REF_* case");
673 return aItems;
677 Sequence< Calendar2 > SAL_CALL
678 LocaleData::getAllCalendars2( const Locale& rLocale ) throw(RuntimeException)
681 sal_Unicode const * const * allCalendars = NULL;
683 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getAllCalendars" );
685 if ( func ) {
686 sal_Int16 calendarsCount = 0;
687 allCalendars = func(calendarsCount);
689 Sequence< Calendar2 > calendarsSeq(calendarsCount);
690 sal_Int16 offset = REF_OFFSET_COUNT;
691 for(sal_Int16 i = 0; i < calendarsCount; i++) {
692 OUString calendarID(allCalendars[offset]);
693 offset++;
694 sal_Bool defaultCalendar = sal::static_int_cast<sal_Bool>( allCalendars[offset][0] );
695 offset++;
696 Sequence< CalendarItem2 > days = getCalendarItems( allCalendars, offset, REF_DAYS, i,
697 rLocale, calendarsSeq);
698 Sequence< CalendarItem2 > months = getCalendarItems( allCalendars, offset, REF_MONTHS, i,
699 rLocale, calendarsSeq);
700 Sequence< CalendarItem2 > gmonths = getCalendarItems( allCalendars, offset, REF_GMONTHS, i,
701 rLocale, calendarsSeq);
702 Sequence< CalendarItem2 > pmonths = getCalendarItems( allCalendars, offset, REF_PMONTHS, i,
703 rLocale, calendarsSeq);
704 Sequence< CalendarItem2 > eras = getCalendarItems( allCalendars, offset, REF_ERAS, i,
705 rLocale, calendarsSeq);
706 OUString startOfWeekDay(allCalendars[offset]);
707 offset++;
708 sal_Int16 minimalDaysInFirstWeek = allCalendars[offset][0];
709 offset++;
710 Calendar2 aCalendar(days, months, gmonths, pmonths, eras, startOfWeekDay,
711 minimalDaysInFirstWeek, defaultCalendar, calendarID);
712 calendarsSeq[i] = aCalendar;
714 return calendarsSeq;
716 else {
717 Sequence< Calendar2 > seq1(0);
718 return seq1;
723 Sequence< Calendar > SAL_CALL
724 LocaleData::getAllCalendars( const Locale& rLocale ) throw(RuntimeException)
726 const Sequence< Calendar2 > aCal2( getAllCalendars2( rLocale));
727 sal_Int32 nLen = aCal2.getLength();
728 Sequence< Calendar > aCal1( nLen);
729 const Calendar2* p2 = aCal2.getConstArray();
730 Calendar* p1 = aCal1.getArray();
731 for (sal_Int32 i=0; i < nLen; ++i, ++p1, ++p2)
733 *p1 = downcastCalendar( *p2);
735 return aCal1;
739 Sequence< Currency2 > SAL_CALL
740 LocaleData::getAllCurrencies2( const Locale& rLocale ) throw(RuntimeException)
742 sal_Unicode **allCurrencies = NULL;
744 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getAllCurrencies" );
746 if ( func ) {
747 sal_Int16 currencyCount = 0;
748 allCurrencies = func(currencyCount);
750 Sequence< Currency2 > seq(currencyCount);
751 for(int i = 0, nOff = 0; i < currencyCount; i++, nOff += 8 ) {
752 Currency2 cur(
753 allCurrencies[nOff], // string ID
754 allCurrencies[nOff+1], // string Symbol
755 allCurrencies[nOff+2], // string BankSymbol
756 allCurrencies[nOff+3], // string Name
757 allCurrencies[nOff+4][0] != 0, // boolean Default
758 allCurrencies[nOff+5][0] != 0, // boolean UsedInCompatibleFormatCodes
759 allCurrencies[nOff+6][0], // short DecimalPlaces
760 allCurrencies[nOff+7][0] != 0 // boolean LegacyOnly
762 seq[i] = cur;
764 return seq;
766 else {
767 Sequence< Currency2 > seq1(0);
768 return seq1;
773 Sequence< Currency > SAL_CALL
774 LocaleData::getAllCurrencies( const Locale& rLocale ) throw(RuntimeException)
776 Sequence< Currency2 > aCur2( getAllCurrencies2( rLocale));
777 sal_Int32 nLen = aCur2.getLength();
778 Sequence< Currency > aCur1( nLen);
779 const Currency2* p2 = aCur2.getArray();
780 Currency* p1 = aCur1.getArray();
781 for (sal_Int32 i=0; i < nLen; ++i, ++p1, ++p2)
783 *p1 = *p2;
785 return aCur1;
789 // return a static (!) string resulting from replacing all occurrences of
790 // 'oldStr' string in 'formatCode' string with 'newStr' string
791 static const sal_Unicode * replace( sal_Unicode const * const formatCode, sal_Unicode const * const oldStr, sal_Unicode const * const newStr)
793 // make reasonable assumption of maximum length of formatCode.
794 #define MAX_FORMATCODE_LENTH 512
795 static sal_Unicode str[MAX_FORMATCODE_LENTH];
797 if (oldStr[0] == 0) // no replacement requires
798 return formatCode;
800 sal_Int32 i = 0, k = 0;
801 while (formatCode[i] > 0 && k < MAX_FORMATCODE_LENTH) {
802 sal_Int32 j = 0, last = k;
803 // search oldStr in formatCode
804 while (formatCode[i] > 0 && oldStr[j] > 0 && k < MAX_FORMATCODE_LENTH) {
805 str[k++] = formatCode[i];
806 if (formatCode[i++] != oldStr[j++])
807 break;
809 if (oldStr[j] == 0) {
810 // matched string found, do replacement
811 k = last; j = 0;
812 while (newStr[j] > 0 && k < MAX_FORMATCODE_LENTH)
813 str[k++] = newStr[j++];
816 if (k >= MAX_FORMATCODE_LENTH) // could not complete replacement, return original formatCode
817 return formatCode;
819 str[k] = 0;
820 return str;
823 Sequence< FormatElement > SAL_CALL
824 LocaleData::getAllFormats( const Locale& rLocale ) throw(RuntimeException)
826 const int SECTIONS = 2;
827 struct FormatSection
829 MyFunc_FormatCode func;
830 sal_Unicode const *from;
831 sal_Unicode const *to;
832 sal_Unicode const *const *formatArray;
833 sal_Int16 formatCount;
835 FormatSection() : func(0), from(0), to(0), formatArray(0), formatCount(0) {}
836 sal_Int16 getFunc( LocaleData& rLocaleData, const Locale& rL, const char* pName )
838 func = reinterpret_cast<MyFunc_FormatCode>( rLocaleData.getFunctionSymbol( rL, pName));
839 if (func)
840 formatArray = func( formatCount, from, to);
841 return formatCount;
843 } section[SECTIONS];
845 sal_Int32 formatCount;
846 formatCount = section[0].getFunc( *this, rLocale, "getAllFormats0");
847 formatCount += section[1].getFunc( *this, rLocale, "getAllFormats1");
849 Sequence< FormatElement > seq(formatCount);
850 sal_Int32 f = 0;
851 for (int s = 0; s < SECTIONS; ++s)
853 sal_Unicode const * const * const formatArray = section[s].formatArray;
854 if ( formatArray )
856 for (int i = 0, nOff = 0; i < section[s].formatCount; ++i, nOff += 7, ++f)
858 FormatElement elem(
859 replace( formatArray[nOff], section[s].from, section[s].to),
860 formatArray[nOff + 1],
861 formatArray[nOff + 2],
862 formatArray[nOff + 3],
863 formatArray[nOff + 4],
864 formatArray[nOff + 5][0],
865 sal::static_int_cast<sal_Bool>(formatArray[nOff + 6][0]));
866 seq[f] = elem;
870 return seq;
874 Sequence< OUString > SAL_CALL
875 LocaleData::getDateAcceptancePatterns( const Locale& rLocale ) throw(RuntimeException)
877 sal_Unicode **patternsArray = NULL;
879 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getDateAcceptancePatterns" );
881 if (func)
883 sal_Int16 patternsCount = 0;
884 patternsArray = func( patternsCount );
885 Sequence< OUString > seq( patternsCount );
886 for (sal_Int16 i = 0; i < patternsCount; ++i)
888 seq[i] = OUString( patternsArray[i] );
890 return seq;
892 else
894 Sequence< OUString > seq(0);
895 return seq;
900 #define COLLATOR_OFFSET_ALGO 0
901 #define COLLATOR_OFFSET_DEFAULT 1
902 #define COLLATOR_OFFSET_RULE 2
903 #define COLLATOR_ELEMENTS 3
905 OUString SAL_CALL
906 LocaleData::getCollatorRuleByAlgorithm( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException)
908 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getCollatorImplementation" );
909 if ( func ) {
910 sal_Int16 collatorCount = 0;
911 sal_Unicode **collatorArray = func(collatorCount);
912 for(sal_Int16 i = 0; i < collatorCount; i++)
913 if (algorithm.equals(collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_ALGO]))
914 return OUString(collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_RULE]);
916 return OUString();
920 Sequence< Implementation > SAL_CALL
921 LocaleData::getCollatorImplementations( const Locale& rLocale ) throw(RuntimeException)
923 sal_Unicode **collatorArray = NULL;
925 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getCollatorImplementation" );
927 if ( func ) {
928 sal_Int16 collatorCount = 0;
929 collatorArray = func(collatorCount);
930 Sequence< Implementation > seq(collatorCount);
931 for(sal_Int16 i = 0; i < collatorCount; i++) {
932 Implementation impl(collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_ALGO],
933 sal::static_int_cast<sal_Bool>(
934 collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_DEFAULT][0]));
935 seq[i] = impl;
937 return seq;
939 else {
940 Sequence< Implementation > seq1(0);
941 return seq1;
945 Sequence< OUString > SAL_CALL
946 LocaleData::getCollationOptions( const Locale& rLocale ) throw(RuntimeException)
948 sal_Unicode **optionsArray = NULL;
950 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getCollationOptions" );
952 if ( func ) {
953 sal_Int16 optionsCount = 0;
954 optionsArray = func(optionsCount);
955 Sequence< OUString > seq(optionsCount);
956 for(sal_Int16 i = 0; i < optionsCount; i++) {
957 seq[i] = OUString( optionsArray[i] );
959 return seq;
961 else {
962 Sequence< OUString > seq1(0);
963 return seq1;
967 Sequence< OUString > SAL_CALL
968 LocaleData::getSearchOptions( const Locale& rLocale ) throw(RuntimeException)
970 sal_Unicode **optionsArray = NULL;
972 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getSearchOptions" );
974 if ( func ) {
975 sal_Int16 optionsCount = 0;
976 optionsArray = func(optionsCount);
977 Sequence< OUString > seq(optionsCount);
978 for(sal_Int16 i = 0; i < optionsCount; i++) {
979 seq[i] = OUString( optionsArray[i] );
981 return seq;
983 else {
984 Sequence< OUString > seq1(0);
985 return seq1;
989 sal_Unicode ** SAL_CALL
990 LocaleData::getIndexArray(const Locale& rLocale, sal_Int16& indexCount)
992 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getIndexAlgorithm" );
994 if (func)
995 return func(indexCount);
996 return NULL;
999 Sequence< OUString > SAL_CALL
1000 LocaleData::getIndexAlgorithm( const Locale& rLocale ) throw(RuntimeException)
1002 sal_Int16 indexCount = 0;
1003 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount);
1005 if ( indexArray ) {
1006 Sequence< OUString > seq(indexCount);
1007 for(sal_Int16 i = 0; i < indexCount; i++) {
1008 seq[i] = indexArray[i*5];
1010 return seq;
1012 else {
1013 Sequence< OUString > seq1(0);
1014 return seq1;
1018 OUString SAL_CALL
1019 LocaleData::getDefaultIndexAlgorithm( const Locale& rLocale ) throw(RuntimeException)
1021 sal_Int16 indexCount = 0;
1022 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount);
1024 if ( indexArray ) {
1025 for(sal_Int16 i = 0; i < indexCount; i++) {
1026 if (indexArray[i*5 + 3][0])
1027 return OUString(indexArray[i*5]);
1030 return OUString();
1033 sal_Bool SAL_CALL
1034 LocaleData::hasPhonetic( const Locale& rLocale ) throw(RuntimeException)
1036 sal_Int16 indexCount = 0;
1037 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount);
1039 if ( indexArray ) {
1040 for(sal_Int16 i = 0; i < indexCount; i++) {
1041 if (indexArray[i*5 + 4][0])
1042 return sal_True;
1045 return sal_False;
1048 sal_Unicode ** SAL_CALL
1049 LocaleData::getIndexArrayForAlgorithm(const Locale& rLocale, const OUString& algorithm)
1051 sal_Int16 indexCount = 0;
1052 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount);
1053 if ( indexArray ) {
1054 for(sal_Int16 i = 0; i < indexCount; i++) {
1055 if (algorithm.equals(indexArray[i*5]))
1056 return indexArray+i*5;
1059 return NULL;
1062 sal_Bool SAL_CALL
1063 LocaleData::isPhonetic( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException)
1065 sal_Unicode **indexArray = getIndexArrayForAlgorithm(rLocale, algorithm);
1066 return (indexArray && indexArray[4][0]) ? sal_True : sal_False;
1069 OUString SAL_CALL
1070 LocaleData::getIndexKeysByAlgorithm( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException)
1072 sal_Unicode **indexArray = getIndexArrayForAlgorithm(rLocale, algorithm);
1073 return indexArray ? OUString("0-9")+OUString(indexArray[2]) : OUString();
1076 OUString SAL_CALL
1077 LocaleData::getIndexModuleByAlgorithm( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException)
1079 sal_Unicode **indexArray = getIndexArrayForAlgorithm(rLocale, algorithm);
1080 return indexArray ? OUString(indexArray[1]) : OUString();
1083 Sequence< UnicodeScript > SAL_CALL
1084 LocaleData::getUnicodeScripts( const Locale& rLocale ) throw(RuntimeException)
1086 sal_Unicode **scriptArray = NULL;
1088 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getUnicodeScripts" );
1090 if ( func ) {
1091 sal_Int16 scriptCount = 0;
1092 scriptArray = func(scriptCount);
1093 Sequence< UnicodeScript > seq(scriptCount);
1094 for(sal_Int16 i = 0; i < scriptCount; i++) {
1095 seq[i] = UnicodeScript( OUString(scriptArray[i]).toInt32() );
1097 return seq;
1099 else {
1100 Sequence< UnicodeScript > seq1(0);
1101 return seq1;
1105 Sequence< OUString > SAL_CALL
1106 LocaleData::getFollowPageWords( const Locale& rLocale ) throw(RuntimeException)
1108 sal_Unicode **wordArray = NULL;
1110 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getFollowPageWords" );
1112 if ( func ) {
1113 sal_Int16 wordCount = 0;
1114 wordArray = func(wordCount);
1115 Sequence< OUString > seq(wordCount);
1116 for(sal_Int16 i = 0; i < wordCount; i++) {
1117 seq[i] = OUString(wordArray[i]);
1119 return seq;
1121 else {
1122 Sequence< OUString > seq1(0);
1123 return seq1;
1127 Sequence< OUString > SAL_CALL
1128 LocaleData::getTransliterations( const Locale& rLocale ) throw(RuntimeException)
1131 sal_Unicode **transliterationsArray = NULL;
1133 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getTransliterations" );
1135 if ( func ) {
1136 sal_Int16 transliterationsCount = 0;
1137 transliterationsArray = func(transliterationsCount);
1139 Sequence< OUString > seq(transliterationsCount);
1140 for(int i = 0; i < transliterationsCount; i++) {
1141 OUString elem(transliterationsArray[i]);
1142 seq[i] = elem;
1144 return seq;
1146 else {
1147 Sequence< OUString > seq1(0);
1148 return seq1;
1155 LanguageCountryInfo SAL_CALL
1156 LocaleData::getLanguageCountryInfo( const Locale& rLocale ) throw(RuntimeException)
1159 sal_Unicode **LCInfoArray = NULL;
1161 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getLCInfo" );
1163 if ( func ) {
1164 sal_Int16 LCInfoCount = 0;
1165 LCInfoArray = func(LCInfoCount);
1166 LanguageCountryInfo info(LCInfoArray[0],
1167 LCInfoArray[1],
1168 LCInfoArray[2],
1169 LCInfoArray[3],
1170 LCInfoArray[4]);
1171 return info;
1173 else {
1174 LanguageCountryInfo info1;
1175 return info1;
1181 ForbiddenCharacters SAL_CALL
1182 LocaleData::getForbiddenCharacters( const Locale& rLocale ) throw(RuntimeException)
1184 sal_Unicode **LCForbiddenCharactersArray = NULL;
1186 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getForbiddenCharacters" );
1188 if ( func ) {
1189 sal_Int16 LCForbiddenCharactersCount = 0;
1190 LCForbiddenCharactersArray = func(LCForbiddenCharactersCount);
1191 ForbiddenCharacters chars(LCForbiddenCharactersArray[0], LCForbiddenCharactersArray[1]);
1192 return chars;
1194 else {
1195 ForbiddenCharacters chars1;
1196 return chars1;
1200 OUString SAL_CALL
1201 LocaleData::getHangingCharacters( const Locale& rLocale ) throw(RuntimeException)
1203 sal_Unicode **LCForbiddenCharactersArray = NULL;
1205 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getForbiddenCharacters" );
1207 if ( func ) {
1208 sal_Int16 LCForbiddenCharactersCount = 0;
1209 LCForbiddenCharactersArray = func(LCForbiddenCharactersCount);
1210 return OUString(LCForbiddenCharactersArray[2]);
1213 return OUString();
1216 Sequence< OUString > SAL_CALL
1217 LocaleData::getBreakIteratorRules( const Locale& rLocale ) throw(RuntimeException)
1219 sal_Unicode **LCBreakIteratorRulesArray = NULL;
1221 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getBreakIteratorRules" );
1223 if ( func ) {
1224 sal_Int16 LCBreakIteratorRuleCount = 0;
1225 LCBreakIteratorRulesArray = func(LCBreakIteratorRuleCount);
1226 Sequence< OUString > seq(LCBreakIteratorRuleCount);
1227 for(int i = 0; i < (LCBreakIteratorRuleCount); i++) {
1228 OUString elem(LCBreakIteratorRulesArray[i]);
1229 seq[i] = elem;
1231 return seq;
1233 else {
1234 Sequence< OUString > seq1(0);
1235 return seq1;
1240 Sequence< OUString > SAL_CALL
1241 LocaleData::getReservedWord( const Locale& rLocale ) throw(RuntimeException)
1243 sal_Unicode **LCReservedWordsArray = NULL;
1245 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getReservedWords" );
1247 if ( func ) {
1248 sal_Int16 LCReservedWordsCount = 0;
1249 LCReservedWordsArray = func(LCReservedWordsCount);
1250 Sequence< OUString > seq(LCReservedWordsCount);
1251 for(int i = 0; i < (LCReservedWordsCount); i++) {
1252 OUString elem(LCReservedWordsArray[i]);
1253 seq[i] = elem;
1255 return seq;
1257 else {
1258 Sequence< OUString > seq1(0);
1259 return seq1;
1264 inline OUString C2U( const char* s )
1266 return OUString::createFromAscii( s );
1269 Sequence< Sequence<beans::PropertyValue> > SAL_CALL
1270 LocaleData::getContinuousNumberingLevels( const lang::Locale& rLocale ) throw(RuntimeException)
1272 // load symbol
1273 MyFunc_Type2 func = (MyFunc_Type2) getFunctionSymbol( rLocale, "getContinuousNumberingLevels" );
1275 if ( func )
1277 int i;
1278 // invoke function
1279 sal_Int16 nStyles;
1280 sal_Int16 nAttributes;
1281 sal_Unicode*** p0 = func( nStyles, nAttributes );
1283 // allocate memory for nAttributes attributes for each of the nStyles styles.
1284 Sequence< Sequence<beans::PropertyValue> > pv( nStyles );
1285 for( i=0; i<pv.getLength(); i++ ) {
1286 pv[i] = Sequence<beans::PropertyValue>( nAttributes );
1289 sal_Unicode*** pStyle = p0;
1290 for( i=0; i<nStyles; i++ ) {
1291 sal_Unicode** pAttribute = pStyle[i];
1292 for( int j=0; j<nAttributes; j++ ) { // prefix, numberingtype, ...
1293 sal_Unicode* pString = pAttribute[j];
1294 beans::PropertyValue& rVal = pv[i][j];
1295 OUString sVal;
1296 if( pString ) {
1297 if( 0 != j && 2 != j )
1298 sVal = pString;
1299 else if( *pString )
1300 sVal = OUString( pString, 1 );
1303 switch( j )
1305 case 0:
1306 rVal.Name = C2U("Prefix");
1307 rVal.Value <<= sVal;
1308 break;
1309 case 1:
1310 rVal.Name = C2U("NumberingType");
1311 rVal.Value <<= (sal_Int16) sVal.toInt32();
1312 break;
1313 case 2:
1314 rVal.Name = C2U("Suffix");
1315 rVal.Value <<= sVal;
1316 break;
1317 case 3:
1318 rVal.Name = C2U("Transliteration");
1319 rVal.Value <<= sVal;
1320 break;
1321 case 4:
1322 rVal.Name = C2U("NatNum");
1323 rVal.Value <<= (sal_Int16) sVal.toInt32();
1324 break;
1325 default:
1326 OSL_ASSERT(0);
1330 return pv;
1333 Sequence< Sequence<beans::PropertyValue> > seq1(0);
1334 return seq1;
1337 // OutlineNumbering helper class
1339 #include <com/sun/star/container/XIndexAccess.hpp>
1340 #include <cppuhelper/implbase1.hxx>
1342 namespace com{ namespace sun{ namespace star{ namespace lang {
1343 struct Locale;
1344 }}}}
1345 //-----------------------------------------------------------------------------
1346 struct OutlineNumberingLevel_Impl
1348 OUString sPrefix;
1349 sal_Int16 nNumType; //com::sun::star::style::NumberingType
1350 OUString sSuffix;
1351 sal_Unicode cBulletChar;
1352 const sal_Char* sBulletFontName;
1353 sal_Int16 nParentNumbering;
1354 sal_Int32 nLeftMargin;
1355 sal_Int32 nSymbolTextDistance;
1356 sal_Int32 nFirstLineOffset;
1357 OUString sTransliteration;
1358 sal_Int32 nNatNum;
1361 class OutlineNumbering : public cppu::WeakImplHelper1 < container::XIndexAccess >
1363 // OutlineNumbering helper class
1365 const OutlineNumberingLevel_Impl* m_pOutlineLevels;
1366 sal_Int16 m_nCount;
1367 public:
1368 OutlineNumbering(const OutlineNumberingLevel_Impl* pOutlineLevels, int nLevels);
1369 ~OutlineNumbering();
1371 //XIndexAccess
1372 virtual sal_Int32 SAL_CALL getCount( ) throw(RuntimeException);
1373 virtual Any SAL_CALL getByIndex( sal_Int32 Index )
1374 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException);
1376 //XElementAccess
1377 virtual Type SAL_CALL getElementType( ) throw(RuntimeException);
1378 virtual sal_Bool SAL_CALL hasElements( ) throw(RuntimeException);
1381 static sal_Char* U2C( OUString str )
1383 sal_Char* s = new sal_Char[ str.getLength()+1 ];
1384 int i;
1385 for( i = 0; i < str.getLength(); i++)
1386 s[i] = sal::static_int_cast<sal_Char>( str[i] );
1387 s[i]='\0';
1388 return s;
1392 Sequence< Reference<container::XIndexAccess> > SAL_CALL
1393 LocaleData::getOutlineNumberingLevels( const lang::Locale& rLocale ) throw(RuntimeException)
1395 // load symbol
1396 MyFunc_Type3 func = (MyFunc_Type3) getFunctionSymbol( rLocale, "getOutlineNumberingLevels" );
1398 if ( func )
1400 int i;
1401 // invoke function
1402 sal_Int16 nStyles;
1403 sal_Int16 nLevels;
1404 sal_Int16 nAttributes;
1405 sal_Unicode**** p0 = func( nStyles, nLevels, nAttributes );
1407 Sequence< Reference<container::XIndexAccess> > aRet( nStyles );
1409 OUString aEmptyStr;
1411 sal_Unicode**** pStyle = p0;
1412 for( i=0; i<nStyles; i++ )
1414 int j;
1416 OutlineNumberingLevel_Impl* level = new OutlineNumberingLevel_Impl[ nLevels+1 ];
1417 sal_Unicode*** pLevel = pStyle[i];
1418 for( j = 0; j < nLevels; j++ )
1420 sal_Unicode** pAttribute = pLevel[j];
1421 for( int k=0; k<nAttributes; k++ )
1423 OUString tmp( pAttribute[k] );
1424 switch( k )
1426 case 0: level[j].sPrefix = tmp; break;
1427 case 1: level[j].nNumType = sal::static_int_cast<sal_Int16>(tmp.toInt32()); break;
1428 case 2: level[j].sSuffix = tmp; break;
1429 case 3: level[j].cBulletChar = sal::static_int_cast<sal_Unicode>(tmp.toInt32(16)); break; // base 16
1430 case 4: level[j].sBulletFontName = U2C( tmp ); break;
1431 case 5: level[j].nParentNumbering = sal::static_int_cast<sal_Int16>(tmp.toInt32()); break;
1432 case 6: level[j].nLeftMargin = tmp.toInt32(); break;
1433 case 7: level[j].nSymbolTextDistance = tmp.toInt32(); break;
1434 case 8: level[j].nFirstLineOffset = tmp.toInt32(); break;
1435 case 9: break;
1436 case 10: level[j].sTransliteration = tmp; break;
1437 case 11: level[j].nNatNum = tmp.toInt32(); break;
1438 default:
1439 OSL_ASSERT(0);
1443 level[j].sPrefix = aEmptyStr;
1444 level[j].nNumType = 0;
1445 level[j].sSuffix = aEmptyStr;
1446 level[j].cBulletChar = 0;
1447 level[j].sBulletFontName = 0;
1448 level[j].nParentNumbering = 0;
1449 level[j].nLeftMargin = 0;
1450 level[j].nSymbolTextDistance = 0;
1451 level[j].nFirstLineOffset = 0;
1452 level[j].sTransliteration = aEmptyStr;
1453 level[j].nNatNum = 0;
1454 aRet[i] = new OutlineNumbering( level, nLevels );
1456 return aRet;
1458 else {
1459 Sequence< Reference<container::XIndexAccess> > seq1(0);
1460 return seq1;
1464 // helper functions
1466 oslGenericFunction SAL_CALL LocaleData::getFunctionSymbol( const Locale& rLocale, const sal_Char* pFunction )
1467 throw(RuntimeException)
1469 lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get();
1471 OUStringBuffer aBuf(1);
1472 if (cachedItem.get() && cachedItem->equals(rLocale))
1474 aBuf.ensureCapacity(strlen(pFunction) + 1 + strlen(cachedItem->localeName));
1475 return cachedItem->module->getFunctionSymbol(aBuf.appendAscii(pFunction).append(under).
1476 appendAscii(cachedItem->localeName).makeStringAndClear());
1479 oslGenericFunction pSymbol = 0;
1481 sal_Int32 l = rLocale.Language.getLength();
1482 sal_Int32 c = rLocale.Country.getLength();
1483 sal_Int32 v = rLocale.Variant.getLength();
1484 aBuf.ensureCapacity(l+c+v+3);
1486 LocaleDataLookupTableItem *pCachedItem = 0;
1488 if (l > 0 && c > 0 && v > 0)
1490 // load function with name <func>_<lang>_<country>_<variant>
1491 pSymbol = rLookupTable.getFunctionSymbolByName(
1492 aBuf.append(rLocale.Language).append(under).append(rLocale.Country).append(under).append(rLocale.Variant).makeStringAndClear(),
1493 pFunction, &pCachedItem);
1496 if (!pSymbol && l > 0 && c > 0)
1498 // load function with name <ase>_<lang>_<country>
1499 pSymbol = rLookupTable.getFunctionSymbolByName(
1500 aBuf.append(rLocale.Language).append(under).append(rLocale.Country).makeStringAndClear(),
1501 pFunction, &pCachedItem);
1504 if (!pSymbol && l > 0 && c > 0 && rLocale.Language == "zh" && (rLocale.Country == "HK" || rLocale.Country == "MO"))
1506 // if the country code is HK or MO, one more step to try TW.
1507 pSymbol = rLookupTable.getFunctionSymbolByName(
1508 aBuf.append(rLocale.Language).append(under).append("TW").makeStringAndClear(),
1509 pFunction, &pCachedItem);
1512 if (!pSymbol)
1514 // load function with name <func>_<lang>
1515 pSymbol = rLookupTable.getFunctionSymbolByName(rLocale.Language, pFunction, &pCachedItem);
1518 if (!pSymbol)
1520 // load default function with name <func>_en_US
1521 pSymbol = rLookupTable.getFunctionSymbolByName(OUString("en_US"), pFunction, &pCachedItem);
1524 if (!pSymbol)
1525 // Appropriate symbol could not be found. Give up.
1526 throw RuntimeException();
1528 if (pCachedItem)
1529 cachedItem.reset(pCachedItem);
1530 if (cachedItem.get())
1531 cachedItem->aLocale = rLocale;
1533 return pSymbol;
1536 Sequence< Locale > SAL_CALL
1537 LocaleData::getAllInstalledLocaleNames() throw(RuntimeException)
1539 Sequence< lang::Locale > seq( nbOfLocales );
1540 OUString empStr;
1541 sal_Int16 nInstalled = 0;
1543 for( sal_Int16 i=0; i<nbOfLocales; i++ ) {
1544 OUString name = OUString::createFromAscii( aLibTable[i].pLocale );
1546 // Check if the locale is really available and not just in the table,
1547 // don't allow fall backs.
1548 LocaleDataLookupTableItem *pCachedItem = 0;
1549 if (lcl_LookupTableStatic::get().getFunctionSymbolByName( name, "getLocaleItem", &pCachedItem )) {
1550 if( pCachedItem )
1551 cachedItem.reset( pCachedItem );
1552 sal_Int32 index = 0;
1553 lang::Locale tmpLocale(name.getToken(0, under, index), empStr, empStr);
1554 if (index >= 0) {
1555 tmpLocale.Country = name.getToken(0, under, index);
1556 if (index >= 0)
1557 tmpLocale.Variant = name.getToken(0, under, index);
1559 seq[nInstalled++] = tmpLocale;
1562 if ( nInstalled < nbOfLocales )
1563 seq.realloc( nInstalled ); // reflect reality
1565 return seq;
1568 using namespace ::com::sun::star::container;
1569 using namespace ::com::sun::star::beans;
1570 using namespace ::com::sun::star::style;
1571 using namespace ::com::sun::star::text;
1573 OutlineNumbering::OutlineNumbering(const OutlineNumberingLevel_Impl* pOutlnLevels, int nLevels) :
1574 m_pOutlineLevels(pOutlnLevels),
1575 m_nCount(sal::static_int_cast<sal_Int16>(nLevels))
1579 OutlineNumbering::~OutlineNumbering()
1581 delete [] m_pOutlineLevels;
1584 sal_Int32 OutlineNumbering::getCount( ) throw(RuntimeException)
1586 return m_nCount;
1589 Any OutlineNumbering::getByIndex( sal_Int32 nIndex )
1590 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
1592 if(nIndex < 0 || nIndex >= m_nCount)
1593 throw IndexOutOfBoundsException();
1594 const OutlineNumberingLevel_Impl* pTemp = m_pOutlineLevels;
1595 pTemp += nIndex;
1596 Any aRet;
1598 Sequence<PropertyValue> aOutlineNumbering(12);
1599 PropertyValue* pValues = aOutlineNumbering.getArray();
1600 pValues[0].Name = C2U( "Prefix");
1601 pValues[0].Value <<= pTemp->sPrefix;
1602 pValues[1].Name = C2U("NumberingType");
1603 pValues[1].Value <<= pTemp->nNumType;
1604 pValues[2].Name = C2U("Suffix");
1605 pValues[2].Value <<= pTemp->sSuffix;
1606 pValues[3].Name = C2U("BulletChar");
1607 pValues[3].Value <<= OUString(&pTemp->cBulletChar, 1);
1608 pValues[4].Name = C2U("BulletFontName");
1609 pValues[4].Value <<= C2U(pTemp->sBulletFontName);
1610 pValues[5].Name = C2U("ParentNumbering");
1611 pValues[5].Value <<= pTemp->nParentNumbering;
1612 pValues[6].Name = C2U("LeftMargin");
1613 pValues[6].Value <<= pTemp->nLeftMargin;
1614 pValues[7].Name = C2U("SymbolTextDistance");
1615 pValues[7].Value <<= pTemp->nSymbolTextDistance;
1616 pValues[8].Name = C2U("FirstLineOffset");
1617 pValues[8].Value <<= pTemp->nFirstLineOffset;
1618 pValues[9].Name = C2U("Adjust");
1619 pValues[9].Value <<= (sal_Int16)HoriOrientation::LEFT;
1620 pValues[10].Name = C2U("Transliteration");
1621 pValues[10].Value <<= pTemp->sTransliteration;
1622 pValues[11].Name = C2U("NatNum");
1623 pValues[11].Value <<= pTemp->nNatNum;
1624 aRet <<= aOutlineNumbering;
1625 return aRet;
1628 Type OutlineNumbering::getElementType( ) throw(RuntimeException)
1630 return ::getCppuType((Sequence<PropertyValue>*)0);
1633 sal_Bool OutlineNumbering::hasElements( ) throw(RuntimeException)
1635 return m_nCount > 0;
1638 OUString SAL_CALL
1639 LocaleData::getImplementationName() throw( RuntimeException )
1641 return OUString(clocaledata);
1644 sal_Bool SAL_CALL
1645 LocaleData::supportsService(const OUString& rServiceName)
1646 throw( RuntimeException )
1648 return rServiceName == clocaledata;
1651 Sequence< OUString > SAL_CALL
1652 LocaleData::getSupportedServiceNames() throw( RuntimeException )
1654 Sequence< OUString > aRet(1);
1655 aRet[0] = OUString(clocaledata);
1656 return aRet;
1659 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */