1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_unotools.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <string.h> // memcpy() 32*cdf0e10cSrcweir #include <stdio.h> // fprintf(), stderr 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include <unotools/localedatawrapper.hxx> 35*cdf0e10cSrcweir #include <unotools/numberformatcodewrapper.hxx> 36*cdf0e10cSrcweir #include <unotools/calendarwrapper.hxx> 37*cdf0e10cSrcweir #include <unotools/digitgroupingiterator.hxx> 38*cdf0e10cSrcweir #include <tools/string.hxx> 39*cdf0e10cSrcweir #include <tools/debug.hxx> 40*cdf0e10cSrcweir #include <i18npool/mslangid.hxx> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #ifndef _COMPHELPER_COMPONENTFACTORY_HXX_ 43*cdf0e10cSrcweir #include <comphelper/componentfactory.hxx> 44*cdf0e10cSrcweir #endif 45*cdf0e10cSrcweir #include <unotools/processfactory.hxx> 46*cdf0e10cSrcweir #include <com/sun/star/uno/XInterface.hpp> 47*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 48*cdf0e10cSrcweir #include <com/sun/star/i18n/KNumberFormatUsage.hpp> 49*cdf0e10cSrcweir #include <com/sun/star/i18n/KNumberFormatType.hpp> 50*cdf0e10cSrcweir #include <com/sun/star/i18n/CalendarFieldIndex.hpp> 51*cdf0e10cSrcweir #include <com/sun/star/i18n/CalendarDisplayIndex.hpp> 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir #ifndef _COM_SUN_STAR_I18N_NUMBERFORMATINDEX_HPP_ 54*cdf0e10cSrcweir #include <com/sun/star/i18n/NumberFormatIndex.hdl> 55*cdf0e10cSrcweir #endif 56*cdf0e10cSrcweir #include <rtl/instance.hxx> 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir #define LOCALEDATA_LIBRARYNAME "i18npool" 59*cdf0e10cSrcweir #define LOCALEDATA_SERVICENAME "com.sun.star.i18n.LocaleData" 60*cdf0e10cSrcweir 61*cdf0e10cSrcweir static const int nDateFormatInvalid = -1; 62*cdf0e10cSrcweir static const sal_uInt16 nCurrFormatInvalid = 0xffff; 63*cdf0e10cSrcweir static const sal_uInt16 nCurrFormatDefault = 0; 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir using namespace ::com::sun::star; 66*cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 67*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 68*cdf0e10cSrcweir 69*cdf0e10cSrcweir namespace 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir struct InstalledLocales 72*cdf0e10cSrcweir : public rtl::Static< 73*cdf0e10cSrcweir uno::Sequence< lang::Locale >, InstalledLocales > 74*cdf0e10cSrcweir {}; 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir struct InstalledLanguageTypes 77*cdf0e10cSrcweir : public rtl::Static< 78*cdf0e10cSrcweir uno::Sequence< sal_uInt16 >, InstalledLanguageTypes > 79*cdf0e10cSrcweir {}; 80*cdf0e10cSrcweir } 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir sal_uInt8 LocaleDataWrapper::nLocaleDataChecking = 0; 83*cdf0e10cSrcweir 84*cdf0e10cSrcweir LocaleDataWrapper::LocaleDataWrapper( 85*cdf0e10cSrcweir const Reference< lang::XMultiServiceFactory > & xSF, 86*cdf0e10cSrcweir const lang::Locale& rLocale 87*cdf0e10cSrcweir ) 88*cdf0e10cSrcweir : 89*cdf0e10cSrcweir xSMgr( xSF ), 90*cdf0e10cSrcweir bLocaleDataItemValid( sal_False ), 91*cdf0e10cSrcweir bReservedWordValid( sal_False ) 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir setLocale( rLocale ); 94*cdf0e10cSrcweir if ( xSMgr.is() ) 95*cdf0e10cSrcweir { 96*cdf0e10cSrcweir try 97*cdf0e10cSrcweir { 98*cdf0e10cSrcweir xLD = Reference< XLocaleData2 > ( xSMgr->createInstance( 99*cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALEDATA_SERVICENAME ) ) ), 100*cdf0e10cSrcweir uno::UNO_QUERY ); 101*cdf0e10cSrcweir } 102*cdf0e10cSrcweir catch ( Exception& e ) 103*cdf0e10cSrcweir { 104*cdf0e10cSrcweir #ifdef DBG_UTIL 105*cdf0e10cSrcweir ByteString aMsg( "LocaleDataWrapper ctor: Exception caught\n" ); 106*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 107*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 108*cdf0e10cSrcweir #else 109*cdf0e10cSrcweir (void)e; 110*cdf0e10cSrcweir #endif 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir } 113*cdf0e10cSrcweir else 114*cdf0e10cSrcweir { // try to get an instance somehow 115*cdf0e10cSrcweir DBG_ERRORFILE( "LocaleDataWrapper: no service manager, trying own" ); 116*cdf0e10cSrcweir try 117*cdf0e10cSrcweir { 118*cdf0e10cSrcweir Reference< XInterface > xI = ::comphelper::getComponentInstance( 119*cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LLCF_LIBNAME( LOCALEDATA_LIBRARYNAME ) ) ), 120*cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( LOCALEDATA_SERVICENAME ) ) ); 121*cdf0e10cSrcweir if ( xI.is() ) 122*cdf0e10cSrcweir { 123*cdf0e10cSrcweir Any x = xI->queryInterface( ::getCppuType((const Reference< XLocaleData2 >*)0) ); 124*cdf0e10cSrcweir x >>= xLD; 125*cdf0e10cSrcweir } 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir catch ( Exception& e ) 128*cdf0e10cSrcweir { 129*cdf0e10cSrcweir #ifdef DBG_UTIL 130*cdf0e10cSrcweir ByteString aMsg( "getComponentInstance: Exception caught\n" ); 131*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 132*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 133*cdf0e10cSrcweir #else 134*cdf0e10cSrcweir (void)e; 135*cdf0e10cSrcweir #endif 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir } 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir LocaleDataWrapper::~LocaleDataWrapper() 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir } 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir void LocaleDataWrapper::setLocale( const ::com::sun::star::lang::Locale& rLocale ) 147*cdf0e10cSrcweir { 148*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nCriticalChange ); 149*cdf0e10cSrcweir aLocale = rLocale; 150*cdf0e10cSrcweir invalidateData(); 151*cdf0e10cSrcweir } 152*cdf0e10cSrcweir 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir const ::com::sun::star::lang::Locale& LocaleDataWrapper::getLocale() const 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 157*cdf0e10cSrcweir return aLocale; 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir void LocaleDataWrapper::invalidateData() 162*cdf0e10cSrcweir { 163*cdf0e10cSrcweir aCurrSymbol.Erase(); 164*cdf0e10cSrcweir aCurrBankSymbol.Erase(); 165*cdf0e10cSrcweir nDateFormat = nLongDateFormat = nDateFormatInvalid; 166*cdf0e10cSrcweir nCurrPositiveFormat = nCurrNegativeFormat = nCurrDigits = nCurrFormatInvalid; 167*cdf0e10cSrcweir if ( bLocaleDataItemValid ) 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir for ( sal_Int32 j=0; j<LocaleItem::COUNT; j++ ) 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir aLocaleItem[j].Erase(); 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir bLocaleDataItemValid = sal_False; 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir if ( bReservedWordValid ) 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir for ( sal_Int16 j=0; j<reservedWords::COUNT; j++ ) 178*cdf0e10cSrcweir { 179*cdf0e10cSrcweir aReservedWord[j].Erase(); 180*cdf0e10cSrcweir } 181*cdf0e10cSrcweir bReservedWordValid = sal_False; 182*cdf0e10cSrcweir } 183*cdf0e10cSrcweir xDefaultCalendar.reset(); 184*cdf0e10cSrcweir if (aGrouping.getLength()) 185*cdf0e10cSrcweir aGrouping[0] = 0; 186*cdf0e10cSrcweir // dummies 187*cdf0e10cSrcweir cCurrZeroChar = '0'; 188*cdf0e10cSrcweir } 189*cdf0e10cSrcweir 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir ::com::sun::star::i18n::LanguageCountryInfo LocaleDataWrapper::getLanguageCountryInfo() const 192*cdf0e10cSrcweir { 193*cdf0e10cSrcweir try 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir if ( xLD.is() ) 196*cdf0e10cSrcweir return xLD->getLanguageCountryInfo( getLocale() ); 197*cdf0e10cSrcweir } 198*cdf0e10cSrcweir catch ( Exception& e ) 199*cdf0e10cSrcweir { 200*cdf0e10cSrcweir #ifdef DBG_UTIL 201*cdf0e10cSrcweir ByteString aMsg( "getLanguageCountryInfo: Exception caught\n" ); 202*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 203*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 204*cdf0e10cSrcweir #else 205*cdf0e10cSrcweir (void)e; 206*cdf0e10cSrcweir #endif 207*cdf0e10cSrcweir } 208*cdf0e10cSrcweir return ::com::sun::star::i18n::LanguageCountryInfo(); 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir ::com::sun::star::i18n::LocaleDataItem LocaleDataWrapper::getLocaleItem() const 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir try 215*cdf0e10cSrcweir { 216*cdf0e10cSrcweir if ( xLD.is() ) 217*cdf0e10cSrcweir return xLD->getLocaleItem( getLocale() ); 218*cdf0e10cSrcweir } 219*cdf0e10cSrcweir catch ( Exception& e ) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir #ifdef DBG_UTIL 222*cdf0e10cSrcweir ByteString aMsg( "getLocaleItem: Exception caught\n" ); 223*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 224*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 225*cdf0e10cSrcweir #else 226*cdf0e10cSrcweir (void)e; 227*cdf0e10cSrcweir #endif 228*cdf0e10cSrcweir } 229*cdf0e10cSrcweir return ::com::sun::star::i18n::LocaleDataItem(); 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Calendar > LocaleDataWrapper::getAllCalendars() const 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir try 236*cdf0e10cSrcweir { 237*cdf0e10cSrcweir if ( xLD.is() ) 238*cdf0e10cSrcweir return xLD->getAllCalendars( getLocale() ); 239*cdf0e10cSrcweir } 240*cdf0e10cSrcweir catch ( Exception& e ) 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir #ifdef DBG_UTIL 243*cdf0e10cSrcweir ByteString aMsg( "getAllCalendars: Exception caught\n" ); 244*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 245*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 246*cdf0e10cSrcweir #else 247*cdf0e10cSrcweir (void)e; 248*cdf0e10cSrcweir #endif 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Calendar >(0); 251*cdf0e10cSrcweir } 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Currency2 > LocaleDataWrapper::getAllCurrencies() const 255*cdf0e10cSrcweir { 256*cdf0e10cSrcweir try 257*cdf0e10cSrcweir { 258*cdf0e10cSrcweir if ( xLD.is() ) 259*cdf0e10cSrcweir return xLD->getAllCurrencies2( getLocale() ); 260*cdf0e10cSrcweir } 261*cdf0e10cSrcweir catch ( Exception& e ) 262*cdf0e10cSrcweir { 263*cdf0e10cSrcweir #ifdef DBG_UTIL 264*cdf0e10cSrcweir ByteString aMsg( "getAllCurrencies: Exception caught\n" ); 265*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 266*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 267*cdf0e10cSrcweir #else 268*cdf0e10cSrcweir (void)e; 269*cdf0e10cSrcweir #endif 270*cdf0e10cSrcweir } 271*cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Currency2 >(0); 272*cdf0e10cSrcweir } 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::FormatElement > LocaleDataWrapper::getAllFormats() const 276*cdf0e10cSrcweir { 277*cdf0e10cSrcweir try 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir if ( xLD.is() ) 280*cdf0e10cSrcweir return xLD->getAllFormats( getLocale() ); 281*cdf0e10cSrcweir } 282*cdf0e10cSrcweir catch ( Exception& e ) 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir #ifdef DBG_UTIL 285*cdf0e10cSrcweir ByteString aMsg( "getAllFormats: Exception caught\n" ); 286*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 287*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 288*cdf0e10cSrcweir #else 289*cdf0e10cSrcweir (void)e; 290*cdf0e10cSrcweir #endif 291*cdf0e10cSrcweir } 292*cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::FormatElement >(0); 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Implementation > LocaleDataWrapper::getCollatorImplementations() const 297*cdf0e10cSrcweir { 298*cdf0e10cSrcweir try 299*cdf0e10cSrcweir { 300*cdf0e10cSrcweir if ( xLD.is() ) 301*cdf0e10cSrcweir return xLD->getCollatorImplementations( getLocale() ); 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir catch ( Exception& e ) 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir #ifdef DBG_UTIL 306*cdf0e10cSrcweir ByteString aMsg( "getCollatorImplementations: Exception caught\n" ); 307*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 308*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 309*cdf0e10cSrcweir #else 310*cdf0e10cSrcweir (void)e; 311*cdf0e10cSrcweir #endif 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::Implementation >(0); 314*cdf0e10cSrcweir } 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::rtl::OUString > LocaleDataWrapper::getTransliterations() const 318*cdf0e10cSrcweir { 319*cdf0e10cSrcweir try 320*cdf0e10cSrcweir { 321*cdf0e10cSrcweir if ( xLD.is() ) 322*cdf0e10cSrcweir return xLD->getTransliterations( getLocale() ); 323*cdf0e10cSrcweir } 324*cdf0e10cSrcweir catch ( Exception& e ) 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir #ifdef DBG_UTIL 327*cdf0e10cSrcweir ByteString aMsg( "getTransliterations: Exception caught\n" ); 328*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 329*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 330*cdf0e10cSrcweir #else 331*cdf0e10cSrcweir (void)e; 332*cdf0e10cSrcweir #endif 333*cdf0e10cSrcweir } 334*cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< ::rtl::OUString >(0); 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir ::com::sun::star::i18n::ForbiddenCharacters LocaleDataWrapper::getForbiddenCharacters() const 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir try 341*cdf0e10cSrcweir { 342*cdf0e10cSrcweir if ( xLD.is() ) 343*cdf0e10cSrcweir return xLD->getForbiddenCharacters( getLocale() ); 344*cdf0e10cSrcweir } 345*cdf0e10cSrcweir catch ( Exception& e ) 346*cdf0e10cSrcweir { 347*cdf0e10cSrcweir #ifdef DBG_UTIL 348*cdf0e10cSrcweir ByteString aMsg( "getForbiddenCharacters: Exception caught\n" ); 349*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 350*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 351*cdf0e10cSrcweir #else 352*cdf0e10cSrcweir (void)e; 353*cdf0e10cSrcweir #endif 354*cdf0e10cSrcweir } 355*cdf0e10cSrcweir return ::com::sun::star::i18n::ForbiddenCharacters(); 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir 359*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::rtl::OUString > LocaleDataWrapper::getReservedWord() const 360*cdf0e10cSrcweir { 361*cdf0e10cSrcweir try 362*cdf0e10cSrcweir { 363*cdf0e10cSrcweir if ( xLD.is() ) 364*cdf0e10cSrcweir return xLD->getReservedWord( getLocale() ); 365*cdf0e10cSrcweir } 366*cdf0e10cSrcweir catch ( Exception& e ) 367*cdf0e10cSrcweir { 368*cdf0e10cSrcweir #ifdef DBG_UTIL 369*cdf0e10cSrcweir ByteString aMsg( "getReservedWord: Exception caught\n" ); 370*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 371*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 372*cdf0e10cSrcweir #else 373*cdf0e10cSrcweir (void)e; 374*cdf0e10cSrcweir #endif 375*cdf0e10cSrcweir } 376*cdf0e10cSrcweir return ::com::sun::star::uno::Sequence< ::rtl::OUString >(0); 377*cdf0e10cSrcweir } 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > LocaleDataWrapper::getAllInstalledLocaleNames() const 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir uno::Sequence< lang::Locale > &rInstalledLocales = InstalledLocales::get(); 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir if ( rInstalledLocales.getLength() ) 385*cdf0e10cSrcweir return rInstalledLocales; 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir try 388*cdf0e10cSrcweir { 389*cdf0e10cSrcweir if ( xLD.is() ) 390*cdf0e10cSrcweir rInstalledLocales = xLD->getAllInstalledLocaleNames(); 391*cdf0e10cSrcweir } 392*cdf0e10cSrcweir catch ( Exception& e ) 393*cdf0e10cSrcweir { 394*cdf0e10cSrcweir #ifdef DBG_UTIL 395*cdf0e10cSrcweir ByteString aMsg( "getAllInstalledLocaleNames: Exception caught\n" ); 396*cdf0e10cSrcweir aMsg += ByteString( String( e.Message ), RTL_TEXTENCODING_UTF8 ); 397*cdf0e10cSrcweir DBG_ERRORFILE( aMsg.GetBuffer() ); 398*cdf0e10cSrcweir #else 399*cdf0e10cSrcweir (void)e; 400*cdf0e10cSrcweir #endif 401*cdf0e10cSrcweir } 402*cdf0e10cSrcweir return rInstalledLocales; 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir // --- Impl and helpers ---------------------------------------------------- 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir // static 409*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > LocaleDataWrapper::getInstalledLocaleNames() 410*cdf0e10cSrcweir { 411*cdf0e10cSrcweir const uno::Sequence< lang::Locale > &rInstalledLocales = 412*cdf0e10cSrcweir InstalledLocales::get(); 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir if ( !rInstalledLocales.getLength() ) 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir LocaleDataWrapper aLDW( ::comphelper::getProcessServiceFactory(), lang::Locale() ); 417*cdf0e10cSrcweir aLDW.getAllInstalledLocaleNames(); 418*cdf0e10cSrcweir } 419*cdf0e10cSrcweir return rInstalledLocales; 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir 422*cdf0e10cSrcweir // static 423*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< sal_uInt16 > LocaleDataWrapper::getInstalledLanguageTypes() 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir uno::Sequence< sal_uInt16 > &rInstalledLanguageTypes = 426*cdf0e10cSrcweir InstalledLanguageTypes::get(); 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir if ( rInstalledLanguageTypes.getLength() ) 429*cdf0e10cSrcweir return rInstalledLanguageTypes; 430*cdf0e10cSrcweir 431*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< ::com::sun::star::lang::Locale > xLoc = 432*cdf0e10cSrcweir getInstalledLocaleNames(); 433*cdf0e10cSrcweir sal_Int32 nCount = xLoc.getLength(); 434*cdf0e10cSrcweir ::com::sun::star::uno::Sequence< sal_uInt16 > xLang( nCount ); 435*cdf0e10cSrcweir sal_Int32 nLanguages = 0; 436*cdf0e10cSrcweir for ( sal_Int32 i=0; i<nCount; i++ ) 437*cdf0e10cSrcweir { 438*cdf0e10cSrcweir String aDebugLocale; 439*cdf0e10cSrcweir if (areChecksEnabled()) 440*cdf0e10cSrcweir { 441*cdf0e10cSrcweir aDebugLocale = xLoc[i].Language; 442*cdf0e10cSrcweir if ( xLoc[i].Country.getLength() ) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir aDebugLocale += '_'; 445*cdf0e10cSrcweir aDebugLocale += String( xLoc[i].Country); 446*cdf0e10cSrcweir if ( xLoc[i].Variant.getLength() ) 447*cdf0e10cSrcweir { 448*cdf0e10cSrcweir aDebugLocale += '_'; 449*cdf0e10cSrcweir aDebugLocale += String( xLoc[i].Variant); 450*cdf0e10cSrcweir } 451*cdf0e10cSrcweir } 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir if ( xLoc[i].Variant.getLength() ) 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir if (areChecksEnabled()) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 459*cdf0e10cSrcweir "LocaleDataWrapper::getInstalledLanguageTypes: Variants not supported, locale\n")); 460*cdf0e10cSrcweir aMsg += aDebugLocale; 461*cdf0e10cSrcweir outputCheckMessage( aMsg ); 462*cdf0e10cSrcweir } 463*cdf0e10cSrcweir continue; 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir LanguageType eLang = MsLangId::convertLocaleToLanguage( xLoc[i] ); 466*cdf0e10cSrcweir 467*cdf0e10cSrcweir // In checks, exclude known problems because no MS-LCID defined. 468*cdf0e10cSrcweir if (areChecksEnabled() && eLang == LANGUAGE_DONTKNOW 469*cdf0e10cSrcweir // && !aDebugLocale.EqualsAscii( "br_AE" ) // ?!? Breton in United Arabic Emirates 470*cdf0e10cSrcweir ) 471*cdf0e10cSrcweir { 472*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 473*cdf0e10cSrcweir "ConvertIsoNamesToLanguage: unknown MS-LCID for locale\n")); 474*cdf0e10cSrcweir aMsg += aDebugLocale; 475*cdf0e10cSrcweir outputCheckMessage( aMsg ); 476*cdf0e10cSrcweir } 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir switch ( eLang ) 479*cdf0e10cSrcweir { 480*cdf0e10cSrcweir case LANGUAGE_NORWEGIAN : // no_NO, not Bokmal (nb_NO), not Nynorsk (nn_NO) 481*cdf0e10cSrcweir eLang = LANGUAGE_DONTKNOW; // don't offer "Unknown" language 482*cdf0e10cSrcweir break; 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir if ( eLang != LANGUAGE_DONTKNOW ) 485*cdf0e10cSrcweir { 486*cdf0e10cSrcweir rtl::OUString aLanguage, aCountry; 487*cdf0e10cSrcweir MsLangId::convertLanguageToIsoNames( eLang, aLanguage, aCountry ); 488*cdf0e10cSrcweir if ( xLoc[i].Language != aLanguage || 489*cdf0e10cSrcweir xLoc[i].Country != aCountry ) 490*cdf0e10cSrcweir { 491*cdf0e10cSrcweir // In checks, exclude known problems because no MS-LCID defined 492*cdf0e10cSrcweir // and default for Language found. 493*cdf0e10cSrcweir if ( areChecksEnabled() 494*cdf0e10cSrcweir && !aDebugLocale.EqualsAscii( "ar_SD" ) // Sudan/ar 495*cdf0e10cSrcweir && !aDebugLocale.EqualsAscii( "en_CB" ) // Carribean is not a country 496*cdf0e10cSrcweir // && !aDebugLocale.EqualsAscii( "en_BG" ) // ?!? Bulgaria/en 497*cdf0e10cSrcweir // && !aDebugLocale.EqualsAscii( "es_BR" ) // ?!? Brazil/es 498*cdf0e10cSrcweir ) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 501*cdf0e10cSrcweir "ConvertIsoNamesToLanguage/ConvertLanguageToIsoNames: ambiguous locale (MS-LCID?)\n")); 502*cdf0e10cSrcweir aMsg += aDebugLocale; 503*cdf0e10cSrcweir aMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " -> 0x" ) ); 504*cdf0e10cSrcweir aMsg += String::CreateFromInt32( eLang, 16 ); 505*cdf0e10cSrcweir aMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " -> " ) ); 506*cdf0e10cSrcweir aMsg += String( aLanguage); 507*cdf0e10cSrcweir if ( aCountry.getLength() ) 508*cdf0e10cSrcweir { 509*cdf0e10cSrcweir aMsg += '_'; 510*cdf0e10cSrcweir aMsg += String( aCountry); 511*cdf0e10cSrcweir } 512*cdf0e10cSrcweir outputCheckMessage( aMsg ); 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir eLang = LANGUAGE_DONTKNOW; 515*cdf0e10cSrcweir } 516*cdf0e10cSrcweir } 517*cdf0e10cSrcweir if ( eLang != LANGUAGE_DONTKNOW ) 518*cdf0e10cSrcweir xLang[ nLanguages++ ] = eLang; 519*cdf0e10cSrcweir } 520*cdf0e10cSrcweir if ( nLanguages < nCount ) 521*cdf0e10cSrcweir xLang.realloc( nLanguages ); 522*cdf0e10cSrcweir rInstalledLanguageTypes = xLang; 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir return rInstalledLanguageTypes; 525*cdf0e10cSrcweir } 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir const String& LocaleDataWrapper::getOneLocaleItem( sal_Int16 nItem ) const 528*cdf0e10cSrcweir { 529*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 530*cdf0e10cSrcweir if ( nItem >= LocaleItem::COUNT ) 531*cdf0e10cSrcweir { 532*cdf0e10cSrcweir DBG_ERRORFILE( "getOneLocaleItem: bounds" ); 533*cdf0e10cSrcweir return aLocaleItem[0]; 534*cdf0e10cSrcweir } 535*cdf0e10cSrcweir if ( aLocaleItem[nItem].Len() == 0 ) 536*cdf0e10cSrcweir { // no cached content 537*cdf0e10cSrcweir aGuard.changeReadToWrite(); 538*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getOneLocaleItemImpl( nItem ); 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir return aLocaleItem[nItem]; 541*cdf0e10cSrcweir } 542*cdf0e10cSrcweir 543*cdf0e10cSrcweir 544*cdf0e10cSrcweir void LocaleDataWrapper::getOneLocaleItemImpl( sal_Int16 nItem ) 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir if ( !bLocaleDataItemValid ) 547*cdf0e10cSrcweir { 548*cdf0e10cSrcweir aLocaleDataItem = getLocaleItem(); 549*cdf0e10cSrcweir bLocaleDataItemValid = sal_True; 550*cdf0e10cSrcweir } 551*cdf0e10cSrcweir switch ( nItem ) 552*cdf0e10cSrcweir { 553*cdf0e10cSrcweir case LocaleItem::DATE_SEPARATOR : 554*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.dateSeparator; 555*cdf0e10cSrcweir break; 556*cdf0e10cSrcweir case LocaleItem::THOUSAND_SEPARATOR : 557*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.thousandSeparator; 558*cdf0e10cSrcweir break; 559*cdf0e10cSrcweir case LocaleItem::DECIMAL_SEPARATOR : 560*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.decimalSeparator; 561*cdf0e10cSrcweir break; 562*cdf0e10cSrcweir case LocaleItem::TIME_SEPARATOR : 563*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.timeSeparator; 564*cdf0e10cSrcweir break; 565*cdf0e10cSrcweir case LocaleItem::TIME_100SEC_SEPARATOR : 566*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.time100SecSeparator; 567*cdf0e10cSrcweir break; 568*cdf0e10cSrcweir case LocaleItem::LIST_SEPARATOR : 569*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.listSeparator; 570*cdf0e10cSrcweir break; 571*cdf0e10cSrcweir case LocaleItem::SINGLE_QUOTATION_START : 572*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.quotationStart; 573*cdf0e10cSrcweir break; 574*cdf0e10cSrcweir case LocaleItem::SINGLE_QUOTATION_END : 575*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.quotationEnd; 576*cdf0e10cSrcweir break; 577*cdf0e10cSrcweir case LocaleItem::DOUBLE_QUOTATION_START : 578*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.doubleQuotationStart; 579*cdf0e10cSrcweir break; 580*cdf0e10cSrcweir case LocaleItem::DOUBLE_QUOTATION_END : 581*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.doubleQuotationEnd; 582*cdf0e10cSrcweir break; 583*cdf0e10cSrcweir case LocaleItem::MEASUREMENT_SYSTEM : 584*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.measurementSystem; 585*cdf0e10cSrcweir break; 586*cdf0e10cSrcweir case LocaleItem::TIME_AM : 587*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.timeAM; 588*cdf0e10cSrcweir break; 589*cdf0e10cSrcweir case LocaleItem::TIME_PM : 590*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.timePM; 591*cdf0e10cSrcweir break; 592*cdf0e10cSrcweir case LocaleItem::LONG_DATE_DAY_OF_WEEK_SEPARATOR : 593*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.LongDateDayOfWeekSeparator; 594*cdf0e10cSrcweir break; 595*cdf0e10cSrcweir case LocaleItem::LONG_DATE_DAY_SEPARATOR : 596*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.LongDateDaySeparator; 597*cdf0e10cSrcweir break; 598*cdf0e10cSrcweir case LocaleItem::LONG_DATE_MONTH_SEPARATOR : 599*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.LongDateMonthSeparator; 600*cdf0e10cSrcweir break; 601*cdf0e10cSrcweir case LocaleItem::LONG_DATE_YEAR_SEPARATOR : 602*cdf0e10cSrcweir aLocaleItem[nItem] = aLocaleDataItem.LongDateYearSeparator; 603*cdf0e10cSrcweir break; 604*cdf0e10cSrcweir default: 605*cdf0e10cSrcweir DBG_ERRORFILE( "getOneLocaleItemImpl: which one?" ); 606*cdf0e10cSrcweir } 607*cdf0e10cSrcweir } 608*cdf0e10cSrcweir 609*cdf0e10cSrcweir 610*cdf0e10cSrcweir void LocaleDataWrapper::getOneReservedWordImpl( sal_Int16 nWord ) 611*cdf0e10cSrcweir { 612*cdf0e10cSrcweir if ( !bReservedWordValid ) 613*cdf0e10cSrcweir { 614*cdf0e10cSrcweir aReservedWordSeq = getReservedWord(); 615*cdf0e10cSrcweir bReservedWordValid = sal_True; 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir DBG_ASSERT( nWord < aReservedWordSeq.getLength(), "getOneReservedWordImpl: which one?" ); 618*cdf0e10cSrcweir if ( nWord < aReservedWordSeq.getLength() ) 619*cdf0e10cSrcweir aReservedWord[nWord] = aReservedWordSeq[nWord]; 620*cdf0e10cSrcweir } 621*cdf0e10cSrcweir 622*cdf0e10cSrcweir 623*cdf0e10cSrcweir const String& LocaleDataWrapper::getOneReservedWord( sal_Int16 nWord ) const 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 626*cdf0e10cSrcweir if ( nWord < 0 || nWord >= reservedWords::COUNT ) 627*cdf0e10cSrcweir { 628*cdf0e10cSrcweir DBG_ERRORFILE( "getOneReservedWord: bounds" ); 629*cdf0e10cSrcweir nWord = reservedWords::FALSE_WORD; 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir if ( aReservedWord[nWord].Len() == 0 ) 632*cdf0e10cSrcweir { // no cached content 633*cdf0e10cSrcweir aGuard.changeReadToWrite(); 634*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getOneReservedWordImpl( nWord ); 635*cdf0e10cSrcweir } 636*cdf0e10cSrcweir return aReservedWord[nWord]; 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir 640*cdf0e10cSrcweir MeasurementSystem LocaleDataWrapper::mapMeasurementStringToEnum( const String& rMS ) const 641*cdf0e10cSrcweir { 642*cdf0e10cSrcweir //! TODO: could be cached too 643*cdf0e10cSrcweir if ( rMS.EqualsIgnoreCaseAscii( "metric" ) ) 644*cdf0e10cSrcweir return MEASURE_METRIC; 645*cdf0e10cSrcweir //! TODO: other measurement systems? => extend enum MeasurementSystem 646*cdf0e10cSrcweir return MEASURE_US; 647*cdf0e10cSrcweir } 648*cdf0e10cSrcweir 649*cdf0e10cSrcweir 650*cdf0e10cSrcweir void LocaleDataWrapper::getDefaultCalendarImpl() 651*cdf0e10cSrcweir { 652*cdf0e10cSrcweir if (!xDefaultCalendar) 653*cdf0e10cSrcweir { 654*cdf0e10cSrcweir Sequence< Calendar > xCals = getAllCalendars(); 655*cdf0e10cSrcweir sal_Int32 nCount = xCals.getLength(); 656*cdf0e10cSrcweir sal_Int32 nDef = 0; 657*cdf0e10cSrcweir if (nCount > 1) 658*cdf0e10cSrcweir { 659*cdf0e10cSrcweir const Calendar* pArr = xCals.getArray(); 660*cdf0e10cSrcweir for (sal_Int32 i=0; i<nCount; ++i) 661*cdf0e10cSrcweir { 662*cdf0e10cSrcweir if (pArr[i].Default) 663*cdf0e10cSrcweir { 664*cdf0e10cSrcweir nDef = i; 665*cdf0e10cSrcweir break; 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir } 669*cdf0e10cSrcweir xDefaultCalendar.reset( new Calendar( xCals[nDef])); 670*cdf0e10cSrcweir } 671*cdf0e10cSrcweir } 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir 674*cdf0e10cSrcweir const ::boost::shared_ptr< ::com::sun::star::i18n::Calendar > LocaleDataWrapper::getDefaultCalendar() const 675*cdf0e10cSrcweir { 676*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 677*cdf0e10cSrcweir if (!xDefaultCalendar) 678*cdf0e10cSrcweir { // no cached content 679*cdf0e10cSrcweir aGuard.changeReadToWrite(); 680*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getDefaultCalendarImpl(); 681*cdf0e10cSrcweir } 682*cdf0e10cSrcweir return xDefaultCalendar; 683*cdf0e10cSrcweir } 684*cdf0e10cSrcweir 685*cdf0e10cSrcweir 686*cdf0e10cSrcweir const ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem > LocaleDataWrapper::getDefaultCalendarDays() const 687*cdf0e10cSrcweir { 688*cdf0e10cSrcweir return getDefaultCalendar()->Days; 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir 692*cdf0e10cSrcweir const ::com::sun::star::uno::Sequence< ::com::sun::star::i18n::CalendarItem > LocaleDataWrapper::getDefaultCalendarMonths() const 693*cdf0e10cSrcweir { 694*cdf0e10cSrcweir return getDefaultCalendar()->Months; 695*cdf0e10cSrcweir } 696*cdf0e10cSrcweir 697*cdf0e10cSrcweir 698*cdf0e10cSrcweir // --- currencies ----------------------------------------------------- 699*cdf0e10cSrcweir 700*cdf0e10cSrcweir const String& LocaleDataWrapper::getCurrSymbol() const 701*cdf0e10cSrcweir { 702*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 703*cdf0e10cSrcweir if ( !aCurrSymbol.Len() ) 704*cdf0e10cSrcweir { 705*cdf0e10cSrcweir aGuard.changeReadToWrite(); 706*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getCurrSymbolsImpl(); 707*cdf0e10cSrcweir } 708*cdf0e10cSrcweir return aCurrSymbol; 709*cdf0e10cSrcweir } 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir 712*cdf0e10cSrcweir const String& LocaleDataWrapper::getCurrBankSymbol() const 713*cdf0e10cSrcweir { 714*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 715*cdf0e10cSrcweir if ( !aCurrBankSymbol.Len() ) 716*cdf0e10cSrcweir { 717*cdf0e10cSrcweir aGuard.changeReadToWrite(); 718*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getCurrSymbolsImpl(); 719*cdf0e10cSrcweir } 720*cdf0e10cSrcweir return aCurrBankSymbol; 721*cdf0e10cSrcweir } 722*cdf0e10cSrcweir 723*cdf0e10cSrcweir 724*cdf0e10cSrcweir sal_uInt16 LocaleDataWrapper::getCurrPositiveFormat() const 725*cdf0e10cSrcweir { 726*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 727*cdf0e10cSrcweir if ( nCurrPositiveFormat == nCurrFormatInvalid ) 728*cdf0e10cSrcweir { 729*cdf0e10cSrcweir aGuard.changeReadToWrite(); 730*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getCurrFormatsImpl(); 731*cdf0e10cSrcweir } 732*cdf0e10cSrcweir return nCurrPositiveFormat; 733*cdf0e10cSrcweir } 734*cdf0e10cSrcweir 735*cdf0e10cSrcweir 736*cdf0e10cSrcweir sal_uInt16 LocaleDataWrapper::getCurrNegativeFormat() const 737*cdf0e10cSrcweir { 738*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 739*cdf0e10cSrcweir if ( nCurrNegativeFormat == nCurrFormatInvalid ) 740*cdf0e10cSrcweir { 741*cdf0e10cSrcweir aGuard.changeReadToWrite(); 742*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getCurrFormatsImpl(); 743*cdf0e10cSrcweir } 744*cdf0e10cSrcweir return nCurrNegativeFormat; 745*cdf0e10cSrcweir } 746*cdf0e10cSrcweir 747*cdf0e10cSrcweir 748*cdf0e10cSrcweir sal_uInt16 LocaleDataWrapper::getCurrDigits() const 749*cdf0e10cSrcweir { 750*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 751*cdf0e10cSrcweir if ( nCurrDigits == nCurrFormatInvalid ) 752*cdf0e10cSrcweir { 753*cdf0e10cSrcweir aGuard.changeReadToWrite(); 754*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getCurrSymbolsImpl(); 755*cdf0e10cSrcweir } 756*cdf0e10cSrcweir return nCurrDigits; 757*cdf0e10cSrcweir } 758*cdf0e10cSrcweir 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir void LocaleDataWrapper::getCurrSymbolsImpl() 761*cdf0e10cSrcweir { 762*cdf0e10cSrcweir Sequence< Currency2 > aCurrSeq = getAllCurrencies(); 763*cdf0e10cSrcweir sal_Int32 nCnt = aCurrSeq.getLength(); 764*cdf0e10cSrcweir Currency2 const * const pCurrArr = aCurrSeq.getArray(); 765*cdf0e10cSrcweir sal_Int32 nElem; 766*cdf0e10cSrcweir for ( nElem = 0; nElem < nCnt; nElem++ ) 767*cdf0e10cSrcweir { 768*cdf0e10cSrcweir if ( pCurrArr[nElem].Default ) 769*cdf0e10cSrcweir break; 770*cdf0e10cSrcweir } 771*cdf0e10cSrcweir if ( nElem >= nCnt ) 772*cdf0e10cSrcweir { 773*cdf0e10cSrcweir if (areChecksEnabled()) 774*cdf0e10cSrcweir { 775*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 776*cdf0e10cSrcweir "LocaleDataWrapper::getCurrSymbolsImpl: no default currency")); 777*cdf0e10cSrcweir outputCheckMessage( appendLocaleInfo( aMsg ) ); 778*cdf0e10cSrcweir } 779*cdf0e10cSrcweir nElem = 0; 780*cdf0e10cSrcweir if ( nElem >= nCnt ) 781*cdf0e10cSrcweir { 782*cdf0e10cSrcweir if (areChecksEnabled()) 783*cdf0e10cSrcweir outputCheckMessage( String( RTL_CONSTASCII_USTRINGPARAM( 784*cdf0e10cSrcweir "LocaleDataWrapper::getCurrSymbolsImpl: no currency at all, using ShellsAndPebbles"))); 785*cdf0e10cSrcweir aCurrSymbol.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "ShellsAndPebbles" ) ); 786*cdf0e10cSrcweir aCurrBankSymbol = aCurrSymbol; 787*cdf0e10cSrcweir nCurrPositiveFormat = nCurrNegativeFormat = nCurrFormatDefault; 788*cdf0e10cSrcweir nCurrDigits = 2; 789*cdf0e10cSrcweir return ; 790*cdf0e10cSrcweir } 791*cdf0e10cSrcweir } 792*cdf0e10cSrcweir aCurrSymbol = pCurrArr[nElem].Symbol; 793*cdf0e10cSrcweir aCurrBankSymbol = pCurrArr[nElem].BankSymbol; 794*cdf0e10cSrcweir nCurrDigits = pCurrArr[nElem].DecimalPlaces; 795*cdf0e10cSrcweir } 796*cdf0e10cSrcweir 797*cdf0e10cSrcweir 798*cdf0e10cSrcweir void LocaleDataWrapper::scanCurrFormatImpl( const String& rCode, 799*cdf0e10cSrcweir xub_StrLen nStart, xub_StrLen& nSign, xub_StrLen& nPar, 800*cdf0e10cSrcweir xub_StrLen& nNum, xub_StrLen& nBlank, xub_StrLen& nSym ) 801*cdf0e10cSrcweir { 802*cdf0e10cSrcweir nSign = nPar = nNum = nBlank = nSym = STRING_NOTFOUND; 803*cdf0e10cSrcweir const sal_Unicode* const pStr = rCode.GetBuffer(); 804*cdf0e10cSrcweir const sal_Unicode* const pStop = pStr + rCode.Len(); 805*cdf0e10cSrcweir const sal_Unicode* p = pStr + nStart; 806*cdf0e10cSrcweir int nInSection = 0; 807*cdf0e10cSrcweir sal_Bool bQuote = sal_False; 808*cdf0e10cSrcweir while ( p < pStop ) 809*cdf0e10cSrcweir { 810*cdf0e10cSrcweir if ( bQuote ) 811*cdf0e10cSrcweir { 812*cdf0e10cSrcweir if ( *p == '"' && *(p-1) != '\\' ) 813*cdf0e10cSrcweir bQuote = sal_False; 814*cdf0e10cSrcweir } 815*cdf0e10cSrcweir else 816*cdf0e10cSrcweir { 817*cdf0e10cSrcweir switch ( *p ) 818*cdf0e10cSrcweir { 819*cdf0e10cSrcweir case '"' : 820*cdf0e10cSrcweir if ( pStr == p || *(p-1) != '\\' ) 821*cdf0e10cSrcweir bQuote = sal_True; 822*cdf0e10cSrcweir break; 823*cdf0e10cSrcweir case '-' : 824*cdf0e10cSrcweir if ( !nInSection && nSign == STRING_NOTFOUND ) 825*cdf0e10cSrcweir nSign = (xub_StrLen)(p - pStr); 826*cdf0e10cSrcweir break; 827*cdf0e10cSrcweir case '(' : 828*cdf0e10cSrcweir if ( !nInSection && nPar == STRING_NOTFOUND ) 829*cdf0e10cSrcweir nPar = (xub_StrLen)(p - pStr); 830*cdf0e10cSrcweir break; 831*cdf0e10cSrcweir case '0' : 832*cdf0e10cSrcweir case '#' : 833*cdf0e10cSrcweir if ( !nInSection && nNum == STRING_NOTFOUND ) 834*cdf0e10cSrcweir nNum = (xub_StrLen)(p - pStr); 835*cdf0e10cSrcweir break; 836*cdf0e10cSrcweir case '[' : 837*cdf0e10cSrcweir nInSection++; 838*cdf0e10cSrcweir break; 839*cdf0e10cSrcweir case ']' : 840*cdf0e10cSrcweir if ( nInSection ) 841*cdf0e10cSrcweir { 842*cdf0e10cSrcweir nInSection--; 843*cdf0e10cSrcweir if ( !nInSection && nBlank == STRING_NOTFOUND 844*cdf0e10cSrcweir && nSym != STRING_NOTFOUND && p < pStop-1 && *(p+1) == ' ' ) 845*cdf0e10cSrcweir nBlank = (xub_StrLen)(p - pStr + 1); 846*cdf0e10cSrcweir } 847*cdf0e10cSrcweir break; 848*cdf0e10cSrcweir case '$' : 849*cdf0e10cSrcweir if ( nSym == STRING_NOTFOUND && nInSection && *(p-1) == '[' ) 850*cdf0e10cSrcweir { 851*cdf0e10cSrcweir nSym = (xub_StrLen)(p - pStr + 1); 852*cdf0e10cSrcweir if ( nNum != STRING_NOTFOUND && *(p-2) == ' ' ) 853*cdf0e10cSrcweir nBlank = (xub_StrLen)(p - pStr - 2); 854*cdf0e10cSrcweir } 855*cdf0e10cSrcweir break; 856*cdf0e10cSrcweir case ';' : 857*cdf0e10cSrcweir if ( !nInSection ) 858*cdf0e10cSrcweir p = pStop; 859*cdf0e10cSrcweir break; 860*cdf0e10cSrcweir default: 861*cdf0e10cSrcweir if ( !nInSection && nSym == STRING_NOTFOUND && rCode.Equals( aCurrSymbol, (xub_StrLen)(p-pStr), aCurrSymbol.Len() ) ) 862*cdf0e10cSrcweir { // currency symbol not surrounded by [$...] 863*cdf0e10cSrcweir nSym = (xub_StrLen)(p - pStr); 864*cdf0e10cSrcweir if ( nBlank == STRING_NOTFOUND && pStr < p && *(p-1) == ' ' ) 865*cdf0e10cSrcweir nBlank = (xub_StrLen)(p - pStr - 1); 866*cdf0e10cSrcweir p += aCurrSymbol.Len() - 1; 867*cdf0e10cSrcweir if ( nBlank == STRING_NOTFOUND && p < pStop-2 && *(p+2) == ' ' ) 868*cdf0e10cSrcweir nBlank = (xub_StrLen)(p - pStr + 2); 869*cdf0e10cSrcweir } 870*cdf0e10cSrcweir } 871*cdf0e10cSrcweir } 872*cdf0e10cSrcweir p++; 873*cdf0e10cSrcweir } 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir 876*cdf0e10cSrcweir 877*cdf0e10cSrcweir void LocaleDataWrapper::getCurrFormatsImpl() 878*cdf0e10cSrcweir { 879*cdf0e10cSrcweir NumberFormatCodeWrapper aNumberFormatCode( xSMgr, getLocale() ); 880*cdf0e10cSrcweir uno::Sequence< NumberFormatCode > aFormatSeq 881*cdf0e10cSrcweir = aNumberFormatCode.getAllFormatCode( KNumberFormatUsage::CURRENCY ); 882*cdf0e10cSrcweir sal_Int32 nCnt = aFormatSeq.getLength(); 883*cdf0e10cSrcweir if ( !nCnt ) 884*cdf0e10cSrcweir { // bad luck 885*cdf0e10cSrcweir if (areChecksEnabled()) 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 888*cdf0e10cSrcweir "LocaleDataWrapper::getCurrFormatsImpl: no currency formats")); 889*cdf0e10cSrcweir outputCheckMessage( appendLocaleInfo( aMsg ) ); 890*cdf0e10cSrcweir } 891*cdf0e10cSrcweir nCurrPositiveFormat = nCurrNegativeFormat = nCurrFormatDefault; 892*cdf0e10cSrcweir return ; 893*cdf0e10cSrcweir } 894*cdf0e10cSrcweir // find a negative code (medium preferred) and a default (medium preferred) (not necessarily the same) 895*cdf0e10cSrcweir NumberFormatCode const * const pFormatArr = aFormatSeq.getArray(); 896*cdf0e10cSrcweir sal_Int32 nElem, nDef, nNeg, nMedium; 897*cdf0e10cSrcweir nDef = nNeg = nMedium = -1; 898*cdf0e10cSrcweir for ( nElem = 0; nElem < nCnt; nElem++ ) 899*cdf0e10cSrcweir { 900*cdf0e10cSrcweir if ( pFormatArr[nElem].Type == KNumberFormatType::MEDIUM ) 901*cdf0e10cSrcweir { 902*cdf0e10cSrcweir if ( pFormatArr[nElem].Default ) 903*cdf0e10cSrcweir { 904*cdf0e10cSrcweir nDef = nElem; 905*cdf0e10cSrcweir nMedium = nElem; 906*cdf0e10cSrcweir if ( pFormatArr[nElem].Code.indexOf( ';' ) >= 0 ) 907*cdf0e10cSrcweir nNeg = nElem; 908*cdf0e10cSrcweir } 909*cdf0e10cSrcweir else 910*cdf0e10cSrcweir { 911*cdf0e10cSrcweir if ( (nNeg == -1 || nMedium == -1) && pFormatArr[nElem].Code.indexOf( ';' ) >= 0 ) 912*cdf0e10cSrcweir nNeg = nElem; 913*cdf0e10cSrcweir if ( nMedium == -1 ) 914*cdf0e10cSrcweir nMedium = nElem; 915*cdf0e10cSrcweir } 916*cdf0e10cSrcweir } 917*cdf0e10cSrcweir else 918*cdf0e10cSrcweir { 919*cdf0e10cSrcweir if ( nDef == -1 && pFormatArr[nElem].Default ) 920*cdf0e10cSrcweir nDef = nElem; 921*cdf0e10cSrcweir if ( nNeg == -1 && pFormatArr[nElem].Code.indexOf( ';' ) >= 0 ) 922*cdf0e10cSrcweir nNeg = nElem; 923*cdf0e10cSrcweir } 924*cdf0e10cSrcweir } 925*cdf0e10cSrcweir 926*cdf0e10cSrcweir // make sure it's loaded 927*cdf0e10cSrcweir getCurrSymbol(); 928*cdf0e10cSrcweir 929*cdf0e10cSrcweir xub_StrLen nSign, nPar, nNum, nBlank, nSym; 930*cdf0e10cSrcweir 931*cdf0e10cSrcweir // positive format 932*cdf0e10cSrcweir nElem = (nDef >= 0 ? nDef : (nNeg >= 0 ? nNeg : 0)); 933*cdf0e10cSrcweir scanCurrFormatImpl( pFormatArr[nElem].Code, 0, nSign, nPar, nNum, nBlank, nSym ); 934*cdf0e10cSrcweir if (areChecksEnabled() && (nNum == STRING_NOTFOUND || nSym == STRING_NOTFOUND)) 935*cdf0e10cSrcweir { 936*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 937*cdf0e10cSrcweir "LocaleDataWrapper::getCurrFormatsImpl: CurrPositiveFormat?")); 938*cdf0e10cSrcweir outputCheckMessage( appendLocaleInfo( aMsg ) ); 939*cdf0e10cSrcweir } 940*cdf0e10cSrcweir if ( nBlank == STRING_NOTFOUND ) 941*cdf0e10cSrcweir { 942*cdf0e10cSrcweir if ( nSym < nNum ) 943*cdf0e10cSrcweir nCurrPositiveFormat = 0; // $1 944*cdf0e10cSrcweir else 945*cdf0e10cSrcweir nCurrPositiveFormat = 1; // 1$ 946*cdf0e10cSrcweir } 947*cdf0e10cSrcweir else 948*cdf0e10cSrcweir { 949*cdf0e10cSrcweir if ( nSym < nNum ) 950*cdf0e10cSrcweir nCurrPositiveFormat = 2; // $ 1 951*cdf0e10cSrcweir else 952*cdf0e10cSrcweir nCurrPositiveFormat = 3; // 1 $ 953*cdf0e10cSrcweir } 954*cdf0e10cSrcweir 955*cdf0e10cSrcweir // negative format 956*cdf0e10cSrcweir if ( nNeg < 0 ) 957*cdf0e10cSrcweir nCurrNegativeFormat = nCurrFormatDefault; 958*cdf0e10cSrcweir else 959*cdf0e10cSrcweir { 960*cdf0e10cSrcweir const ::rtl::OUString& rCode = pFormatArr[nNeg].Code; 961*cdf0e10cSrcweir xub_StrLen nDelim = (xub_StrLen)rCode.indexOf( ';' ); 962*cdf0e10cSrcweir scanCurrFormatImpl( rCode, nDelim+1, nSign, nPar, nNum, nBlank, nSym ); 963*cdf0e10cSrcweir if (areChecksEnabled() && (nNum == STRING_NOTFOUND || 964*cdf0e10cSrcweir nSym == STRING_NOTFOUND || (nPar == STRING_NOTFOUND && 965*cdf0e10cSrcweir nSign == STRING_NOTFOUND))) 966*cdf0e10cSrcweir { 967*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 968*cdf0e10cSrcweir "LocaleDataWrapper::getCurrFormatsImpl: CurrNegativeFormat?")); 969*cdf0e10cSrcweir outputCheckMessage( appendLocaleInfo( aMsg ) ); 970*cdf0e10cSrcweir } 971*cdf0e10cSrcweir if ( nBlank == STRING_NOTFOUND ) 972*cdf0e10cSrcweir { 973*cdf0e10cSrcweir if ( nSym < nNum ) 974*cdf0e10cSrcweir { 975*cdf0e10cSrcweir if ( nPar < nSym ) 976*cdf0e10cSrcweir nCurrNegativeFormat = 0; // ($1) 977*cdf0e10cSrcweir else if ( nSign < nSym ) 978*cdf0e10cSrcweir nCurrNegativeFormat = 1; // -$1 979*cdf0e10cSrcweir else if ( nNum < nSign ) 980*cdf0e10cSrcweir nCurrNegativeFormat = 3; // $1- 981*cdf0e10cSrcweir else 982*cdf0e10cSrcweir nCurrNegativeFormat = 2; // $-1 983*cdf0e10cSrcweir } 984*cdf0e10cSrcweir else 985*cdf0e10cSrcweir { 986*cdf0e10cSrcweir if ( nPar < nNum ) 987*cdf0e10cSrcweir nCurrNegativeFormat = 4; // (1$) 988*cdf0e10cSrcweir else if ( nSign < nNum ) 989*cdf0e10cSrcweir nCurrNegativeFormat = 5; // -1$ 990*cdf0e10cSrcweir else if ( nSym < nSign ) 991*cdf0e10cSrcweir nCurrNegativeFormat = 7; // 1$- 992*cdf0e10cSrcweir else 993*cdf0e10cSrcweir nCurrNegativeFormat = 6; // 1-$ 994*cdf0e10cSrcweir } 995*cdf0e10cSrcweir } 996*cdf0e10cSrcweir else 997*cdf0e10cSrcweir { 998*cdf0e10cSrcweir if ( nSym < nNum ) 999*cdf0e10cSrcweir { 1000*cdf0e10cSrcweir if ( nPar < nSym ) 1001*cdf0e10cSrcweir nCurrNegativeFormat = 14; // ($ 1) 1002*cdf0e10cSrcweir else if ( nSign < nSym ) 1003*cdf0e10cSrcweir nCurrNegativeFormat = 9; // -$ 1 1004*cdf0e10cSrcweir else if ( nNum < nSign ) 1005*cdf0e10cSrcweir nCurrNegativeFormat = 12; // $ 1- 1006*cdf0e10cSrcweir else 1007*cdf0e10cSrcweir nCurrNegativeFormat = 11; // $ -1 1008*cdf0e10cSrcweir } 1009*cdf0e10cSrcweir else 1010*cdf0e10cSrcweir { 1011*cdf0e10cSrcweir if ( nPar < nNum ) 1012*cdf0e10cSrcweir nCurrNegativeFormat = 15; // (1 $) 1013*cdf0e10cSrcweir else if ( nSign < nNum ) 1014*cdf0e10cSrcweir nCurrNegativeFormat = 8; // -1 $ 1015*cdf0e10cSrcweir else if ( nSym < nSign ) 1016*cdf0e10cSrcweir nCurrNegativeFormat = 10; // 1 $- 1017*cdf0e10cSrcweir else 1018*cdf0e10cSrcweir nCurrNegativeFormat = 13; // 1- $ 1019*cdf0e10cSrcweir } 1020*cdf0e10cSrcweir } 1021*cdf0e10cSrcweir } 1022*cdf0e10cSrcweir } 1023*cdf0e10cSrcweir 1024*cdf0e10cSrcweir 1025*cdf0e10cSrcweir // --- date ----------------------------------------------------------- 1026*cdf0e10cSrcweir 1027*cdf0e10cSrcweir DateFormat LocaleDataWrapper::getDateFormat() const 1028*cdf0e10cSrcweir { 1029*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 1030*cdf0e10cSrcweir if ( nDateFormat == nDateFormatInvalid ) 1031*cdf0e10cSrcweir { 1032*cdf0e10cSrcweir aGuard.changeReadToWrite(); 1033*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getDateFormatsImpl(); 1034*cdf0e10cSrcweir } 1035*cdf0e10cSrcweir return (DateFormat) nDateFormat; 1036*cdf0e10cSrcweir } 1037*cdf0e10cSrcweir 1038*cdf0e10cSrcweir 1039*cdf0e10cSrcweir DateFormat LocaleDataWrapper::getLongDateFormat() const 1040*cdf0e10cSrcweir { 1041*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 1042*cdf0e10cSrcweir if ( nLongDateFormat == nDateFormatInvalid ) 1043*cdf0e10cSrcweir { 1044*cdf0e10cSrcweir aGuard.changeReadToWrite(); 1045*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getDateFormatsImpl(); 1046*cdf0e10cSrcweir } 1047*cdf0e10cSrcweir return (DateFormat) nLongDateFormat; 1048*cdf0e10cSrcweir } 1049*cdf0e10cSrcweir 1050*cdf0e10cSrcweir 1051*cdf0e10cSrcweir DateFormat LocaleDataWrapper::scanDateFormatImpl( const String& rCode ) 1052*cdf0e10cSrcweir { 1053*cdf0e10cSrcweir // Only some european versions were translated, the ones with different 1054*cdf0e10cSrcweir // keyword combinations are: 1055*cdf0e10cSrcweir // English DMY, German TMJ, Spanish DMA, French JMA, Italian GMA, 1056*cdf0e10cSrcweir // Dutch DMJ, Finnish PKV 1057*cdf0e10cSrcweir 1058*cdf0e10cSrcweir // default is English keywords for every other language 1059*cdf0e10cSrcweir xub_StrLen nDay = rCode.Search( 'D' ); 1060*cdf0e10cSrcweir xub_StrLen nMonth = rCode.Search( 'M' ); 1061*cdf0e10cSrcweir xub_StrLen nYear = rCode.Search( 'Y' ); 1062*cdf0e10cSrcweir if ( nDay == STRING_NOTFOUND || nMonth == STRING_NOTFOUND || nYear == STRING_NOTFOUND ) 1063*cdf0e10cSrcweir { // This algorithm assumes that all three parts (DMY) are present 1064*cdf0e10cSrcweir if ( nMonth == STRING_NOTFOUND ) 1065*cdf0e10cSrcweir { // only Finnish has something else than 'M' for month 1066*cdf0e10cSrcweir nMonth = rCode.Search( 'K' ); 1067*cdf0e10cSrcweir if ( nMonth != STRING_NOTFOUND ) 1068*cdf0e10cSrcweir { 1069*cdf0e10cSrcweir nDay = rCode.Search( 'P' ); 1070*cdf0e10cSrcweir nYear = rCode.Search( 'V' ); 1071*cdf0e10cSrcweir } 1072*cdf0e10cSrcweir } 1073*cdf0e10cSrcweir else if ( nDay == STRING_NOTFOUND ) 1074*cdf0e10cSrcweir { // We have a month 'M' if we reach this branch. 1075*cdf0e10cSrcweir // Possible languages containing 'M' but no 'D': 1076*cdf0e10cSrcweir // German, French, Italian 1077*cdf0e10cSrcweir nDay = rCode.Search( 'T' ); // German 1078*cdf0e10cSrcweir if ( nDay != STRING_NOTFOUND ) 1079*cdf0e10cSrcweir nYear = rCode.Search( 'J' ); 1080*cdf0e10cSrcweir else 1081*cdf0e10cSrcweir { 1082*cdf0e10cSrcweir nYear = rCode.Search( 'A' ); // French, Italian 1083*cdf0e10cSrcweir if ( nYear != STRING_NOTFOUND ) 1084*cdf0e10cSrcweir { 1085*cdf0e10cSrcweir nDay = rCode.Search( 'J' ); // French 1086*cdf0e10cSrcweir if ( nDay == STRING_NOTFOUND ) 1087*cdf0e10cSrcweir nDay = rCode.Search( 'G' ); // Italian 1088*cdf0e10cSrcweir } 1089*cdf0e10cSrcweir } 1090*cdf0e10cSrcweir } 1091*cdf0e10cSrcweir else 1092*cdf0e10cSrcweir { // We have a month 'M' and a day 'D'. 1093*cdf0e10cSrcweir // Possible languages containing 'D' and 'M' but not 'Y': 1094*cdf0e10cSrcweir // Spanish, Dutch 1095*cdf0e10cSrcweir nYear = rCode.Search( 'A' ); // Spanish 1096*cdf0e10cSrcweir if ( nYear == STRING_NOTFOUND ) 1097*cdf0e10cSrcweir nYear = rCode.Search( 'J' ); // Dutch 1098*cdf0e10cSrcweir } 1099*cdf0e10cSrcweir if ( nDay == STRING_NOTFOUND || nMonth == STRING_NOTFOUND || nYear == STRING_NOTFOUND ) 1100*cdf0e10cSrcweir { 1101*cdf0e10cSrcweir if (areChecksEnabled()) 1102*cdf0e10cSrcweir { 1103*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 1104*cdf0e10cSrcweir "LocaleDataWrapper::scanDateFormat: not all DMY present")); 1105*cdf0e10cSrcweir outputCheckMessage( appendLocaleInfo( aMsg ) ); 1106*cdf0e10cSrcweir } 1107*cdf0e10cSrcweir if ( nDay == STRING_NOTFOUND ) 1108*cdf0e10cSrcweir nDay = rCode.Len(); 1109*cdf0e10cSrcweir if ( nMonth == STRING_NOTFOUND ) 1110*cdf0e10cSrcweir nMonth = rCode.Len(); 1111*cdf0e10cSrcweir if ( nYear == STRING_NOTFOUND ) 1112*cdf0e10cSrcweir nYear = rCode.Len(); 1113*cdf0e10cSrcweir } 1114*cdf0e10cSrcweir } 1115*cdf0e10cSrcweir // compare with <= because each position may equal rCode.Len() 1116*cdf0e10cSrcweir if ( nDay <= nMonth && nMonth <= nYear ) 1117*cdf0e10cSrcweir return DMY; // also if every position equals rCode.Len() 1118*cdf0e10cSrcweir else if ( nMonth <= nDay && nDay <= nYear ) 1119*cdf0e10cSrcweir return MDY; 1120*cdf0e10cSrcweir else if ( nYear <= nMonth && nMonth <= nDay ) 1121*cdf0e10cSrcweir return YMD; 1122*cdf0e10cSrcweir else 1123*cdf0e10cSrcweir { 1124*cdf0e10cSrcweir if (areChecksEnabled()) 1125*cdf0e10cSrcweir { 1126*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 1127*cdf0e10cSrcweir "LocaleDataWrapper::scanDateFormat: no magic applyable")); 1128*cdf0e10cSrcweir outputCheckMessage( appendLocaleInfo( aMsg ) ); 1129*cdf0e10cSrcweir } 1130*cdf0e10cSrcweir return DMY; 1131*cdf0e10cSrcweir } 1132*cdf0e10cSrcweir } 1133*cdf0e10cSrcweir 1134*cdf0e10cSrcweir 1135*cdf0e10cSrcweir void LocaleDataWrapper::getDateFormatsImpl() 1136*cdf0e10cSrcweir { 1137*cdf0e10cSrcweir NumberFormatCodeWrapper aNumberFormatCode( xSMgr, getLocale() ); 1138*cdf0e10cSrcweir uno::Sequence< NumberFormatCode > aFormatSeq 1139*cdf0e10cSrcweir = aNumberFormatCode.getAllFormatCode( KNumberFormatUsage::DATE ); 1140*cdf0e10cSrcweir sal_Int32 nCnt = aFormatSeq.getLength(); 1141*cdf0e10cSrcweir if ( !nCnt ) 1142*cdf0e10cSrcweir { // bad luck 1143*cdf0e10cSrcweir if (areChecksEnabled()) 1144*cdf0e10cSrcweir { 1145*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 1146*cdf0e10cSrcweir "LocaleDataWrapper::getDateFormatsImpl: no date formats")); 1147*cdf0e10cSrcweir outputCheckMessage( appendLocaleInfo( aMsg ) ); 1148*cdf0e10cSrcweir } 1149*cdf0e10cSrcweir nDateFormat = nLongDateFormat = DMY; 1150*cdf0e10cSrcweir return ; 1151*cdf0e10cSrcweir } 1152*cdf0e10cSrcweir // find the edit (21), a default (medium preferred), 1153*cdf0e10cSrcweir // a medium (default preferred), and a long (default preferred) 1154*cdf0e10cSrcweir NumberFormatCode const * const pFormatArr = aFormatSeq.getArray(); 1155*cdf0e10cSrcweir sal_Int32 nElem, nEdit, nDef, nMedium, nLong; 1156*cdf0e10cSrcweir nEdit = nDef = nMedium = nLong = -1; 1157*cdf0e10cSrcweir for ( nElem = 0; nElem < nCnt; nElem++ ) 1158*cdf0e10cSrcweir { 1159*cdf0e10cSrcweir if ( nEdit == -1 && pFormatArr[nElem].Index == NumberFormatIndex::DATE_SYS_DDMMYYYY ) 1160*cdf0e10cSrcweir nEdit = nElem; 1161*cdf0e10cSrcweir if ( nDef == -1 && pFormatArr[nElem].Default ) 1162*cdf0e10cSrcweir nDef = nElem; 1163*cdf0e10cSrcweir switch ( pFormatArr[nElem].Type ) 1164*cdf0e10cSrcweir { 1165*cdf0e10cSrcweir case KNumberFormatType::MEDIUM : 1166*cdf0e10cSrcweir { 1167*cdf0e10cSrcweir if ( pFormatArr[nElem].Default ) 1168*cdf0e10cSrcweir { 1169*cdf0e10cSrcweir nDef = nElem; 1170*cdf0e10cSrcweir nMedium = nElem; 1171*cdf0e10cSrcweir } 1172*cdf0e10cSrcweir else if ( nMedium == -1 ) 1173*cdf0e10cSrcweir nMedium = nElem; 1174*cdf0e10cSrcweir } 1175*cdf0e10cSrcweir break; 1176*cdf0e10cSrcweir case KNumberFormatType::LONG : 1177*cdf0e10cSrcweir { 1178*cdf0e10cSrcweir if ( pFormatArr[nElem].Default ) 1179*cdf0e10cSrcweir nLong = nElem; 1180*cdf0e10cSrcweir else if ( nLong == -1 ) 1181*cdf0e10cSrcweir nLong = nElem; 1182*cdf0e10cSrcweir } 1183*cdf0e10cSrcweir break; 1184*cdf0e10cSrcweir } 1185*cdf0e10cSrcweir } 1186*cdf0e10cSrcweir if ( nEdit == -1 ) 1187*cdf0e10cSrcweir { 1188*cdf0e10cSrcweir if (areChecksEnabled()) 1189*cdf0e10cSrcweir { 1190*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 1191*cdf0e10cSrcweir "LocaleDataWrapper::getDateFormatsImpl: no edit")); 1192*cdf0e10cSrcweir outputCheckMessage( appendLocaleInfo( aMsg ) ); 1193*cdf0e10cSrcweir } 1194*cdf0e10cSrcweir if ( nDef == -1 ) 1195*cdf0e10cSrcweir { 1196*cdf0e10cSrcweir if (areChecksEnabled()) 1197*cdf0e10cSrcweir { 1198*cdf0e10cSrcweir String aMsg( RTL_CONSTASCII_USTRINGPARAM( 1199*cdf0e10cSrcweir "LocaleDataWrapper::getDateFormatsImpl: no default")); 1200*cdf0e10cSrcweir outputCheckMessage( appendLocaleInfo( aMsg ) ); 1201*cdf0e10cSrcweir } 1202*cdf0e10cSrcweir if ( nMedium != -1 ) 1203*cdf0e10cSrcweir nDef = nMedium; 1204*cdf0e10cSrcweir else if ( nLong != -1 ) 1205*cdf0e10cSrcweir nDef = nLong; 1206*cdf0e10cSrcweir else 1207*cdf0e10cSrcweir nDef = 0; 1208*cdf0e10cSrcweir } 1209*cdf0e10cSrcweir nEdit = nDef; 1210*cdf0e10cSrcweir } 1211*cdf0e10cSrcweir DateFormat nDF = scanDateFormatImpl( pFormatArr[nEdit].Code ); 1212*cdf0e10cSrcweir if ( pFormatArr[nEdit].Type == KNumberFormatType::LONG ) 1213*cdf0e10cSrcweir { // normally this is not the case 1214*cdf0e10cSrcweir nLongDateFormat = nDateFormat = nDF; 1215*cdf0e10cSrcweir } 1216*cdf0e10cSrcweir else 1217*cdf0e10cSrcweir { 1218*cdf0e10cSrcweir nDateFormat = nDF; 1219*cdf0e10cSrcweir if ( nLong == -1 ) 1220*cdf0e10cSrcweir nLongDateFormat = nDF; 1221*cdf0e10cSrcweir else 1222*cdf0e10cSrcweir nLongDateFormat = scanDateFormatImpl( pFormatArr[nLong].Code ); 1223*cdf0e10cSrcweir } 1224*cdf0e10cSrcweir } 1225*cdf0e10cSrcweir 1226*cdf0e10cSrcweir 1227*cdf0e10cSrcweir // --- digit grouping ------------------------------------------------- 1228*cdf0e10cSrcweir 1229*cdf0e10cSrcweir void LocaleDataWrapper::getDigitGroupingImpl() 1230*cdf0e10cSrcweir { 1231*cdf0e10cSrcweir /* TODO: This is a very simplified grouping setup that only serves its 1232*cdf0e10cSrcweir * current purpose for Indian locales. A free-form flexible one would 1233*cdf0e10cSrcweir * obtain grouping from locale data where it could be specified using, for 1234*cdf0e10cSrcweir * example, codes like #,### and #,##,### that would generate the integer 1235*cdf0e10cSrcweir * sequence. Needed additional API and a locale data element. 1236*cdf0e10cSrcweir */ 1237*cdf0e10cSrcweir 1238*cdf0e10cSrcweir if (!aGrouping.getLength()) 1239*cdf0e10cSrcweir { 1240*cdf0e10cSrcweir aGrouping.realloc(3); // room for {3,2,0} 1241*cdf0e10cSrcweir aGrouping[0] = 0; // invalidate 1242*cdf0e10cSrcweir } 1243*cdf0e10cSrcweir if (!aGrouping[0]) 1244*cdf0e10cSrcweir { 1245*cdf0e10cSrcweir i18n::LanguageCountryInfo aLCInfo( getLanguageCountryInfo()); 1246*cdf0e10cSrcweir if (aLCInfo.Country.equalsIgnoreAsciiCaseAscii( "IN") || // India 1247*cdf0e10cSrcweir aLCInfo.Country.equalsIgnoreAsciiCaseAscii( "BT")) // Bhutan 1248*cdf0e10cSrcweir { 1249*cdf0e10cSrcweir aGrouping[0] = 3; 1250*cdf0e10cSrcweir aGrouping[1] = 2; 1251*cdf0e10cSrcweir aGrouping[2] = 0; 1252*cdf0e10cSrcweir } 1253*cdf0e10cSrcweir else 1254*cdf0e10cSrcweir { 1255*cdf0e10cSrcweir aGrouping[0] = 3; 1256*cdf0e10cSrcweir aGrouping[1] = 0; 1257*cdf0e10cSrcweir } 1258*cdf0e10cSrcweir } 1259*cdf0e10cSrcweir } 1260*cdf0e10cSrcweir 1261*cdf0e10cSrcweir 1262*cdf0e10cSrcweir const ::com::sun::star::uno::Sequence< sal_Int32 > LocaleDataWrapper::getDigitGrouping() const 1263*cdf0e10cSrcweir { 1264*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex ); 1265*cdf0e10cSrcweir if (!aGrouping.getLength() || aGrouping[0] == 0) 1266*cdf0e10cSrcweir { // no cached content 1267*cdf0e10cSrcweir aGuard.changeReadToWrite(); 1268*cdf0e10cSrcweir ((LocaleDataWrapper*)this)->getDigitGroupingImpl(); 1269*cdf0e10cSrcweir } 1270*cdf0e10cSrcweir return aGrouping; 1271*cdf0e10cSrcweir } 1272*cdf0e10cSrcweir 1273*cdf0e10cSrcweir 1274*cdf0e10cSrcweir // --- simple number formatting helpers ------------------------------- 1275*cdf0e10cSrcweir 1276*cdf0e10cSrcweir // The ImplAdd... methods are taken from class International and modified to 1277*cdf0e10cSrcweir // suit the needs. 1278*cdf0e10cSrcweir 1279*cdf0e10cSrcweir static sal_Unicode* ImplAddUNum( sal_Unicode* pBuf, sal_uInt64 nNumber ) 1280*cdf0e10cSrcweir { 1281*cdf0e10cSrcweir // fill temp buffer with digits 1282*cdf0e10cSrcweir sal_Unicode aTempBuf[64]; 1283*cdf0e10cSrcweir sal_Unicode* pTempBuf = aTempBuf; 1284*cdf0e10cSrcweir do 1285*cdf0e10cSrcweir { 1286*cdf0e10cSrcweir *pTempBuf = (sal_Unicode)(nNumber % 10) + '0'; 1287*cdf0e10cSrcweir pTempBuf++; 1288*cdf0e10cSrcweir nNumber /= 10; 1289*cdf0e10cSrcweir } 1290*cdf0e10cSrcweir while ( nNumber ); 1291*cdf0e10cSrcweir 1292*cdf0e10cSrcweir // copy temp buffer to buffer passed 1293*cdf0e10cSrcweir do 1294*cdf0e10cSrcweir { 1295*cdf0e10cSrcweir pTempBuf--; 1296*cdf0e10cSrcweir *pBuf = *pTempBuf; 1297*cdf0e10cSrcweir pBuf++; 1298*cdf0e10cSrcweir } 1299*cdf0e10cSrcweir while ( pTempBuf != aTempBuf ); 1300*cdf0e10cSrcweir 1301*cdf0e10cSrcweir return pBuf; 1302*cdf0e10cSrcweir } 1303*cdf0e10cSrcweir 1304*cdf0e10cSrcweir 1305*cdf0e10cSrcweir static sal_Unicode* ImplAddUNum( sal_Unicode* pBuf, sal_uInt64 nNumber, int nMinLen ) 1306*cdf0e10cSrcweir { 1307*cdf0e10cSrcweir // fill temp buffer with digits 1308*cdf0e10cSrcweir sal_Unicode aTempBuf[64]; 1309*cdf0e10cSrcweir sal_Unicode* pTempBuf = aTempBuf; 1310*cdf0e10cSrcweir do 1311*cdf0e10cSrcweir { 1312*cdf0e10cSrcweir *pTempBuf = (sal_Unicode)(nNumber % 10) + '0'; 1313*cdf0e10cSrcweir pTempBuf++; 1314*cdf0e10cSrcweir nNumber /= 10; 1315*cdf0e10cSrcweir nMinLen--; 1316*cdf0e10cSrcweir } 1317*cdf0e10cSrcweir while ( nNumber ); 1318*cdf0e10cSrcweir 1319*cdf0e10cSrcweir // fill with zeros up to the minimal length 1320*cdf0e10cSrcweir while ( nMinLen > 0 ) 1321*cdf0e10cSrcweir { 1322*cdf0e10cSrcweir *pBuf = '0'; 1323*cdf0e10cSrcweir pBuf++; 1324*cdf0e10cSrcweir nMinLen--; 1325*cdf0e10cSrcweir } 1326*cdf0e10cSrcweir 1327*cdf0e10cSrcweir // copy temp buffer to real buffer 1328*cdf0e10cSrcweir do 1329*cdf0e10cSrcweir { 1330*cdf0e10cSrcweir pTempBuf--; 1331*cdf0e10cSrcweir *pBuf = *pTempBuf; 1332*cdf0e10cSrcweir pBuf++; 1333*cdf0e10cSrcweir } 1334*cdf0e10cSrcweir while ( pTempBuf != aTempBuf ); 1335*cdf0e10cSrcweir 1336*cdf0e10cSrcweir return pBuf; 1337*cdf0e10cSrcweir } 1338*cdf0e10cSrcweir 1339*cdf0e10cSrcweir 1340*cdf0e10cSrcweir static sal_Unicode* ImplAdd2UNum( sal_Unicode* pBuf, sal_uInt16 nNumber, int bLeading ) 1341*cdf0e10cSrcweir { 1342*cdf0e10cSrcweir DBG_ASSERT( nNumber < 100, "ImplAdd2UNum() - Number >= 100" ); 1343*cdf0e10cSrcweir 1344*cdf0e10cSrcweir if ( nNumber < 10 ) 1345*cdf0e10cSrcweir { 1346*cdf0e10cSrcweir if ( bLeading ) 1347*cdf0e10cSrcweir { 1348*cdf0e10cSrcweir *pBuf = '0'; 1349*cdf0e10cSrcweir pBuf++; 1350*cdf0e10cSrcweir } 1351*cdf0e10cSrcweir *pBuf = nNumber + '0'; 1352*cdf0e10cSrcweir } 1353*cdf0e10cSrcweir else 1354*cdf0e10cSrcweir { 1355*cdf0e10cSrcweir sal_uInt16 nTemp = nNumber % 10; 1356*cdf0e10cSrcweir nNumber /= 10; 1357*cdf0e10cSrcweir *pBuf = nNumber + '0'; 1358*cdf0e10cSrcweir pBuf++; 1359*cdf0e10cSrcweir *pBuf = nTemp + '0'; 1360*cdf0e10cSrcweir } 1361*cdf0e10cSrcweir 1362*cdf0e10cSrcweir pBuf++; 1363*cdf0e10cSrcweir return pBuf; 1364*cdf0e10cSrcweir } 1365*cdf0e10cSrcweir 1366*cdf0e10cSrcweir 1367*cdf0e10cSrcweir inline sal_Unicode* ImplAddString( sal_Unicode* pBuf, const String& rStr ) 1368*cdf0e10cSrcweir { 1369*cdf0e10cSrcweir if ( rStr.Len() == 1 ) 1370*cdf0e10cSrcweir *pBuf++ = rStr.GetChar(0); 1371*cdf0e10cSrcweir else if ( rStr.Len() == 0 ) 1372*cdf0e10cSrcweir ; 1373*cdf0e10cSrcweir else 1374*cdf0e10cSrcweir { 1375*cdf0e10cSrcweir memcpy( pBuf, rStr.GetBuffer(), rStr.Len() * sizeof(sal_Unicode) ); 1376*cdf0e10cSrcweir pBuf += rStr.Len(); 1377*cdf0e10cSrcweir } 1378*cdf0e10cSrcweir return pBuf; 1379*cdf0e10cSrcweir } 1380*cdf0e10cSrcweir 1381*cdf0e10cSrcweir 1382*cdf0e10cSrcweir inline sal_Unicode* ImplAddString( sal_Unicode* pBuf, sal_Unicode c ) 1383*cdf0e10cSrcweir { 1384*cdf0e10cSrcweir *pBuf = c; 1385*cdf0e10cSrcweir pBuf++; 1386*cdf0e10cSrcweir return pBuf; 1387*cdf0e10cSrcweir } 1388*cdf0e10cSrcweir 1389*cdf0e10cSrcweir 1390*cdf0e10cSrcweir inline sal_Unicode* ImplAddString( sal_Unicode* pBuf, const sal_Unicode* pCopyBuf, xub_StrLen nLen ) 1391*cdf0e10cSrcweir { 1392*cdf0e10cSrcweir memcpy( pBuf, pCopyBuf, nLen * sizeof(sal_Unicode) ); 1393*cdf0e10cSrcweir return pBuf + nLen; 1394*cdf0e10cSrcweir } 1395*cdf0e10cSrcweir 1396*cdf0e10cSrcweir 1397*cdf0e10cSrcweir sal_Unicode* LocaleDataWrapper::ImplAddFormatNum( sal_Unicode* pBuf, 1398*cdf0e10cSrcweir sal_Int64 nNumber, sal_uInt16 nDecimals, sal_Bool bUseThousandSep, 1399*cdf0e10cSrcweir sal_Bool bTrailingZeros ) const 1400*cdf0e10cSrcweir { 1401*cdf0e10cSrcweir sal_Unicode aNumBuf[64]; 1402*cdf0e10cSrcweir sal_Unicode* pNumBuf; 1403*cdf0e10cSrcweir sal_uInt16 nNumLen; 1404*cdf0e10cSrcweir sal_uInt16 i = 0; 1405*cdf0e10cSrcweir sal_Bool bNeg; 1406*cdf0e10cSrcweir 1407*cdf0e10cSrcweir // negative number 1408*cdf0e10cSrcweir if ( nNumber < 0 ) 1409*cdf0e10cSrcweir { 1410*cdf0e10cSrcweir nNumber *= -1; 1411*cdf0e10cSrcweir bNeg = sal_True; 1412*cdf0e10cSrcweir *pBuf = '-'; 1413*cdf0e10cSrcweir pBuf++; 1414*cdf0e10cSrcweir } 1415*cdf0e10cSrcweir else 1416*cdf0e10cSrcweir bNeg = sal_False; 1417*cdf0e10cSrcweir 1418*cdf0e10cSrcweir // convert number 1419*cdf0e10cSrcweir pNumBuf = ImplAddUNum( aNumBuf, (sal_uInt64)nNumber ); 1420*cdf0e10cSrcweir nNumLen = (sal_uInt16)(sal_uLong)(pNumBuf-aNumBuf); 1421*cdf0e10cSrcweir pNumBuf = aNumBuf; 1422*cdf0e10cSrcweir 1423*cdf0e10cSrcweir if ( nNumLen <= nDecimals ) 1424*cdf0e10cSrcweir { 1425*cdf0e10cSrcweir // strip .0 in decimals? 1426*cdf0e10cSrcweir if ( !nNumber && !bTrailingZeros ) 1427*cdf0e10cSrcweir { 1428*cdf0e10cSrcweir *pBuf = '0'; 1429*cdf0e10cSrcweir pBuf++; 1430*cdf0e10cSrcweir } 1431*cdf0e10cSrcweir else 1432*cdf0e10cSrcweir { 1433*cdf0e10cSrcweir // LeadingZero, insert 0 1434*cdf0e10cSrcweir if ( isNumLeadingZero() ) 1435*cdf0e10cSrcweir { 1436*cdf0e10cSrcweir *pBuf = '0'; 1437*cdf0e10cSrcweir pBuf++; 1438*cdf0e10cSrcweir } 1439*cdf0e10cSrcweir 1440*cdf0e10cSrcweir // append decimal separator 1441*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getNumDecimalSep() ); 1442*cdf0e10cSrcweir 1443*cdf0e10cSrcweir // fill with zeros 1444*cdf0e10cSrcweir while ( i < (nDecimals-nNumLen) ) 1445*cdf0e10cSrcweir { 1446*cdf0e10cSrcweir *pBuf = '0'; 1447*cdf0e10cSrcweir pBuf++; 1448*cdf0e10cSrcweir i++; 1449*cdf0e10cSrcweir } 1450*cdf0e10cSrcweir 1451*cdf0e10cSrcweir // append decimals 1452*cdf0e10cSrcweir while ( nNumLen ) 1453*cdf0e10cSrcweir { 1454*cdf0e10cSrcweir *pBuf = *pNumBuf; 1455*cdf0e10cSrcweir pBuf++; 1456*cdf0e10cSrcweir pNumBuf++; 1457*cdf0e10cSrcweir nNumLen--; 1458*cdf0e10cSrcweir } 1459*cdf0e10cSrcweir } 1460*cdf0e10cSrcweir } 1461*cdf0e10cSrcweir else 1462*cdf0e10cSrcweir { 1463*cdf0e10cSrcweir const String& rThoSep = getNumThousandSep(); 1464*cdf0e10cSrcweir 1465*cdf0e10cSrcweir // copy number to buffer (excluding decimals) 1466*cdf0e10cSrcweir sal_uInt16 nNumLen2 = nNumLen-nDecimals; 1467*cdf0e10cSrcweir uno::Sequence< sal_Bool > aGroupPos; 1468*cdf0e10cSrcweir if (bUseThousandSep) 1469*cdf0e10cSrcweir aGroupPos = utl::DigitGroupingIterator::createForwardSequence( 1470*cdf0e10cSrcweir nNumLen2, getDigitGrouping()); 1471*cdf0e10cSrcweir for ( ; i < nNumLen2; ++i ) 1472*cdf0e10cSrcweir { 1473*cdf0e10cSrcweir *pBuf = *pNumBuf; 1474*cdf0e10cSrcweir pBuf++; 1475*cdf0e10cSrcweir pNumBuf++; 1476*cdf0e10cSrcweir 1477*cdf0e10cSrcweir // add thousand separator? 1478*cdf0e10cSrcweir if ( bUseThousandSep && aGroupPos[i] ) 1479*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rThoSep ); 1480*cdf0e10cSrcweir } 1481*cdf0e10cSrcweir 1482*cdf0e10cSrcweir // append decimals 1483*cdf0e10cSrcweir if ( nDecimals ) 1484*cdf0e10cSrcweir { 1485*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getNumDecimalSep() ); 1486*cdf0e10cSrcweir 1487*cdf0e10cSrcweir sal_Bool bNullEnd = sal_True; 1488*cdf0e10cSrcweir while ( i < nNumLen ) 1489*cdf0e10cSrcweir { 1490*cdf0e10cSrcweir if ( *pNumBuf != '0' ) 1491*cdf0e10cSrcweir bNullEnd = sal_False; 1492*cdf0e10cSrcweir 1493*cdf0e10cSrcweir *pBuf = *pNumBuf; 1494*cdf0e10cSrcweir pBuf++; 1495*cdf0e10cSrcweir pNumBuf++; 1496*cdf0e10cSrcweir i++; 1497*cdf0e10cSrcweir } 1498*cdf0e10cSrcweir 1499*cdf0e10cSrcweir // strip .0 in decimals? 1500*cdf0e10cSrcweir if ( bNullEnd && !bTrailingZeros ) 1501*cdf0e10cSrcweir pBuf -= nDecimals+1; 1502*cdf0e10cSrcweir } 1503*cdf0e10cSrcweir } 1504*cdf0e10cSrcweir 1505*cdf0e10cSrcweir return pBuf; 1506*cdf0e10cSrcweir } 1507*cdf0e10cSrcweir 1508*cdf0e10cSrcweir 1509*cdf0e10cSrcweir // --- simple date and time formatting -------------------------------- 1510*cdf0e10cSrcweir 1511*cdf0e10cSrcweir String LocaleDataWrapper::getDate( const Date& rDate ) const 1512*cdf0e10cSrcweir { 1513*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); 1514*cdf0e10cSrcweir //!TODO: leading zeros et al 1515*cdf0e10cSrcweir sal_Unicode aBuf[128]; 1516*cdf0e10cSrcweir sal_Unicode* pBuf = aBuf; 1517*cdf0e10cSrcweir sal_uInt16 nDay = rDate.GetDay(); 1518*cdf0e10cSrcweir sal_uInt16 nMonth = rDate.GetMonth(); 1519*cdf0e10cSrcweir sal_uInt16 nYear = rDate.GetYear(); 1520*cdf0e10cSrcweir sal_uInt16 nYearLen; 1521*cdf0e10cSrcweir 1522*cdf0e10cSrcweir if ( sal_True /* IsDateCentury() */ ) 1523*cdf0e10cSrcweir nYearLen = 4; 1524*cdf0e10cSrcweir else 1525*cdf0e10cSrcweir { 1526*cdf0e10cSrcweir nYearLen = 2; 1527*cdf0e10cSrcweir nYear %= 100; 1528*cdf0e10cSrcweir } 1529*cdf0e10cSrcweir 1530*cdf0e10cSrcweir switch ( getDateFormat() ) 1531*cdf0e10cSrcweir { 1532*cdf0e10cSrcweir case DMY : 1533*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, nDay, sal_True /* IsDateDayLeadingZero() */ ); 1534*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getDateSep() ); 1535*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, nMonth, sal_True /* IsDateMonthLeadingZero() */ ); 1536*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getDateSep() ); 1537*cdf0e10cSrcweir pBuf = ImplAddUNum( pBuf, nYear, nYearLen ); 1538*cdf0e10cSrcweir break; 1539*cdf0e10cSrcweir case MDY : 1540*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, nMonth, sal_True /* IsDateMonthLeadingZero() */ ); 1541*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getDateSep() ); 1542*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, nDay, sal_True /* IsDateDayLeadingZero() */ ); 1543*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getDateSep() ); 1544*cdf0e10cSrcweir pBuf = ImplAddUNum( pBuf, nYear, nYearLen ); 1545*cdf0e10cSrcweir break; 1546*cdf0e10cSrcweir default: 1547*cdf0e10cSrcweir pBuf = ImplAddUNum( pBuf, nYear, nYearLen ); 1548*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getDateSep() ); 1549*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, nMonth, sal_True /* IsDateMonthLeadingZero() */ ); 1550*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getDateSep() ); 1551*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, nDay, sal_True /* IsDateDayLeadingZero() */ ); 1552*cdf0e10cSrcweir } 1553*cdf0e10cSrcweir 1554*cdf0e10cSrcweir return String( aBuf, (xub_StrLen)(sal_uLong)(pBuf-aBuf) ); 1555*cdf0e10cSrcweir } 1556*cdf0e10cSrcweir 1557*cdf0e10cSrcweir 1558*cdf0e10cSrcweir String LocaleDataWrapper::getTime( const Time& rTime, sal_Bool bSec, sal_Bool b100Sec ) const 1559*cdf0e10cSrcweir { 1560*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); 1561*cdf0e10cSrcweir //!TODO: leading zeros et al 1562*cdf0e10cSrcweir sal_Unicode aBuf[128]; 1563*cdf0e10cSrcweir sal_Unicode* pBuf = aBuf; 1564*cdf0e10cSrcweir sal_uInt16 nHour = rTime.GetHour(); 1565*cdf0e10cSrcweir sal_Bool bHour12 = sal_False; //!TODO: AM/PM from default time format code 1566*cdf0e10cSrcweir 1567*cdf0e10cSrcweir if ( bHour12 ) 1568*cdf0e10cSrcweir { 1569*cdf0e10cSrcweir nHour %= 12; 1570*cdf0e10cSrcweir // 0:00 -> 12:00 1571*cdf0e10cSrcweir if ( !nHour ) 1572*cdf0e10cSrcweir nHour = 12; 1573*cdf0e10cSrcweir } 1574*cdf0e10cSrcweir else 1575*cdf0e10cSrcweir nHour %= 24; 1576*cdf0e10cSrcweir 1577*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, nHour, sal_True /* IsTimeLeadingZero() */ ); 1578*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getTimeSep() ); 1579*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, rTime.GetMin(), sal_True ); 1580*cdf0e10cSrcweir if ( bSec ) 1581*cdf0e10cSrcweir { 1582*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getTimeSep() ); 1583*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, rTime.GetSec(), sal_True ); 1584*cdf0e10cSrcweir 1585*cdf0e10cSrcweir if ( b100Sec ) 1586*cdf0e10cSrcweir { 1587*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getTime100SecSep() ); 1588*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, rTime.Get100Sec(), sal_True ); 1589*cdf0e10cSrcweir } 1590*cdf0e10cSrcweir } 1591*cdf0e10cSrcweir 1592*cdf0e10cSrcweir String aStr( aBuf, (xub_StrLen)(sal_uLong)(pBuf-aBuf) ); 1593*cdf0e10cSrcweir 1594*cdf0e10cSrcweir if ( bHour12 ) 1595*cdf0e10cSrcweir { 1596*cdf0e10cSrcweir if ( (rTime.GetHour() % 24) >= 12 ) 1597*cdf0e10cSrcweir aStr += getTimePM(); 1598*cdf0e10cSrcweir else 1599*cdf0e10cSrcweir aStr += getTimeAM(); 1600*cdf0e10cSrcweir } 1601*cdf0e10cSrcweir #if 0 1602*cdf0e10cSrcweir //!TODO: do we need a time string? like "o'clock" or "Uhr" or similar 1603*cdf0e10cSrcweir else 1604*cdf0e10cSrcweir aStr += getTimeStr(); 1605*cdf0e10cSrcweir #endif 1606*cdf0e10cSrcweir 1607*cdf0e10cSrcweir return aStr; 1608*cdf0e10cSrcweir } 1609*cdf0e10cSrcweir 1610*cdf0e10cSrcweir 1611*cdf0e10cSrcweir String LocaleDataWrapper::getLongDate( const Date& rDate, CalendarWrapper& rCal, 1612*cdf0e10cSrcweir sal_Int16 nDisplayDayOfWeek, sal_Bool bDayOfMonthWithLeadingZero, 1613*cdf0e10cSrcweir sal_Int16 nDisplayMonth, sal_Bool bTwoDigitYear ) const 1614*cdf0e10cSrcweir { 1615*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); 1616*cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 1617*cdf0e10cSrcweir sal_Unicode aBuf[20]; 1618*cdf0e10cSrcweir sal_Unicode* pBuf; 1619*cdf0e10cSrcweir String aStr; 1620*cdf0e10cSrcweir sal_Int16 nVal; 1621*cdf0e10cSrcweir rCal.setGregorianDateTime( rDate ); 1622*cdf0e10cSrcweir // day of week 1623*cdf0e10cSrcweir nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_WEEK ); 1624*cdf0e10cSrcweir aStr += rCal.getDisplayName( CalendarDisplayIndex::DAY, nVal, nDisplayDayOfWeek ); 1625*cdf0e10cSrcweir aStr += getLongDateDayOfWeekSep(); 1626*cdf0e10cSrcweir // day of month 1627*cdf0e10cSrcweir nVal = rCal.getValue( CalendarFieldIndex::DAY_OF_MONTH ); 1628*cdf0e10cSrcweir pBuf = ImplAdd2UNum( aBuf, nVal, bDayOfMonthWithLeadingZero ); 1629*cdf0e10cSrcweir String aDay( aBuf, (xub_StrLen)(sal_uLong)(pBuf-aBuf) ); 1630*cdf0e10cSrcweir // month of year 1631*cdf0e10cSrcweir nVal = rCal.getValue( CalendarFieldIndex::MONTH ); 1632*cdf0e10cSrcweir String aMonth( rCal.getDisplayName( CalendarDisplayIndex::MONTH, nVal, nDisplayMonth ) ); 1633*cdf0e10cSrcweir // year 1634*cdf0e10cSrcweir nVal = rCal.getValue( CalendarFieldIndex::YEAR ); 1635*cdf0e10cSrcweir if ( bTwoDigitYear ) 1636*cdf0e10cSrcweir pBuf = ImplAddUNum( aBuf, nVal % 100, 2 ); 1637*cdf0e10cSrcweir else 1638*cdf0e10cSrcweir pBuf = ImplAddUNum( aBuf, nVal ); 1639*cdf0e10cSrcweir String aYear( aBuf, (xub_StrLen)(sal_uLong)(pBuf-aBuf) ); 1640*cdf0e10cSrcweir // concatenate 1641*cdf0e10cSrcweir switch ( getLongDateFormat() ) 1642*cdf0e10cSrcweir { 1643*cdf0e10cSrcweir case DMY : 1644*cdf0e10cSrcweir aStr += aDay; 1645*cdf0e10cSrcweir aStr += getLongDateDaySep(); 1646*cdf0e10cSrcweir aStr += aMonth; 1647*cdf0e10cSrcweir aStr += getLongDateMonthSep(); 1648*cdf0e10cSrcweir aStr += aYear; 1649*cdf0e10cSrcweir break; 1650*cdf0e10cSrcweir case MDY : 1651*cdf0e10cSrcweir aStr += aMonth; 1652*cdf0e10cSrcweir aStr += getLongDateMonthSep(); 1653*cdf0e10cSrcweir aStr += aDay; 1654*cdf0e10cSrcweir aStr += getLongDateDaySep(); 1655*cdf0e10cSrcweir aStr += aYear; 1656*cdf0e10cSrcweir break; 1657*cdf0e10cSrcweir default: // YMD 1658*cdf0e10cSrcweir aStr += aYear; 1659*cdf0e10cSrcweir aStr += getLongDateYearSep(); 1660*cdf0e10cSrcweir aStr += aMonth; 1661*cdf0e10cSrcweir aStr += getLongDateMonthSep(); 1662*cdf0e10cSrcweir aStr += aDay; 1663*cdf0e10cSrcweir } 1664*cdf0e10cSrcweir return aStr; 1665*cdf0e10cSrcweir } 1666*cdf0e10cSrcweir 1667*cdf0e10cSrcweir 1668*cdf0e10cSrcweir String LocaleDataWrapper::getDuration( const Time& rTime, sal_Bool bSec, sal_Bool b100Sec ) const 1669*cdf0e10cSrcweir { 1670*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); 1671*cdf0e10cSrcweir sal_Unicode aBuf[128]; 1672*cdf0e10cSrcweir sal_Unicode* pBuf = aBuf; 1673*cdf0e10cSrcweir 1674*cdf0e10cSrcweir if ( rTime < Time( 0 ) ) 1675*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1676*cdf0e10cSrcweir 1677*cdf0e10cSrcweir if ( sal_True /* IsTimeLeadingZero() */ ) 1678*cdf0e10cSrcweir pBuf = ImplAddUNum( pBuf, rTime.GetHour(), 2 ); 1679*cdf0e10cSrcweir else 1680*cdf0e10cSrcweir pBuf = ImplAddUNum( pBuf, rTime.GetHour() ); 1681*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getTimeSep() ); 1682*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, rTime.GetMin(), sal_True ); 1683*cdf0e10cSrcweir if ( bSec ) 1684*cdf0e10cSrcweir { 1685*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getTimeSep() ); 1686*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, rTime.GetSec(), sal_True ); 1687*cdf0e10cSrcweir 1688*cdf0e10cSrcweir if ( b100Sec ) 1689*cdf0e10cSrcweir { 1690*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, getTime100SecSep() ); 1691*cdf0e10cSrcweir pBuf = ImplAdd2UNum( pBuf, rTime.Get100Sec(), sal_True ); 1692*cdf0e10cSrcweir } 1693*cdf0e10cSrcweir } 1694*cdf0e10cSrcweir 1695*cdf0e10cSrcweir return String( aBuf, (xub_StrLen)(sal_uLong)(pBuf-aBuf) ); 1696*cdf0e10cSrcweir } 1697*cdf0e10cSrcweir 1698*cdf0e10cSrcweir 1699*cdf0e10cSrcweir // --- simple number formatting --------------------------------------- 1700*cdf0e10cSrcweir 1701*cdf0e10cSrcweir inline size_t ImplGetNumberStringLengthGuess( const LocaleDataWrapper& rLoc, sal_uInt16 nDecimals ) 1702*cdf0e10cSrcweir { 1703*cdf0e10cSrcweir // approximately 3.2 bits per digit 1704*cdf0e10cSrcweir const size_t nDig = ((sizeof(sal_Int64) * 8) / 3) + 1; 1705*cdf0e10cSrcweir // digits, separators (pessimized for insane "every digit may be grouped"), leading zero, sign 1706*cdf0e10cSrcweir size_t nGuess = ((nDecimals < nDig) ? 1707*cdf0e10cSrcweir (((nDig - nDecimals) * rLoc.getNumThousandSep().Len()) + nDig) : 1708*cdf0e10cSrcweir nDecimals) + rLoc.getNumDecimalSep().Len() + 3; 1709*cdf0e10cSrcweir return nGuess; 1710*cdf0e10cSrcweir } 1711*cdf0e10cSrcweir 1712*cdf0e10cSrcweir 1713*cdf0e10cSrcweir String LocaleDataWrapper::getNum( sal_Int64 nNumber, sal_uInt16 nDecimals, 1714*cdf0e10cSrcweir sal_Bool bUseThousandSep, sal_Bool bTrailingZeros ) const 1715*cdf0e10cSrcweir { 1716*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); 1717*cdf0e10cSrcweir sal_Unicode aBuf[128]; // big enough for 64-bit long and crazy grouping 1718*cdf0e10cSrcweir // check if digits and separators will fit into fixed buffer or allocate 1719*cdf0e10cSrcweir size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals ); 1720*cdf0e10cSrcweir sal_Unicode* const pBuffer = (nGuess < 118 ? aBuf : 1721*cdf0e10cSrcweir new sal_Unicode[nGuess + 16]); 1722*cdf0e10cSrcweir 1723*cdf0e10cSrcweir sal_Unicode* pBuf = ImplAddFormatNum( pBuffer, nNumber, nDecimals, 1724*cdf0e10cSrcweir bUseThousandSep, bTrailingZeros ); 1725*cdf0e10cSrcweir String aStr( pBuffer, (xub_StrLen)(sal_uLong)(pBuf-pBuffer) ); 1726*cdf0e10cSrcweir 1727*cdf0e10cSrcweir if ( pBuffer != aBuf ) 1728*cdf0e10cSrcweir delete [] pBuffer; 1729*cdf0e10cSrcweir return aStr; 1730*cdf0e10cSrcweir } 1731*cdf0e10cSrcweir 1732*cdf0e10cSrcweir 1733*cdf0e10cSrcweir String LocaleDataWrapper::getCurr( sal_Int64 nNumber, sal_uInt16 nDecimals, 1734*cdf0e10cSrcweir const String& rCurrencySymbol, sal_Bool bUseThousandSep ) const 1735*cdf0e10cSrcweir { 1736*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); 1737*cdf0e10cSrcweir sal_Unicode aBuf[192]; 1738*cdf0e10cSrcweir sal_Unicode aNumBuf[128]; // big enough for 64-bit long and crazy grouping 1739*cdf0e10cSrcweir sal_Unicode cZeroChar = getCurrZeroChar(); 1740*cdf0e10cSrcweir 1741*cdf0e10cSrcweir // check if digits and separators will fit into fixed buffer or allocate 1742*cdf0e10cSrcweir size_t nGuess = ImplGetNumberStringLengthGuess( *this, nDecimals ); 1743*cdf0e10cSrcweir sal_Unicode* const pNumBuffer = (nGuess < 118 ? aNumBuf : 1744*cdf0e10cSrcweir new sal_Unicode[nGuess + 16]); 1745*cdf0e10cSrcweir 1746*cdf0e10cSrcweir sal_Unicode* const pBuffer = 1747*cdf0e10cSrcweir ((size_t(rCurrencySymbol.Len()) + nGuess + 20) < sizeof(aBuf)/sizeof(aBuf[0]) ? aBuf : 1748*cdf0e10cSrcweir new sal_Unicode[ rCurrencySymbol.Len() + nGuess + 20 ]); 1749*cdf0e10cSrcweir sal_Unicode* pBuf = pBuffer; 1750*cdf0e10cSrcweir 1751*cdf0e10cSrcweir sal_Bool bNeg; 1752*cdf0e10cSrcweir if ( nNumber < 0 ) 1753*cdf0e10cSrcweir { 1754*cdf0e10cSrcweir bNeg = sal_True; 1755*cdf0e10cSrcweir nNumber *= -1; 1756*cdf0e10cSrcweir } 1757*cdf0e10cSrcweir else 1758*cdf0e10cSrcweir bNeg = sal_False; 1759*cdf0e10cSrcweir 1760*cdf0e10cSrcweir // convert number 1761*cdf0e10cSrcweir sal_Unicode* pEndNumBuf = ImplAddFormatNum( pNumBuffer, nNumber, nDecimals, 1762*cdf0e10cSrcweir bUseThousandSep, sal_True ); 1763*cdf0e10cSrcweir xub_StrLen nNumLen = (xub_StrLen)(sal_uLong)(pEndNumBuf-pNumBuffer); 1764*cdf0e10cSrcweir 1765*cdf0e10cSrcweir // replace zeros with zero character 1766*cdf0e10cSrcweir if ( (cZeroChar != '0') && nDecimals /* && IsNumTrailingZeros() */ ) 1767*cdf0e10cSrcweir { 1768*cdf0e10cSrcweir sal_Unicode* pTempBuf; 1769*cdf0e10cSrcweir sal_uInt16 i; 1770*cdf0e10cSrcweir sal_Bool bZero = sal_True; 1771*cdf0e10cSrcweir 1772*cdf0e10cSrcweir pTempBuf = pNumBuffer+nNumLen-nDecimals; 1773*cdf0e10cSrcweir i = 0; 1774*cdf0e10cSrcweir do 1775*cdf0e10cSrcweir { 1776*cdf0e10cSrcweir if ( *pTempBuf != '0' ) 1777*cdf0e10cSrcweir { 1778*cdf0e10cSrcweir bZero = sal_False; 1779*cdf0e10cSrcweir break; 1780*cdf0e10cSrcweir } 1781*cdf0e10cSrcweir 1782*cdf0e10cSrcweir pTempBuf++; 1783*cdf0e10cSrcweir i++; 1784*cdf0e10cSrcweir } 1785*cdf0e10cSrcweir while ( i < nDecimals ); 1786*cdf0e10cSrcweir 1787*cdf0e10cSrcweir if ( bZero ) 1788*cdf0e10cSrcweir { 1789*cdf0e10cSrcweir pTempBuf = pNumBuffer+nNumLen-nDecimals; 1790*cdf0e10cSrcweir i = 0; 1791*cdf0e10cSrcweir do 1792*cdf0e10cSrcweir { 1793*cdf0e10cSrcweir *pTempBuf = cZeroChar; 1794*cdf0e10cSrcweir pTempBuf++; 1795*cdf0e10cSrcweir i++; 1796*cdf0e10cSrcweir } 1797*cdf0e10cSrcweir while ( i < nDecimals ); 1798*cdf0e10cSrcweir } 1799*cdf0e10cSrcweir } 1800*cdf0e10cSrcweir 1801*cdf0e10cSrcweir if ( !bNeg ) 1802*cdf0e10cSrcweir { 1803*cdf0e10cSrcweir switch( getCurrPositiveFormat() ) 1804*cdf0e10cSrcweir { 1805*cdf0e10cSrcweir case 0: 1806*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1807*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1808*cdf0e10cSrcweir break; 1809*cdf0e10cSrcweir case 1: 1810*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1811*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1812*cdf0e10cSrcweir break; 1813*cdf0e10cSrcweir case 2: 1814*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1815*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1816*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1817*cdf0e10cSrcweir break; 1818*cdf0e10cSrcweir case 3: 1819*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1820*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1821*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1822*cdf0e10cSrcweir break; 1823*cdf0e10cSrcweir } 1824*cdf0e10cSrcweir } 1825*cdf0e10cSrcweir else 1826*cdf0e10cSrcweir { 1827*cdf0e10cSrcweir switch( getCurrNegativeFormat() ) 1828*cdf0e10cSrcweir { 1829*cdf0e10cSrcweir case 0: 1830*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '(' ); 1831*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1832*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1833*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ')' ); 1834*cdf0e10cSrcweir break; 1835*cdf0e10cSrcweir case 1: 1836*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1837*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1838*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1839*cdf0e10cSrcweir break; 1840*cdf0e10cSrcweir case 2: 1841*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1842*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1843*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1844*cdf0e10cSrcweir break; 1845*cdf0e10cSrcweir case 3: 1846*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1847*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1848*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1849*cdf0e10cSrcweir break; 1850*cdf0e10cSrcweir case 4: 1851*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '(' ); 1852*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1853*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1854*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ')' ); 1855*cdf0e10cSrcweir break; 1856*cdf0e10cSrcweir case 5: 1857*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1858*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1859*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1860*cdf0e10cSrcweir break; 1861*cdf0e10cSrcweir case 6: 1862*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1863*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1864*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1865*cdf0e10cSrcweir break; 1866*cdf0e10cSrcweir case 7: 1867*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1868*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1869*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1870*cdf0e10cSrcweir break; 1871*cdf0e10cSrcweir case 8: 1872*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1873*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1874*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1875*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1876*cdf0e10cSrcweir break; 1877*cdf0e10cSrcweir case 9: 1878*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1879*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1880*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1881*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1882*cdf0e10cSrcweir break; 1883*cdf0e10cSrcweir case 10: 1884*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1885*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1886*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1887*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1888*cdf0e10cSrcweir break; 1889*cdf0e10cSrcweir case 11: 1890*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1891*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1892*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1893*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1894*cdf0e10cSrcweir break; 1895*cdf0e10cSrcweir case 12: 1896*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1897*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1898*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1899*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1900*cdf0e10cSrcweir break; 1901*cdf0e10cSrcweir case 13: 1902*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1903*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '-' ); 1904*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1905*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1906*cdf0e10cSrcweir break; 1907*cdf0e10cSrcweir case 14: 1908*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '(' ); 1909*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1910*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1911*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1912*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ')' ); 1913*cdf0e10cSrcweir break; 1914*cdf0e10cSrcweir case 15: 1915*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, '(' ); 1916*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, pNumBuffer, nNumLen ); 1917*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ' ' ); 1918*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, rCurrencySymbol ); 1919*cdf0e10cSrcweir pBuf = ImplAddString( pBuf, ')' ); 1920*cdf0e10cSrcweir break; 1921*cdf0e10cSrcweir } 1922*cdf0e10cSrcweir } 1923*cdf0e10cSrcweir 1924*cdf0e10cSrcweir String aNumber( pBuffer, (xub_StrLen)(sal_uLong)(pBuf-pBuffer) ); 1925*cdf0e10cSrcweir 1926*cdf0e10cSrcweir if ( pBuffer != aBuf ) 1927*cdf0e10cSrcweir delete [] pBuffer; 1928*cdf0e10cSrcweir if ( pNumBuffer != aNumBuf ) 1929*cdf0e10cSrcweir delete [] pNumBuffer; 1930*cdf0e10cSrcweir 1931*cdf0e10cSrcweir return aNumber; 1932*cdf0e10cSrcweir } 1933*cdf0e10cSrcweir 1934*cdf0e10cSrcweir 1935*cdf0e10cSrcweir // --- mixed ---------------------------------------------------------- 1936*cdf0e10cSrcweir 1937*cdf0e10cSrcweir ::com::sun::star::lang::Locale LocaleDataWrapper::getLoadedLocale() const 1938*cdf0e10cSrcweir { 1939*cdf0e10cSrcweir LanguageCountryInfo aLCInfo = getLanguageCountryInfo(); 1940*cdf0e10cSrcweir return lang::Locale( aLCInfo.Language, aLCInfo.Country, aLCInfo.Variant ); 1941*cdf0e10cSrcweir } 1942*cdf0e10cSrcweir 1943*cdf0e10cSrcweir 1944*cdf0e10cSrcweir String& LocaleDataWrapper::appendLocaleInfo( String& rDebugMsg ) const 1945*cdf0e10cSrcweir { 1946*cdf0e10cSrcweir ::utl::ReadWriteGuard aGuard( aMutex, ::utl::ReadWriteGuardMode::nBlockCritical ); 1947*cdf0e10cSrcweir rDebugMsg += '\n'; 1948*cdf0e10cSrcweir rDebugMsg += String( aLocale.Language); 1949*cdf0e10cSrcweir rDebugMsg += '_'; 1950*cdf0e10cSrcweir rDebugMsg += String( aLocale.Country); 1951*cdf0e10cSrcweir rDebugMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " requested\n" ) ); 1952*cdf0e10cSrcweir lang::Locale aLoaded = getLoadedLocale(); 1953*cdf0e10cSrcweir rDebugMsg += String( aLoaded.Language); 1954*cdf0e10cSrcweir rDebugMsg += '_'; 1955*cdf0e10cSrcweir rDebugMsg += String( aLoaded.Country); 1956*cdf0e10cSrcweir rDebugMsg.AppendAscii( RTL_CONSTASCII_STRINGPARAM( " loaded" ) ); 1957*cdf0e10cSrcweir return rDebugMsg; 1958*cdf0e10cSrcweir } 1959*cdf0e10cSrcweir 1960*cdf0e10cSrcweir 1961*cdf0e10cSrcweir // static 1962*cdf0e10cSrcweir void LocaleDataWrapper::outputCheckMessage( const String& rMsg ) 1963*cdf0e10cSrcweir { 1964*cdf0e10cSrcweir outputCheckMessage( ByteString( rMsg, RTL_TEXTENCODING_UTF8).GetBuffer()); 1965*cdf0e10cSrcweir } 1966*cdf0e10cSrcweir 1967*cdf0e10cSrcweir 1968*cdf0e10cSrcweir // static 1969*cdf0e10cSrcweir void LocaleDataWrapper::outputCheckMessage( const char* pStr ) 1970*cdf0e10cSrcweir { 1971*cdf0e10cSrcweir fprintf( stderr, "\n%s\n", pStr); 1972*cdf0e10cSrcweir fflush( stderr); 1973*cdf0e10cSrcweir DBG_ERROR( pStr); 1974*cdf0e10cSrcweir } 1975*cdf0e10cSrcweir 1976*cdf0e10cSrcweir 1977*cdf0e10cSrcweir // static 1978*cdf0e10cSrcweir void LocaleDataWrapper::evaluateLocaleDataChecking() 1979*cdf0e10cSrcweir { 1980*cdf0e10cSrcweir // Using the rtl_Instance template here wouldn't solve all threaded write 1981*cdf0e10cSrcweir // accesses, since we want to assign the result to the static member 1982*cdf0e10cSrcweir // variable and would need to dereference the pointer returned and assign 1983*cdf0e10cSrcweir // the value unguarded. This is the same pattern manually coded. 1984*cdf0e10cSrcweir sal_uInt8 nCheck = nLocaleDataChecking; 1985*cdf0e10cSrcweir if (!nCheck) 1986*cdf0e10cSrcweir { 1987*cdf0e10cSrcweir ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex()); 1988*cdf0e10cSrcweir nCheck = nLocaleDataChecking; 1989*cdf0e10cSrcweir if (!nCheck) 1990*cdf0e10cSrcweir { 1991*cdf0e10cSrcweir #ifdef DBG_UTIL 1992*cdf0e10cSrcweir nCheck = 1; 1993*cdf0e10cSrcweir #else 1994*cdf0e10cSrcweir const char* pEnv = getenv( "OOO_ENABLE_LOCALE_DATA_CHECKS"); 1995*cdf0e10cSrcweir if (pEnv && (pEnv[0] == 'Y' || pEnv[0] == 'y' || pEnv[0] == '1')) 1996*cdf0e10cSrcweir nCheck = 1; 1997*cdf0e10cSrcweir else 1998*cdf0e10cSrcweir nCheck = 2; 1999*cdf0e10cSrcweir #endif 2000*cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 2001*cdf0e10cSrcweir nLocaleDataChecking = nCheck; 2002*cdf0e10cSrcweir } 2003*cdf0e10cSrcweir } 2004*cdf0e10cSrcweir else { 2005*cdf0e10cSrcweir OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER(); 2006*cdf0e10cSrcweir } 2007*cdf0e10cSrcweir } 2008