1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_i18npool.hxx" 26 27 #include <localedata.hxx> 28 #include <i18npool/mslangid.hxx> 29 #include <rtl/ustrbuf.hxx> 30 #include <string.h> 31 #include <stdio.h> 32 #include "rtl/instance.hxx" 33 34 using namespace com::sun::star::i18n; 35 using namespace com::sun::star::uno; 36 using namespace com::sun::star::lang; 37 using namespace com::sun::star; 38 using namespace rtl; 39 40 static const sal_Char clocaledata[] = "com.sun.star.i18n.LocaleData"; 41 42 typedef sal_Unicode** (SAL_CALL * MyFunc_Type)( sal_Int16&); 43 typedef sal_Unicode*** (SAL_CALL * MyFunc_Type2)( sal_Int16&, sal_Int16& ); 44 typedef sal_Unicode**** (SAL_CALL * MyFunc_Type3)( sal_Int16&, sal_Int16&, sal_Int16& ); 45 typedef sal_Unicode const * const * (SAL_CALL * MyFunc_FormatCode)( sal_Int16&, sal_Unicode const *&, sal_Unicode const *& ); 46 47 #ifdef OS2 // YD 8.3!! 48 static const char *lcl_DATA_EN = "ld_en"; 49 static const char *lcl_DATA_ES = "ld_es"; 50 static const char *lcl_DATA_EURO = "ld_eur"; 51 static const char *lcl_DATA_OTHERS = "ld_oth"; 52 #else 53 static const char *lcl_DATA_EN = "localedata_en"; 54 static const char *lcl_DATA_ES = "localedata_es"; 55 static const char *lcl_DATA_EURO = "localedata_euro"; 56 static const char *lcl_DATA_OTHERS = "localedata_others"; 57 #endif 58 59 static const struct { 60 const char* pLocale; 61 const char* pLib; 62 } aLibTable[] = { 63 { "en_US", lcl_DATA_EN }, 64 { "en_AU", lcl_DATA_EN }, 65 { "en_BZ", lcl_DATA_EN }, 66 { "en_CA", lcl_DATA_EN }, 67 { "en_GB", lcl_DATA_EN }, 68 { "en_IE", lcl_DATA_EN }, 69 { "en_JM", lcl_DATA_EN }, 70 { "en_NZ", lcl_DATA_EN }, 71 { "en_PH", lcl_DATA_EN }, 72 { "en_TT", lcl_DATA_EN }, 73 { "en_ZA", lcl_DATA_EN }, 74 { "en_ZW", lcl_DATA_EN }, 75 { "en_NA", lcl_DATA_EN }, 76 { "en_GH", lcl_DATA_EN }, 77 78 { "es_ES", lcl_DATA_ES }, 79 { "es_AR", lcl_DATA_ES }, 80 { "es_BO", lcl_DATA_ES }, 81 { "es_CL", lcl_DATA_ES }, 82 { "es_CO", lcl_DATA_ES }, 83 { "es_CR", lcl_DATA_ES }, 84 { "es_DO", lcl_DATA_ES }, 85 { "es_EC", lcl_DATA_ES }, 86 { "es_GT", lcl_DATA_ES }, 87 { "es_HN", lcl_DATA_ES }, 88 { "es_MX", lcl_DATA_ES }, 89 { "es_NI", lcl_DATA_ES }, 90 { "es_PA", lcl_DATA_ES }, 91 { "es_PE", lcl_DATA_ES }, 92 { "es_PR", lcl_DATA_ES }, 93 { "es_PY", lcl_DATA_ES }, 94 { "es_SV", lcl_DATA_ES }, 95 { "es_UY", lcl_DATA_ES }, 96 { "es_VE", lcl_DATA_ES }, 97 { "gl_ES", lcl_DATA_ES }, 98 99 { "de_DE", lcl_DATA_EURO }, 100 { "de_AT", lcl_DATA_EURO }, 101 { "de_CH", lcl_DATA_EURO }, 102 { "de_LI", lcl_DATA_EURO }, 103 { "de_LU", lcl_DATA_EURO }, 104 { "fr_FR", lcl_DATA_EURO }, 105 { "fr_BE", lcl_DATA_EURO }, 106 { "fr_CA", lcl_DATA_EURO }, 107 { "fr_CH", lcl_DATA_EURO }, 108 { "fr_LU", lcl_DATA_EURO }, 109 { "fr_MC", 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 { "cs_CZ", lcl_DATA_EURO }, 117 { "sk_SK", lcl_DATA_EURO }, 118 { "da_DK", lcl_DATA_EURO }, 119 { "el_GR", lcl_DATA_EURO }, 120 { "fi_FI", lcl_DATA_EURO }, 121 { "is_IS", lcl_DATA_EURO }, 122 { "nl_BE", lcl_DATA_EURO }, 123 { "nl_NL", lcl_DATA_EURO }, 124 { "no_NO", lcl_DATA_EURO }, 125 { "nn_NO", lcl_DATA_EURO }, 126 { "nb_NO", lcl_DATA_EURO }, 127 { "pl_PL", lcl_DATA_EURO }, 128 { "pt_BR", lcl_DATA_EURO }, 129 { "pt_PT", lcl_DATA_EURO }, 130 { "ru_RU", lcl_DATA_EURO }, 131 { "tr_TR", lcl_DATA_EURO }, 132 { "et_EE", lcl_DATA_EURO }, 133 { "lb_LU", lcl_DATA_EURO }, 134 { "lt_LT", lcl_DATA_EURO }, 135 { "lv_LV", lcl_DATA_EURO }, 136 { "uk_UA", lcl_DATA_EURO }, 137 { "ro_RO", lcl_DATA_EURO }, 138 { "cy_GB", lcl_DATA_EURO }, 139 { "bg_BG", lcl_DATA_EURO }, 140 { "sh_ME", lcl_DATA_EURO }, 141 { "sh_RS", lcl_DATA_EURO }, 142 { "sh_YU", lcl_DATA_EURO }, 143 { "sr_ME", lcl_DATA_EURO }, 144 { "sr_RS", lcl_DATA_EURO }, 145 { "sr_YU", lcl_DATA_EURO }, 146 { "hr_HR", lcl_DATA_EURO }, 147 { "bs_BA", lcl_DATA_EURO }, 148 { "eu", lcl_DATA_EURO }, 149 { "fo_FO", lcl_DATA_EURO }, 150 { "ga_IE", lcl_DATA_EURO }, 151 { "ka_GE", lcl_DATA_EURO }, 152 { "be_BY", lcl_DATA_EURO }, 153 { "kl_GL", lcl_DATA_EURO }, 154 { "mk_MK", lcl_DATA_EURO }, 155 { "br_FR", lcl_DATA_EURO }, 156 { "la_VA", lcl_DATA_EURO }, 157 { "cv_RU", lcl_DATA_EURO }, 158 { "wa_BE", lcl_DATA_EURO }, 159 { "fur_IT", lcl_DATA_EURO }, 160 { "gsc_FR", lcl_DATA_EURO }, 161 { "fy_NL", lcl_DATA_EURO }, 162 { "oc_FR", lcl_DATA_EURO }, 163 { "mt_MT", lcl_DATA_EURO }, 164 { "sc_IT", lcl_DATA_EURO }, 165 { "ast_ES", lcl_DATA_EURO }, 166 { "ltg_LV", lcl_DATA_EURO }, 167 { "hsb_DE", lcl_DATA_EURO }, 168 { "dsb_DE", lcl_DATA_EURO }, 169 { "rue_SK", lcl_DATA_EURO }, 170 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 }, 178 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 }, 198 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 }; 258 259 static const sal_Unicode under = sal_Unicode('_'); 260 261 static const sal_Int16 nbOfLocales = sizeof(aLibTable) / sizeof(aLibTable[0]); 262 263 struct LocaleDataLookupTableItem 264 { 265 LocaleDataLookupTableItem(const sal_Char *name, osl::Module* m, const sal_Char* lname) : dllName(name), module(m), localeName(lname) 266 { 267 } 268 const sal_Char* dllName; 269 osl::Module *module; 270 const sal_Char* localeName; 271 272 com::sun::star::lang::Locale aLocale; 273 sal_Bool equals(const com::sun::star::lang::Locale& rLocale) 274 { 275 return (rLocale == aLocale); 276 } 277 }; 278 279 LocaleData::LocaleData() 280 { 281 } 282 LocaleData::~LocaleData() 283 { 284 } 285 286 287 LocaleDataItem SAL_CALL 288 LocaleData::getLocaleItem( const Locale& rLocale ) throw(RuntimeException) 289 { 290 sal_Int16 dataItemCount = 0; 291 sal_Unicode **dataItem = NULL; 292 293 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getLocaleItem" ); 294 295 if ( func ) { 296 dataItem = func(dataItemCount); 297 298 LocaleDataItem item( 299 dataItem[0], 300 dataItem[1], 301 dataItem[2], 302 dataItem[3], 303 dataItem[4], 304 dataItem[5], 305 dataItem[6], 306 dataItem[7], 307 dataItem[8], 308 dataItem[9], 309 dataItem[10], 310 dataItem[11], 311 dataItem[12], 312 dataItem[13], 313 dataItem[14], 314 dataItem[15], 315 dataItem[16], 316 dataItem[17] 317 ); 318 return item; 319 } 320 else { 321 LocaleDataItem item1; 322 return item1; 323 } 324 } 325 326 extern "C" { static void SAL_CALL thisModule() {} } 327 328 namespace 329 { 330 331 // implement the lookup table as a safe static object 332 class lcl_LookupTableHelper 333 { 334 public: 335 lcl_LookupTableHelper(); 336 ~lcl_LookupTableHelper(); 337 338 oslGenericFunction SAL_CALL getFunctionSymbolByName( 339 const OUString& localeName, const sal_Char* pFunction, 340 LocaleDataLookupTableItem** pOutCachedItem ); 341 342 private: 343 ::osl::Mutex maMutex; 344 ::std::vector< LocaleDataLookupTableItem* > maLookupTable; 345 }; 346 347 // from instance.hxx: Helper base class for a late-initialized 348 // (default-constructed) static variable, implementing the double-checked 349 // locking pattern correctly. 350 // usage: lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get(); 351 // retrieves the singleton lookup table instance 352 struct lcl_LookupTableStatic : public ::rtl::Static< lcl_LookupTableHelper, lcl_LookupTableStatic > 353 {}; 354 355 lcl_LookupTableHelper::lcl_LookupTableHelper() 356 { 357 } 358 359 lcl_LookupTableHelper::~lcl_LookupTableHelper() 360 { 361 LocaleDataLookupTableItem* pItem = 0; 362 363 std::vector<LocaleDataLookupTableItem*>::const_iterator aEnd(maLookupTable.end()); 364 std::vector<LocaleDataLookupTableItem*>::iterator aIter(maLookupTable.begin()); 365 366 for ( ; aIter != aEnd; ++aIter ) { 367 pItem = *aIter; 368 delete pItem->module; 369 delete pItem; 370 } 371 maLookupTable.clear(); 372 } 373 374 oslGenericFunction SAL_CALL lcl_LookupTableHelper::getFunctionSymbolByName( 375 const OUString& localeName, const sal_Char* pFunction, 376 LocaleDataLookupTableItem** pOutCachedItem ) 377 { 378 OUString aFallback; 379 bool bFallback = (localeName.indexOf( under) < 0); 380 if (bFallback) 381 { 382 Locale aLocale; 383 aLocale.Language = localeName; 384 Locale aFbLocale = MsLangId::getFallbackLocale( aLocale); 385 if (aFbLocale == aLocale) 386 bFallback = false; // may be a "language-only-locale" like Interlingua (ia) 387 else if (aFbLocale.Country.getLength()) { 388 OUStringBuffer aBuf(5); 389 aFallback = aBuf.append(aFbLocale.Language).append( under).append(aFbLocale.Country).makeStringAndClear(); 390 } 391 else 392 aFallback = aFbLocale.Language; 393 } 394 395 for ( sal_Int16 i = 0; i < nbOfLocales; i++) 396 { 397 if (localeName.equalsAscii(aLibTable[i].pLocale) || 398 (bFallback && localeName == aFallback)) 399 { 400 LocaleDataLookupTableItem* pCurrent = 0; 401 OUStringBuffer aBuf(strlen(aLibTable[i].pLocale) + 1 + strlen(pFunction)); 402 { 403 ::osl::MutexGuard aGuard( maMutex ); 404 for (size_t l = 0; l < maLookupTable.size(); l++) 405 { 406 pCurrent = maLookupTable[l]; 407 if (pCurrent->dllName == aLibTable[i].pLib) 408 { 409 OSL_ASSERT( pOutCachedItem ); 410 if( pOutCachedItem ) 411 { 412 (*pOutCachedItem) = new LocaleDataLookupTableItem( *pCurrent ); 413 (*pOutCachedItem)->localeName = aLibTable[i].pLocale; 414 return (*pOutCachedItem)->module->getFunctionSymbol( 415 aBuf.appendAscii( pFunction).append( under). 416 appendAscii( (*pOutCachedItem)->localeName).makeStringAndClear()); 417 } 418 else 419 return NULL; 420 } 421 } 422 } 423 // Library not loaded, load it and add it to the list. 424 #ifdef SAL_DLLPREFIX 425 aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 6); // mostly "lib*.so" 426 aBuf.appendAscii( SAL_DLLPREFIX ).appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION ); 427 #else 428 aBuf.ensureCapacity(strlen(aLibTable[i].pLib) + 4); // mostly "*.dll" 429 aBuf.appendAscii(aLibTable[i].pLib).appendAscii( SAL_DLLEXTENSION ); 430 #endif 431 osl::Module *module = new osl::Module(); 432 if ( module->loadRelative(&thisModule, aBuf.makeStringAndClear()) ) 433 { 434 ::osl::MutexGuard aGuard( maMutex ); 435 LocaleDataLookupTableItem* pNewItem = 0; 436 maLookupTable.push_back(pNewItem = new LocaleDataLookupTableItem(aLibTable[i].pLib, module, aLibTable[i].pLocale )); 437 OSL_ASSERT( pOutCachedItem ); 438 if( pOutCachedItem ) 439 { 440 (*pOutCachedItem) = new LocaleDataLookupTableItem( *pNewItem ); 441 return module->getFunctionSymbol( 442 aBuf.appendAscii(pFunction).append(under). 443 appendAscii((*pOutCachedItem)->localeName).makeStringAndClear()); 444 } 445 else 446 return NULL; 447 } 448 else 449 delete module; 450 } 451 } 452 return NULL; 453 } 454 455 } // anonymous namespace 456 457 #define REF_DAYS 0 458 #define REF_MONTHS 1 459 #define REF_ERAS 2 460 461 Sequence< CalendarItem > &LocaleData::getCalendarItemByName(const OUString& name, 462 const Locale& rLocale, const Sequence< Calendar >& calendarsSeq, sal_Int16 len, sal_Int16 item) 463 throw(RuntimeException) 464 { 465 if (!ref_name.equals(name)) { 466 sal_Int32 index = 0; 467 OUString language = name.getToken(0, under, index); 468 OUString country = name.getToken(0, under, index); 469 Locale loc(language, country, OUString()); 470 Sequence < Calendar > cals; 471 if (loc == rLocale) { 472 cals = calendarsSeq; 473 } else { 474 cals = getAllCalendars(loc); 475 len = sal::static_int_cast<sal_Int16>( cals.getLength() ); 476 } 477 const OUString& id = name.getToken(0, under, index); 478 for (index = 0; index < cals.getLength(); index++) { 479 if (id.equals(cals[index].Name)) { 480 ref_cal = cals[index]; 481 break; 482 } 483 } 484 // Refered locale does not found, return name for en_US locale. 485 if (index == cals.getLength()) { 486 cals = getAllCalendars( 487 Locale(OUString::createFromAscii("en"), OUString::createFromAscii("US"), OUString())); 488 if (cals.getLength() > 0) 489 ref_cal = cals[0]; 490 else 491 throw RuntimeException(); 492 } 493 ref_name = name; 494 } 495 return item == REF_DAYS ? ref_cal.Days : item == REF_MONTHS ? ref_cal.Months : ref_cal.Eras; 496 } 497 498 499 Sequence< Calendar > SAL_CALL 500 LocaleData::getAllCalendars( const Locale& rLocale ) throw(RuntimeException) 501 { 502 503 sal_Int16 calendarsCount = 0; 504 sal_Unicode **allCalendars = NULL; 505 506 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getAllCalendars" ); 507 508 if ( func ) { 509 allCalendars = func(calendarsCount); 510 511 Sequence< Calendar > calendarsSeq(calendarsCount); 512 sal_Int16 offset = 3; 513 sal_Int16 i, j; 514 for(i = 0; i < calendarsCount; i++) { 515 Sequence< CalendarItem > days(allCalendars[0][i]); 516 Sequence< CalendarItem > months(allCalendars[1][i]); 517 Sequence< CalendarItem > eras(allCalendars[2][i]); 518 OUString calendarID(allCalendars[offset]); 519 offset++; 520 sal_Bool defaultCalendar = sal::static_int_cast<sal_Bool>( allCalendars[offset][0] ); 521 offset++; 522 if (OUString(allCalendars[offset]).equalsAscii("ref")) { 523 days = getCalendarItemByName(OUString(allCalendars[offset+1]), rLocale, calendarsSeq, i, REF_DAYS); 524 offset += 2; 525 } else { 526 for(j = 0; j < allCalendars[0][i]; j++) { 527 CalendarItem day(allCalendars[offset], 528 allCalendars[offset+1], allCalendars[offset+2]); 529 days[j] = day; 530 offset += 3; 531 } 532 } 533 if (OUString(allCalendars[offset]).equalsAscii("ref")) { 534 months = getCalendarItemByName(OUString(allCalendars[offset+1]), rLocale, calendarsSeq, i, REF_MONTHS); 535 offset += 2; 536 } else { 537 for(j = 0; j < allCalendars[1][i]; j++) { 538 CalendarItem month(allCalendars[offset], 539 allCalendars[offset+1], allCalendars[offset+2]); 540 months[j] = month; 541 offset += 3; 542 } 543 } 544 if (OUString(allCalendars[offset]).equalsAscii("ref")) { 545 eras = getCalendarItemByName(OUString(allCalendars[offset+1]), rLocale, calendarsSeq, i, REF_ERAS); 546 offset += 2; 547 } else { 548 for(j = 0; j < allCalendars[2][i]; j++) { 549 CalendarItem era(allCalendars[offset], 550 allCalendars[offset+1], allCalendars[offset+2]); 551 eras[j] = era; 552 offset += 3; 553 } 554 } 555 OUString startOfWeekDay(allCalendars[offset]); 556 offset++; 557 sal_Int16 minimalDaysInFirstWeek = allCalendars[offset][0]; 558 offset++; 559 Calendar aCalendar(days, months, eras, startOfWeekDay, 560 minimalDaysInFirstWeek, defaultCalendar, calendarID); 561 calendarsSeq[i] = aCalendar; 562 } 563 return calendarsSeq; 564 } 565 else { 566 Sequence< Calendar > seq1(0); 567 return seq1; 568 } 569 } 570 571 572 Sequence< Currency2 > SAL_CALL 573 LocaleData::getAllCurrencies2( const Locale& rLocale ) throw(RuntimeException) 574 { 575 576 sal_Int16 currencyCount = 0; 577 sal_Unicode **allCurrencies = NULL; 578 579 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getAllCurrencies" ); 580 581 if ( func ) { 582 allCurrencies = func(currencyCount); 583 584 Sequence< Currency2 > seq(currencyCount); 585 for(int i = 0, nOff = 0; i < currencyCount; i++, nOff += 8 ) { 586 Currency2 cur( 587 allCurrencies[nOff], // string ID 588 allCurrencies[nOff+1], // string Symbol 589 allCurrencies[nOff+2], // string BankSymbol 590 allCurrencies[nOff+3], // string Name 591 allCurrencies[nOff+4][0] != 0, // boolean Default 592 allCurrencies[nOff+5][0] != 0, // boolean UsedInCompatibleFormatCodes 593 allCurrencies[nOff+6][0], // short DecimalPlaces 594 allCurrencies[nOff+7][0] != 0 // boolean LegacyOnly 595 ); 596 seq[i] = cur; 597 } 598 return seq; 599 } 600 else { 601 Sequence< Currency2 > seq1(0); 602 return seq1; 603 } 604 } 605 606 607 Sequence< Currency > SAL_CALL 608 LocaleData::getAllCurrencies( const Locale& rLocale ) throw(RuntimeException) 609 { 610 Sequence< Currency2 > aCur2( getAllCurrencies2( rLocale)); 611 sal_Int32 nLen = aCur2.getLength(); 612 Sequence< Currency > aCur1( nLen); 613 const Currency2* p2 = aCur2.getArray(); 614 Currency* p1 = aCur1.getArray(); 615 for (sal_Int32 i=0; i < nLen; ++i, ++p1, ++p2) 616 { 617 *p1 = *p2; 618 } 619 return aCur1; 620 } 621 622 623 // return a static (!) string resulting from replacing all occurrences of 624 // 'oldStr' string in 'formatCode' string with 'newStr' string 625 static const sal_Unicode * replace( sal_Unicode const * const formatCode, sal_Unicode const * const oldStr, sal_Unicode const * const newStr) 626 { 627 // make reasonable assumption of maximum length of formatCode. 628 #define MAX_FORMATCODE_LENTH 512 629 static sal_Unicode str[MAX_FORMATCODE_LENTH]; 630 631 if (oldStr[0] == 0) // no replacement requires 632 return formatCode; 633 634 sal_Int32 i = 0, k = 0; 635 while (formatCode[i] > 0 && k < MAX_FORMATCODE_LENTH) { 636 sal_Int32 j = 0, last = k; 637 // search oldStr in formatCode 638 while (formatCode[i] > 0 && oldStr[j] > 0 && k < MAX_FORMATCODE_LENTH) { 639 str[k++] = formatCode[i]; 640 if (formatCode[i++] != oldStr[j++]) 641 break; 642 } 643 if (oldStr[j] == 0) { 644 // matched string found, do replacement 645 k = last; j = 0; 646 while (newStr[j] > 0 && k < MAX_FORMATCODE_LENTH) 647 str[k++] = newStr[j++]; 648 } 649 } 650 if (k >= MAX_FORMATCODE_LENTH) // could not complete replacement, return original formatCode 651 return formatCode; 652 653 str[k] = 0; 654 return str; 655 } 656 657 Sequence< FormatElement > SAL_CALL 658 LocaleData::getAllFormats( const Locale& rLocale ) throw(RuntimeException) 659 { 660 const int SECTIONS = 2; 661 struct FormatSection 662 { 663 MyFunc_FormatCode func; 664 sal_Unicode const *from; 665 sal_Unicode const *to; 666 sal_Unicode const *const *formatArray; 667 sal_Int16 formatCount; 668 669 FormatSection() : func(0), from(0), to(0), formatArray(0), formatCount(0) {} 670 sal_Int16 getFunc( LocaleData& rLocaleData, const Locale& rL, const char* pName ) 671 { 672 func = reinterpret_cast<MyFunc_FormatCode>( rLocaleData.getFunctionSymbol( rL, pName)); 673 if (func) 674 formatArray = func( formatCount, from, to); 675 return formatCount; 676 } 677 } section[SECTIONS]; 678 679 #if 0 680 // #i79398# wntmsci10 MSVC doesn't get this right with optimization. 681 const sal_Int32 formatCount = section[0].getFunc( *this, rLocale, "getAllFormats0") 682 + section[1].getFunc( *this, rLocale, "getAllFormats1"); 683 #else 684 sal_Int32 formatCount = section[0].getFunc( *this, rLocale, "getAllFormats0"); 685 formatCount += section[1].getFunc( *this, rLocale, "getAllFormats1"); 686 #endif 687 Sequence< FormatElement > seq(formatCount); 688 sal_Int32 f = 0; 689 for (int s = 0; s < SECTIONS; ++s) 690 { 691 sal_Unicode const * const * const formatArray = section[s].formatArray; 692 if ( formatArray ) 693 { 694 for (int i = 0, nOff = 0; i < section[s].formatCount; ++i, nOff += 7, ++f) 695 { 696 FormatElement elem( 697 replace( formatArray[nOff], section[s].from, section[s].to), 698 formatArray[nOff + 1], 699 formatArray[nOff + 2], 700 formatArray[nOff + 3], 701 formatArray[nOff + 4], 702 formatArray[nOff + 5][0], 703 sal::static_int_cast<sal_Bool>(formatArray[nOff + 6][0])); 704 seq[f] = elem; 705 } 706 } 707 } 708 return seq; 709 } 710 711 #define COLLATOR_OFFSET_ALGO 0 712 #define COLLATOR_OFFSET_DEFAULT 1 713 #define COLLATOR_OFFSET_RULE 2 714 #define COLLATOR_ELEMENTS 3 715 716 OUString SAL_CALL 717 LocaleData::getCollatorRuleByAlgorithm( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException) 718 { 719 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getCollatorImplementation" ); 720 if ( func ) { 721 sal_Int16 collatorCount = 0; 722 sal_Unicode **collatorArray = func(collatorCount); 723 for(sal_Int16 i = 0; i < collatorCount; i++) 724 if (algorithm.equals(collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_ALGO])) 725 return OUString(collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_RULE]); 726 } 727 return OUString(); 728 } 729 730 731 Sequence< Implementation > SAL_CALL 732 LocaleData::getCollatorImplementations( const Locale& rLocale ) throw(RuntimeException) 733 { 734 sal_Int16 collatorCount = 0; 735 sal_Unicode **collatorArray = NULL; 736 737 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getCollatorImplementation" ); 738 739 if ( func ) { 740 collatorArray = func(collatorCount); 741 Sequence< Implementation > seq(collatorCount); 742 for(sal_Int16 i = 0; i < collatorCount; i++) { 743 Implementation impl(collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_ALGO], 744 sal::static_int_cast<sal_Bool>( 745 collatorArray[i * COLLATOR_ELEMENTS + COLLATOR_OFFSET_DEFAULT][0])); 746 seq[i] = impl; 747 } 748 return seq; 749 } 750 else { 751 Sequence< Implementation > seq1(0); 752 return seq1; 753 } 754 } 755 756 Sequence< OUString > SAL_CALL 757 LocaleData::getCollationOptions( const Locale& rLocale ) throw(RuntimeException) 758 { 759 sal_Int16 optionsCount = 0; 760 sal_Unicode **optionsArray = NULL; 761 762 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getCollationOptions" ); 763 764 if ( func ) { 765 optionsArray = func(optionsCount); 766 Sequence< OUString > seq(optionsCount); 767 for(sal_Int16 i = 0; i < optionsCount; i++) { 768 seq[i] = OUString( optionsArray[i] ); 769 } 770 return seq; 771 } 772 else { 773 Sequence< OUString > seq1(0); 774 return seq1; 775 } 776 } 777 778 Sequence< OUString > SAL_CALL 779 LocaleData::getSearchOptions( const Locale& rLocale ) throw(RuntimeException) 780 { 781 sal_Int16 optionsCount = 0; 782 sal_Unicode **optionsArray = NULL; 783 784 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getSearchOptions" ); 785 786 if ( func ) { 787 optionsArray = func(optionsCount); 788 Sequence< OUString > seq(optionsCount); 789 for(sal_Int16 i = 0; i < optionsCount; i++) { 790 seq[i] = OUString( optionsArray[i] ); 791 } 792 return seq; 793 } 794 else { 795 Sequence< OUString > seq1(0); 796 return seq1; 797 } 798 } 799 800 sal_Unicode ** SAL_CALL 801 LocaleData::getIndexArray(const Locale& rLocale, sal_Int16& indexCount) 802 { 803 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getIndexAlgorithm" ); 804 805 if (func) 806 return func(indexCount); 807 return NULL; 808 } 809 810 Sequence< OUString > SAL_CALL 811 LocaleData::getIndexAlgorithm( const Locale& rLocale ) throw(RuntimeException) 812 { 813 sal_Int16 indexCount = 0; 814 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount); 815 816 if ( indexArray ) { 817 Sequence< OUString > seq(indexCount); 818 for(sal_Int16 i = 0; i < indexCount; i++) { 819 seq[i] = indexArray[i*5]; 820 } 821 return seq; 822 } 823 else { 824 Sequence< OUString > seq1(0); 825 return seq1; 826 } 827 } 828 829 OUString SAL_CALL 830 LocaleData::getDefaultIndexAlgorithm( const Locale& rLocale ) throw(RuntimeException) 831 { 832 sal_Int16 indexCount = 0; 833 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount); 834 835 if ( indexArray ) { 836 for(sal_Int16 i = 0; i < indexCount; i++) { 837 if (indexArray[i*5 + 3][0]) 838 return OUString(indexArray[i*5]); 839 } 840 } 841 return OUString(); 842 } 843 844 sal_Bool SAL_CALL 845 LocaleData::hasPhonetic( const Locale& rLocale ) throw(RuntimeException) 846 { 847 sal_Int16 indexCount = 0; 848 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount); 849 850 if ( indexArray ) { 851 for(sal_Int16 i = 0; i < indexCount; i++) { 852 if (indexArray[i*5 + 4][0]) 853 return sal_True; 854 } 855 } 856 return sal_False; 857 } 858 859 sal_Unicode ** SAL_CALL 860 LocaleData::getIndexArrayForAlgorithm(const Locale& rLocale, const OUString& algorithm) 861 { 862 sal_Int16 indexCount = 0; 863 sal_Unicode **indexArray = getIndexArray(rLocale, indexCount); 864 if ( indexArray ) { 865 for(sal_Int16 i = 0; i < indexCount; i++) { 866 if (algorithm.equals(indexArray[i*5])) 867 return indexArray+i*5; 868 } 869 } 870 return NULL; 871 } 872 873 sal_Bool SAL_CALL 874 LocaleData::isPhonetic( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException) 875 { 876 sal_Unicode **indexArray = getIndexArrayForAlgorithm(rLocale, algorithm); 877 return (indexArray && indexArray[4][0]) ? sal_True : sal_False; 878 } 879 880 OUString SAL_CALL 881 LocaleData::getIndexKeysByAlgorithm( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException) 882 { 883 sal_Unicode **indexArray = getIndexArrayForAlgorithm(rLocale, algorithm); 884 return indexArray ? OUString::createFromAscii("0-9")+OUString(indexArray[2]) : OUString(); 885 } 886 887 OUString SAL_CALL 888 LocaleData::getIndexModuleByAlgorithm( const Locale& rLocale, const OUString& algorithm ) throw(RuntimeException) 889 { 890 sal_Unicode **indexArray = getIndexArrayForAlgorithm(rLocale, algorithm); 891 return indexArray ? OUString(indexArray[1]) : OUString(); 892 } 893 894 Sequence< UnicodeScript > SAL_CALL 895 LocaleData::getUnicodeScripts( const Locale& rLocale ) throw(RuntimeException) 896 { 897 sal_Int16 scriptCount = 0; 898 sal_Unicode **scriptArray = NULL; 899 900 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getUnicodeScripts" ); 901 902 if ( func ) { 903 scriptArray = func(scriptCount); 904 Sequence< UnicodeScript > seq(scriptCount); 905 for(sal_Int16 i = 0; i < scriptCount; i++) { 906 seq[i] = UnicodeScript( OUString(scriptArray[i]).toInt32() ); 907 } 908 return seq; 909 } 910 else { 911 Sequence< UnicodeScript > seq1(0); 912 return seq1; 913 } 914 } 915 916 Sequence< OUString > SAL_CALL 917 LocaleData::getFollowPageWords( const Locale& rLocale ) throw(RuntimeException) 918 { 919 sal_Int16 wordCount = 0; 920 sal_Unicode **wordArray = NULL; 921 922 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getFollowPageWords" ); 923 924 if ( func ) { 925 wordArray = func(wordCount); 926 Sequence< OUString > seq(wordCount); 927 for(sal_Int16 i = 0; i < wordCount; i++) { 928 seq[i] = OUString(wordArray[i]); 929 } 930 return seq; 931 } 932 else { 933 Sequence< OUString > seq1(0); 934 return seq1; 935 } 936 } 937 938 Sequence< OUString > SAL_CALL 939 LocaleData::getTransliterations( const Locale& rLocale ) throw(RuntimeException) 940 { 941 942 sal_Int16 transliterationsCount = 0; 943 sal_Unicode **transliterationsArray = NULL; 944 945 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getTransliterations" ); 946 947 if ( func ) { 948 transliterationsArray = func(transliterationsCount); 949 950 Sequence< OUString > seq(transliterationsCount); 951 for(int i = 0; i < transliterationsCount; i++) { 952 OUString elem(transliterationsArray[i]); 953 seq[i] = elem; 954 } 955 return seq; 956 } 957 else { 958 Sequence< OUString > seq1(0); 959 return seq1; 960 } 961 962 963 } 964 965 966 LanguageCountryInfo SAL_CALL 967 LocaleData::getLanguageCountryInfo( const Locale& rLocale ) throw(RuntimeException) 968 { 969 sal_Int16 LCInfoCount = 0; 970 sal_Unicode **LCInfoArray = NULL; 971 972 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getLCInfo" ); 973 974 if ( func ) { 975 LCInfoArray = func(LCInfoCount); 976 LanguageCountryInfo info(LCInfoArray[0], 977 LCInfoArray[1], 978 LCInfoArray[2], 979 LCInfoArray[3], 980 LCInfoArray[4]); 981 return info; 982 } 983 else { 984 LanguageCountryInfo info1; 985 return info1; 986 } 987 988 } 989 990 991 ForbiddenCharacters SAL_CALL 992 LocaleData::getForbiddenCharacters( const Locale& rLocale ) throw(RuntimeException) 993 { 994 sal_Int16 LCForbiddenCharactersCount = 0; 995 sal_Unicode **LCForbiddenCharactersArray = NULL; 996 997 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getForbiddenCharacters" ); 998 999 if ( func ) { 1000 LCForbiddenCharactersArray = func(LCForbiddenCharactersCount); 1001 ForbiddenCharacters chars(LCForbiddenCharactersArray[0], LCForbiddenCharactersArray[1]); 1002 return chars; 1003 } 1004 else { 1005 ForbiddenCharacters chars1; 1006 return chars1; 1007 } 1008 } 1009 1010 OUString SAL_CALL 1011 LocaleData::getHangingCharacters( const Locale& rLocale ) throw(RuntimeException) 1012 { 1013 sal_Int16 LCForbiddenCharactersCount = 0; 1014 sal_Unicode **LCForbiddenCharactersArray = NULL; 1015 1016 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getForbiddenCharacters" ); 1017 1018 if ( func ) { 1019 LCForbiddenCharactersArray = func(LCForbiddenCharactersCount); 1020 return OUString(LCForbiddenCharactersArray[2]); 1021 } 1022 1023 return OUString(); 1024 } 1025 1026 Sequence< OUString > SAL_CALL 1027 LocaleData::getBreakIteratorRules( const Locale& rLocale ) throw(RuntimeException) 1028 { 1029 sal_Int16 LCBreakIteratorRuleCount = 0; 1030 sal_Unicode **LCBreakIteratorRulesArray = NULL; 1031 1032 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getBreakIteratorRules" ); 1033 1034 if ( func ) { 1035 LCBreakIteratorRulesArray = func(LCBreakIteratorRuleCount); 1036 Sequence< OUString > seq(LCBreakIteratorRuleCount); 1037 for(int i = 0; i < (LCBreakIteratorRuleCount); i++) { 1038 OUString elem(LCBreakIteratorRulesArray[i]); 1039 seq[i] = elem; 1040 } 1041 return seq; 1042 } 1043 else { 1044 Sequence< OUString > seq1(0); 1045 return seq1; 1046 } 1047 } 1048 1049 1050 Sequence< OUString > SAL_CALL 1051 LocaleData::getReservedWord( const Locale& rLocale ) throw(RuntimeException) 1052 { 1053 sal_Int16 LCReservedWordsCount = 0; 1054 sal_Unicode **LCReservedWordsArray = NULL; 1055 1056 MyFunc_Type func = (MyFunc_Type) getFunctionSymbol( rLocale, "getReservedWords" ); 1057 1058 if ( func ) { 1059 LCReservedWordsArray = func(LCReservedWordsCount); 1060 Sequence< OUString > seq(LCReservedWordsCount); 1061 for(int i = 0; i < (LCReservedWordsCount); i++) { 1062 OUString elem(LCReservedWordsArray[i]); 1063 seq[i] = elem; 1064 } 1065 return seq; 1066 } 1067 else { 1068 Sequence< OUString > seq1(0); 1069 return seq1; 1070 } 1071 } 1072 1073 1074 inline 1075 OUString C2U( const char* s ) 1076 { 1077 return OUString::createFromAscii( s ); 1078 } 1079 1080 Sequence< Sequence<beans::PropertyValue> > SAL_CALL 1081 LocaleData::getContinuousNumberingLevels( const lang::Locale& rLocale ) throw(RuntimeException) 1082 { 1083 int i; 1084 1085 // load symbol 1086 MyFunc_Type2 func = (MyFunc_Type2) getFunctionSymbol( rLocale, "getContinuousNumberingLevels" ); 1087 1088 if ( func ) 1089 { 1090 // invoke function 1091 sal_Int16 nStyles; 1092 sal_Int16 nAttributes; 1093 sal_Unicode*** p0 = func( nStyles, nAttributes ); 1094 1095 // allocate memory for nAttributes attributes for each of the nStyles styles. 1096 Sequence< Sequence<beans::PropertyValue> > pv( nStyles ); 1097 for( i=0; i<pv.getLength(); i++ ) { 1098 pv[i] = Sequence<beans::PropertyValue>( nAttributes ); 1099 } 1100 1101 sal_Unicode*** pStyle = p0; 1102 for( i=0; i<nStyles; i++ ) { 1103 sal_Unicode** pAttribute = pStyle[i]; 1104 for( int j=0; j<nAttributes; j++ ) { // prefix, numberingtype, ... 1105 sal_Unicode* pString = pAttribute[j]; 1106 beans::PropertyValue& rVal = pv[i][j]; 1107 OUString sVal; 1108 if( pString ) { 1109 if( 0 != j && 2 != j ) 1110 sVal = pString; 1111 else if( *pString ) 1112 sVal = OUString( pString, 1 ); 1113 } 1114 1115 switch( j ) 1116 { 1117 case 0: 1118 rVal.Name = C2U("Prefix"); 1119 rVal.Value <<= sVal; 1120 break; 1121 case 1: 1122 rVal.Name = C2U("NumberingType"); 1123 rVal.Value <<= (sal_Int16) sVal.toInt32(); 1124 break; 1125 case 2: 1126 rVal.Name = C2U("Suffix"); 1127 rVal.Value <<= sVal; 1128 break; 1129 case 3: 1130 rVal.Name = C2U("Transliteration"); 1131 rVal.Value <<= sVal; 1132 break; 1133 case 4: 1134 rVal.Name = C2U("NatNum"); 1135 rVal.Value <<= (sal_Int16) sVal.toInt32(); 1136 break; 1137 default: 1138 OSL_ASSERT(0); 1139 } 1140 } 1141 } 1142 return pv; 1143 } 1144 1145 Sequence< Sequence<beans::PropertyValue> > seq1(0); 1146 return seq1; 1147 } 1148 1149 // ============================================================================ 1150 // \/ OutlineNumbering helper class \/ 1151 // 1152 #include <com/sun/star/container/XIndexAccess.hpp> 1153 #include <cppuhelper/implbase1.hxx> 1154 1155 namespace com{ namespace sun{ namespace star{ namespace lang { 1156 struct Locale; 1157 }}}} 1158 //----------------------------------------------------------------------------- 1159 struct OutlineNumberingLevel_Impl 1160 { 1161 OUString sPrefix; 1162 sal_Int16 nNumType; //com::sun::star::style::NumberingType 1163 OUString sSuffix; 1164 sal_Unicode cBulletChar; 1165 const sal_Char* sBulletFontName; 1166 sal_Int16 nParentNumbering; 1167 sal_Int32 nLeftMargin; 1168 sal_Int32 nSymbolTextDistance; 1169 sal_Int32 nFirstLineOffset; 1170 OUString sTransliteration; 1171 sal_Int32 nNatNum; 1172 }; 1173 //----------------------------------------------------------------------------- 1174 class OutlineNumbering : public cppu::WeakImplHelper1 < container::XIndexAccess > 1175 { 1176 const OutlineNumberingLevel_Impl* m_pOutlineLevels; 1177 sal_Int16 m_nCount; 1178 public: 1179 // OutlineNumbering(const OutlineNumberingLevel_Impl* pOutlineLevels); 1180 OutlineNumbering(const OutlineNumberingLevel_Impl* pOutlineLevels, int nLevels); 1181 ~OutlineNumbering(); 1182 1183 //XIndexAccess 1184 virtual sal_Int32 SAL_CALL getCount( ) throw(RuntimeException); 1185 virtual Any SAL_CALL getByIndex( sal_Int32 Index ) 1186 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException); 1187 1188 //XElementAccess 1189 virtual Type SAL_CALL getElementType( ) throw(RuntimeException); 1190 virtual sal_Bool SAL_CALL hasElements( ) throw(RuntimeException); 1191 }; 1192 1193 // 1194 // OutlineNumbering helper class 1195 // ============================================================================ 1196 1197 static 1198 sal_Char* U2C( OUString str ) 1199 { 1200 sal_Char* s = new sal_Char[ str.getLength()+1 ]; 1201 int i; 1202 for( i = 0; i < str.getLength(); i++) 1203 s[i] = sal::static_int_cast<sal_Char>( str[i] ); 1204 s[i]='\0'; 1205 return s; 1206 } 1207 1208 1209 Sequence< Reference<container::XIndexAccess> > SAL_CALL 1210 LocaleData::getOutlineNumberingLevels( const lang::Locale& rLocale ) throw(RuntimeException) 1211 { 1212 int i; 1213 1214 // load symbol 1215 MyFunc_Type3 func = (MyFunc_Type3) getFunctionSymbol( rLocale, "getOutlineNumberingLevels" ); 1216 1217 if ( func ) 1218 { 1219 // invoke function 1220 sal_Int16 nStyles; 1221 sal_Int16 nLevels; 1222 sal_Int16 nAttributes; 1223 sal_Unicode**** p0 = func( nStyles, nLevels, nAttributes ); 1224 1225 Sequence< Reference<container::XIndexAccess> > aRet( nStyles ); 1226 1227 OUString aEmptyStr; 1228 1229 sal_Unicode**** pStyle = p0; 1230 for( i=0; i<nStyles; i++ ) 1231 { 1232 int j; 1233 1234 OutlineNumberingLevel_Impl* level = new OutlineNumberingLevel_Impl[ nLevels+1 ]; 1235 sal_Unicode*** pLevel = pStyle[i]; 1236 for( j = 0; j < nLevels; j++ ) 1237 { 1238 sal_Unicode** pAttribute = pLevel[j]; 1239 for( int k=0; k<nAttributes; k++ ) 1240 { 1241 OUString tmp( pAttribute[k] ); 1242 switch( k ) 1243 { 1244 case 0: level[j].sPrefix = tmp; break; 1245 case 1: level[j].nNumType = sal::static_int_cast<sal_Int16>(tmp.toInt32()); break; 1246 case 2: level[j].sSuffix = tmp; break; 1247 //case 3: level[j].cBulletChar = tmp.toChar(); break; 1248 case 3: level[j].cBulletChar = sal::static_int_cast<sal_Unicode>(tmp.toInt32(16)); break; // base 16 1249 case 4: level[j].sBulletFontName = U2C( tmp ); break; 1250 case 5: level[j].nParentNumbering = sal::static_int_cast<sal_Int16>(tmp.toInt32()); break; 1251 case 6: level[j].nLeftMargin = tmp.toInt32(); break; 1252 case 7: level[j].nSymbolTextDistance = tmp.toInt32(); break; 1253 case 8: level[j].nFirstLineOffset = tmp.toInt32(); break; 1254 case 9: // Adjust 1255 // these values seem to be hard-coded elsewhere: 1256 // level[j].Value <<= (sal_Int16) text::HoriOrientation::LEFT; 1257 // level[j].Value <<= (sal_Int16) style::HorizontalAlignment::LEFT; 1258 break; 1259 case 10: level[j].sTransliteration = tmp; break; 1260 case 11: level[j].nNatNum = tmp.toInt32(); break; 1261 default: 1262 OSL_ASSERT(0); 1263 } 1264 } 1265 } 1266 level[j].sPrefix = aEmptyStr; 1267 level[j].nNumType = 0; 1268 level[j].sSuffix = aEmptyStr; 1269 level[j].cBulletChar = 0; 1270 level[j].sBulletFontName = 0; 1271 level[j].nParentNumbering = 0; 1272 level[j].nLeftMargin = 0; 1273 level[j].nSymbolTextDistance = 0; 1274 level[j].nFirstLineOffset = 0; 1275 level[j].sTransliteration = aEmptyStr; 1276 level[j].nNatNum = 0; 1277 aRet[i] = new OutlineNumbering( level, nLevels ); 1278 } 1279 return aRet; 1280 } 1281 else { 1282 Sequence< Reference<container::XIndexAccess> > seq1(0); 1283 return seq1; 1284 } 1285 } 1286 1287 ///////////////////////////////////////////////////////////////////////////////////////////// 1288 //////////////////////////////////helper functions/////////////////////////////////////////// 1289 ///////////////////////////////////////////////////////////////////////////////////////////// 1290 1291 oslGenericFunction SAL_CALL LocaleData::getFunctionSymbol( const Locale& rLocale, const sal_Char* pFunction ) 1292 throw(RuntimeException) 1293 { 1294 lcl_LookupTableHelper & rLookupTable = lcl_LookupTableStatic::get(); 1295 1296 OUStringBuffer aBuf(1); 1297 if (cachedItem.get() && cachedItem->equals(rLocale)) { 1298 aBuf.ensureCapacity(strlen(pFunction) + 1 + strlen(cachedItem->localeName)); 1299 return cachedItem->module->getFunctionSymbol(aBuf.appendAscii(pFunction).append(under). 1300 appendAscii(cachedItem->localeName).makeStringAndClear()); 1301 } 1302 1303 oslGenericFunction pSymbol = 0; 1304 static OUString tw(OUString::createFromAscii("TW")); 1305 static OUString en_US(OUString::createFromAscii("en_US")); 1306 1307 sal_Int32 l = rLocale.Language.getLength(); 1308 sal_Int32 c = rLocale.Country.getLength(); 1309 sal_Int32 v = rLocale.Variant.getLength(); 1310 aBuf.ensureCapacity(l+c+v+3); 1311 1312 LocaleDataLookupTableItem *pCachedItem = 0; 1313 1314 if ((l > 0 && c > 0 && v > 0 && 1315 // load function with name <func>_<lang>_<country>_<varian> 1316 (pSymbol = rLookupTable.getFunctionSymbolByName(aBuf.append(rLocale.Language).append(under).append( 1317 rLocale.Country).append(under).append(rLocale.Variant).makeStringAndClear(), pFunction, &pCachedItem)) != 0) || 1318 (l > 0 && c > 0 && 1319 // load function with name <ase>_<lang>_<country> 1320 (pSymbol = rLookupTable.getFunctionSymbolByName(aBuf.append(rLocale.Language).append(under).append( 1321 rLocale.Country).makeStringAndClear(), pFunction, &pCachedItem)) != 0) || 1322 (l > 0 && c > 0 && rLocale.Language.equalsAscii("zh") && 1323 (rLocale.Country.equalsAscii("HK") || 1324 rLocale.Country.equalsAscii("MO")) && 1325 // if the country code is HK or MO, one more step to try TW. 1326 (pSymbol = rLookupTable.getFunctionSymbolByName(aBuf.append(rLocale.Language).append(under).append(tw).makeStringAndClear(), 1327 pFunction, &pCachedItem)) != 0) || 1328 (l > 0 && 1329 // load function with name <func>_<lang> 1330 (pSymbol = rLookupTable.getFunctionSymbolByName(rLocale.Language, pFunction, &pCachedItem)) != 0) || 1331 // load default function with name <func>_en_US 1332 (pSymbol = rLookupTable.getFunctionSymbolByName(en_US, pFunction, &pCachedItem)) != 0) 1333 { 1334 if( pCachedItem ) 1335 cachedItem.reset( pCachedItem ); 1336 if( cachedItem.get()) 1337 cachedItem->aLocale = rLocale; 1338 return pSymbol; 1339 } 1340 throw RuntimeException(); 1341 } 1342 1343 Sequence< Locale > SAL_CALL 1344 LocaleData::getAllInstalledLocaleNames() throw(RuntimeException) 1345 { 1346 Sequence< lang::Locale > seq( nbOfLocales ); 1347 OUString empStr; 1348 sal_Int16 nInstalled = 0; 1349 1350 for( sal_Int16 i=0; i<nbOfLocales; i++ ) { 1351 OUString name = OUString::createFromAscii( aLibTable[i].pLocale ); 1352 1353 // Check if the locale is really available and not just in the table, 1354 // don't allow fall backs. 1355 LocaleDataLookupTableItem *pCachedItem = 0; 1356 if (lcl_LookupTableStatic::get().getFunctionSymbolByName( name, "getLocaleItem", &pCachedItem )) { 1357 if( pCachedItem ) 1358 cachedItem.reset( pCachedItem ); 1359 sal_Int32 index = 0; 1360 lang::Locale tmpLocale(name.getToken(0, under, index), empStr, empStr); 1361 if (index >= 0) { 1362 tmpLocale.Country = name.getToken(0, under, index); 1363 if (index >= 0) 1364 tmpLocale.Variant = name.getToken(0, under, index); 1365 } 1366 seq[nInstalled++] = tmpLocale; 1367 } 1368 } 1369 if ( nInstalled < nbOfLocales ) 1370 seq.realloc( nInstalled ); // reflect reality 1371 1372 return seq; 1373 } 1374 1375 // ============================================================================ 1376 1377 using namespace ::com::sun::star::container; 1378 using namespace ::com::sun::star::beans; 1379 using namespace ::com::sun::star::style; 1380 using namespace ::com::sun::star::text; 1381 1382 // // bad: can't have empty prefix ... 1383 // OutlineNumbering::OutlineNumbering(const OutlineNumberingLevel_Impl* pOutlnLevels) : 1384 // m_pOutlineLevels(pOutlnLevels), 1385 // m_nCount(0) 1386 // { 1387 // const OutlineNumberingLevel_Impl* pTemp = m_pOutlineLevels; 1388 // while((pTemp++)->sPrefix) 1389 // m_nCount++; 1390 // } 1391 1392 OutlineNumbering::OutlineNumbering(const OutlineNumberingLevel_Impl* pOutlnLevels, int nLevels) : 1393 m_pOutlineLevels(pOutlnLevels), 1394 m_nCount(sal::static_int_cast<sal_Int16>(nLevels)) 1395 { 1396 } 1397 1398 OutlineNumbering::~OutlineNumbering() 1399 { 1400 delete [] m_pOutlineLevels; 1401 } 1402 1403 sal_Int32 OutlineNumbering::getCount( ) throw(RuntimeException) 1404 { 1405 return m_nCount; 1406 } 1407 1408 Any OutlineNumbering::getByIndex( sal_Int32 nIndex ) 1409 throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException) 1410 { 1411 if(nIndex < 0 || nIndex >= m_nCount) 1412 throw IndexOutOfBoundsException(); 1413 const OutlineNumberingLevel_Impl* pTemp = m_pOutlineLevels; 1414 pTemp += nIndex; 1415 Any aRet; 1416 1417 Sequence<PropertyValue> aOutlineNumbering(12); 1418 PropertyValue* pValues = aOutlineNumbering.getArray(); 1419 pValues[0].Name = C2U( "Prefix"); 1420 pValues[0].Value <<= pTemp->sPrefix; 1421 pValues[1].Name = C2U("NumberingType"); 1422 pValues[1].Value <<= pTemp->nNumType; 1423 pValues[2].Name = C2U("Suffix"); 1424 pValues[2].Value <<= pTemp->sSuffix; 1425 pValues[3].Name = C2U("BulletChar"); 1426 pValues[3].Value <<= OUString(&pTemp->cBulletChar, 1); 1427 pValues[4].Name = C2U("BulletFontName"); 1428 pValues[4].Value <<= C2U(pTemp->sBulletFontName); 1429 pValues[5].Name = C2U("ParentNumbering"); 1430 pValues[5].Value <<= pTemp->nParentNumbering; 1431 pValues[6].Name = C2U("LeftMargin"); 1432 pValues[6].Value <<= pTemp->nLeftMargin; 1433 pValues[7].Name = C2U("SymbolTextDistance"); 1434 pValues[7].Value <<= pTemp->nSymbolTextDistance; 1435 pValues[8].Name = C2U("FirstLineOffset"); 1436 pValues[8].Value <<= pTemp->nFirstLineOffset; 1437 pValues[9].Name = C2U("Adjust"); 1438 pValues[9].Value <<= (sal_Int16)HoriOrientation::LEFT; 1439 pValues[10].Name = C2U("Transliteration"); 1440 pValues[10].Value <<= pTemp->sTransliteration; 1441 pValues[11].Name = C2U("NatNum"); 1442 pValues[11].Value <<= pTemp->nNatNum; 1443 aRet <<= aOutlineNumbering; 1444 return aRet; 1445 } 1446 1447 Type OutlineNumbering::getElementType( ) throw(RuntimeException) 1448 { 1449 return ::getCppuType((Sequence<PropertyValue>*)0); 1450 } 1451 1452 sal_Bool OutlineNumbering::hasElements( ) throw(RuntimeException) 1453 { 1454 return m_nCount > 0; 1455 } 1456 1457 OUString SAL_CALL 1458 LocaleData::getImplementationName() throw( RuntimeException ) 1459 { 1460 return OUString::createFromAscii(clocaledata); 1461 } 1462 1463 sal_Bool SAL_CALL 1464 LocaleData::supportsService(const OUString& rServiceName) 1465 throw( RuntimeException ) 1466 { 1467 return !rServiceName.compareToAscii(clocaledata); 1468 } 1469 1470 Sequence< OUString > SAL_CALL 1471 LocaleData::getSupportedServiceNames() throw( RuntimeException ) 1472 { 1473 Sequence< OUString > aRet(1); 1474 aRet[0] = OUString::createFromAscii(clocaledata); 1475 return aRet; 1476 } 1477