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_tools.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <string.h> 32*cdf0e10cSrcweir #include <stdio.h> 33*cdf0e10cSrcweir #include <stdlib.h> 34*cdf0e10cSrcweir #include <vos/signal.hxx> 35*cdf0e10cSrcweir #include <tools/debug.hxx> 36*cdf0e10cSrcweir #ifndef _TABLE_HXX 37*cdf0e10cSrcweir #include <tools/table.hxx> 38*cdf0e10cSrcweir #endif 39*cdf0e10cSrcweir #include <tools/stream.hxx> 40*cdf0e10cSrcweir #include <tools/resmgr.hxx> 41*cdf0e10cSrcweir #include <tools/rc.hxx> 42*cdf0e10cSrcweir #include <tools/rcid.h> 43*cdf0e10cSrcweir #include <osl/endian.h> 44*cdf0e10cSrcweir #include <osl/process.h> 45*cdf0e10cSrcweir #include <osl/thread.h> 46*cdf0e10cSrcweir #include <osl/file.hxx> 47*cdf0e10cSrcweir #include <osl/mutex.hxx> 48*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 49*cdf0e10cSrcweir #include <rtl/strbuf.hxx> 50*cdf0e10cSrcweir #include <tools/urlobj.hxx> 51*cdf0e10cSrcweir #include <rtl/instance.hxx> 52*cdf0e10cSrcweir #include <rtl/bootstrap.hxx> 53*cdf0e10cSrcweir #include <i18npool/mslangid.hxx> 54*cdf0e10cSrcweir #include <tools/simplerm.hxx> 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir #include <tools/isofallback.hxx> 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir #include <functional> 59*cdf0e10cSrcweir #include <algorithm> 60*cdf0e10cSrcweir #include <hash_map> 61*cdf0e10cSrcweir #include <list> 62*cdf0e10cSrcweir #include <set> 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir #ifdef UNX 65*cdf0e10cSrcweir #define SEARCH_PATH_DELIMITER_CHAR_STRING ":" 66*cdf0e10cSrcweir #define SEARCH_PATH_DELIMITER ':' 67*cdf0e10cSrcweir #else 68*cdf0e10cSrcweir #define SEARCH_PATH_DELIMITER_CHAR_STRING ";" 69*cdf0e10cSrcweir #define SEARCH_PATH_DELIMITER ';' 70*cdf0e10cSrcweir #endif 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir #define SEARCH_PATH_DELIMITER_STRING ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SEARCH_PATH_DELIMITER_CHAR_STRING ) ) 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir using namespace rtl; 75*cdf0e10cSrcweir using namespace osl; 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir // for thread safety 78*cdf0e10cSrcweir static osl::Mutex* pResMgrMutex = NULL; 79*cdf0e10cSrcweir static osl::Mutex& getResMgrMutex() 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir if( !pResMgrMutex ) 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( *osl::Mutex::getGlobalMutex() ); 84*cdf0e10cSrcweir if( ! pResMgrMutex ) 85*cdf0e10cSrcweir pResMgrMutex = new osl::Mutex(); 86*cdf0e10cSrcweir } 87*cdf0e10cSrcweir return *pResMgrMutex; 88*cdf0e10cSrcweir } 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir struct ImpContent; 91*cdf0e10cSrcweir class InternalResMgr 92*cdf0e10cSrcweir { 93*cdf0e10cSrcweir friend class ResMgr; 94*cdf0e10cSrcweir friend class SimpleResMgr; 95*cdf0e10cSrcweir friend class ResMgrContainer; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir ImpContent * pContent; 98*cdf0e10cSrcweir sal_uInt32 nOffCorrection; 99*cdf0e10cSrcweir sal_uInt8 * pStringBlock; 100*cdf0e10cSrcweir SvStream * pStm; 101*cdf0e10cSrcweir sal_Bool bEqual2Content; 102*cdf0e10cSrcweir sal_uInt32 nEntries; 103*cdf0e10cSrcweir OUString aFileName; 104*cdf0e10cSrcweir OUString aPrefix; 105*cdf0e10cSrcweir OUString aResName; 106*cdf0e10cSrcweir bool bSingular; 107*cdf0e10cSrcweir com::sun::star::lang::Locale aLocale; 108*cdf0e10cSrcweir std::hash_map<sal_uInt64, int>* pResUseDump; 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir InternalResMgr( const OUString& rFileURL, 111*cdf0e10cSrcweir const OUString& aPrefix, 112*cdf0e10cSrcweir const OUString& aResName, 113*cdf0e10cSrcweir const com::sun::star::lang::Locale& rLocale ); 114*cdf0e10cSrcweir ~InternalResMgr(); 115*cdf0e10cSrcweir sal_Bool Create(); 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir sal_Bool IsGlobalAvailable( RESOURCE_TYPE nRT, sal_uInt32 nId ) const; 118*cdf0e10cSrcweir void * LoadGlobalRes( RESOURCE_TYPE nRT, sal_uInt32 nId, 119*cdf0e10cSrcweir void **pResHandle ); 120*cdf0e10cSrcweir public: 121*cdf0e10cSrcweir void FreeGlobalRes( void *, void * ); 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir SvStream * GetBitmapStream( sal_uInt32 nResId ); 124*cdf0e10cSrcweir }; 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir // ======================================================================= 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir class ResMgrContainer 129*cdf0e10cSrcweir { 130*cdf0e10cSrcweir static ResMgrContainer* pOneInstance; 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir struct ContainerElement 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir InternalResMgr* pResMgr; 135*cdf0e10cSrcweir OUString aFileURL; 136*cdf0e10cSrcweir int nRefCount; 137*cdf0e10cSrcweir int nLoadCount; 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir ContainerElement() : 140*cdf0e10cSrcweir pResMgr( NULL ), 141*cdf0e10cSrcweir nRefCount( 0 ), 142*cdf0e10cSrcweir nLoadCount( 0 ) 143*cdf0e10cSrcweir {} 144*cdf0e10cSrcweir }; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir std::hash_map< OUString, ContainerElement, OUStringHash> m_aResFiles; 147*cdf0e10cSrcweir com::sun::star::lang::Locale m_aDefLocale; 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir ResMgrContainer() { init(); } 150*cdf0e10cSrcweir ~ResMgrContainer(); 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir void init(); 153*cdf0e10cSrcweir public: 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir static ResMgrContainer& get(); 156*cdf0e10cSrcweir static void release(); 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir InternalResMgr* getResMgr( const OUString& rPrefix, 159*cdf0e10cSrcweir com::sun::star::lang::Locale& rLocale, 160*cdf0e10cSrcweir bool bForceNewInstance = false 161*cdf0e10cSrcweir ); 162*cdf0e10cSrcweir InternalResMgr* getNextFallback( InternalResMgr* pResMgr ); 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir void freeResMgr( InternalResMgr* pResMgr ); 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir void setDefLocale( const com::sun::star::lang::Locale& rLocale ) 167*cdf0e10cSrcweir { m_aDefLocale = rLocale; } 168*cdf0e10cSrcweir const com::sun::star::lang::Locale& getDefLocale() const 169*cdf0e10cSrcweir { return m_aDefLocale; } 170*cdf0e10cSrcweir }; 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir ResMgrContainer* ResMgrContainer::pOneInstance = NULL; 173*cdf0e10cSrcweir 174*cdf0e10cSrcweir ResMgrContainer& ResMgrContainer::get() 175*cdf0e10cSrcweir { 176*cdf0e10cSrcweir if( ! pOneInstance ) 177*cdf0e10cSrcweir pOneInstance = new ResMgrContainer(); 178*cdf0e10cSrcweir return *pOneInstance; 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir ResMgrContainer::~ResMgrContainer() 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir for( std::hash_map< OUString, ContainerElement, OUStringHash >::iterator it = 184*cdf0e10cSrcweir m_aResFiles.begin(); it != m_aResFiles.end(); ++it ) 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir OSL_TRACE( "Resource file %s loaded %d times\n", 187*cdf0e10cSrcweir OUStringToOString( it->second.aFileURL, osl_getThreadTextEncoding() ).getStr(), 188*cdf0e10cSrcweir it->second.nLoadCount ); 189*cdf0e10cSrcweir delete it->second.pResMgr; 190*cdf0e10cSrcweir } 191*cdf0e10cSrcweir } 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir void ResMgrContainer::release() 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir delete pOneInstance; 196*cdf0e10cSrcweir pOneInstance = NULL; 197*cdf0e10cSrcweir } 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir void ResMgrContainer::init() 200*cdf0e10cSrcweir { 201*cdf0e10cSrcweir // get resource path 202*cdf0e10cSrcweir std::list< OUString > aDirs; 203*cdf0e10cSrcweir sal_Int32 nIndex = 0; 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir // 1. fixed locations 206*cdf0e10cSrcweir rtl::OUString uri( 207*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program/resource")); 208*cdf0e10cSrcweir rtl::Bootstrap::expandMacros(uri); 209*cdf0e10cSrcweir aDirs.push_back(uri); 210*cdf0e10cSrcweir uri = rtl::OUString( 211*cdf0e10cSrcweir RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program/resource")); 212*cdf0e10cSrcweir rtl::Bootstrap::expandMacros(uri); 213*cdf0e10cSrcweir aDirs.push_back(uri); 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir // 2. in STAR_RESOURCEPATH 216*cdf0e10cSrcweir const sal_Char* pEnv = getenv( "STAR_RESOURCEPATH" ); 217*cdf0e10cSrcweir if( pEnv ) 218*cdf0e10cSrcweir { 219*cdf0e10cSrcweir OUString aEnvPath( OStringToOUString( OString( pEnv ), osl_getThreadTextEncoding() ) ); 220*cdf0e10cSrcweir nIndex = 0; 221*cdf0e10cSrcweir while( nIndex >= 0 ) 222*cdf0e10cSrcweir { 223*cdf0e10cSrcweir OUString aPathElement( aEnvPath.getToken( 0, SEARCH_PATH_DELIMITER, nIndex ) ); 224*cdf0e10cSrcweir if( aPathElement.getLength() ) 225*cdf0e10cSrcweir { 226*cdf0e10cSrcweir OUString aFileURL; 227*cdf0e10cSrcweir File::getFileURLFromSystemPath( aPathElement, aFileURL ); 228*cdf0e10cSrcweir aDirs.push_back( aFileURL); 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir } 231*cdf0e10cSrcweir } 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir // collect all possible resource files 234*cdf0e10cSrcweir for( std::list< OUString >::const_iterator dir_it = aDirs.begin(); dir_it != aDirs.end(); ++dir_it ) 235*cdf0e10cSrcweir { 236*cdf0e10cSrcweir Directory aDir( *dir_it ); 237*cdf0e10cSrcweir if( aDir.open() == FileBase::E_None ) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir DirectoryItem aItem; 240*cdf0e10cSrcweir while( aDir.getNextItem( aItem ) == FileBase::E_None ) 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir FileStatus aStatus(FileStatusMask_FileName); 243*cdf0e10cSrcweir if( aItem.getFileStatus( aStatus ) == FileBase::E_None ) 244*cdf0e10cSrcweir { 245*cdf0e10cSrcweir OUString aFileName = aStatus.getFileName(); 246*cdf0e10cSrcweir if( aFileName.getLength() < 5 ) 247*cdf0e10cSrcweir continue; 248*cdf0e10cSrcweir if( ! aFileName.endsWithIgnoreAsciiCaseAsciiL( ".res", 4 ) ) 249*cdf0e10cSrcweir continue; 250*cdf0e10cSrcweir OUString aResName = aFileName.copy( 0, aFileName.getLength()-4 ); 251*cdf0e10cSrcweir if( m_aResFiles.find( aResName ) != m_aResFiles.end() ) 252*cdf0e10cSrcweir continue; 253*cdf0e10cSrcweir OUStringBuffer aURL( dir_it->getLength() + aFileName.getLength() + 1 ); 254*cdf0e10cSrcweir aURL.append( *dir_it ); 255*cdf0e10cSrcweir if( !dir_it->endsWithIgnoreAsciiCaseAsciiL( "/", 1 ) ) 256*cdf0e10cSrcweir aURL.append( sal_Unicode('/') ); 257*cdf0e10cSrcweir aURL.append( aFileName ); 258*cdf0e10cSrcweir m_aResFiles[ aResName ].aFileURL = aURL.makeStringAndClear(); 259*cdf0e10cSrcweir } 260*cdf0e10cSrcweir } 261*cdf0e10cSrcweir } 262*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 263*cdf0e10cSrcweir else 264*cdf0e10cSrcweir OSL_TRACE( "opening dir %s failed\n", OUStringToOString( *dir_it, osl_getThreadTextEncoding() ).getStr() ); 265*cdf0e10cSrcweir #endif 266*cdf0e10cSrcweir } 267*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 268*cdf0e10cSrcweir for( std::hash_map< OUString, ContainerElement, OUStringHash >::const_iterator it = 269*cdf0e10cSrcweir m_aResFiles.begin(); it != m_aResFiles.end(); ++it ) 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir OSL_TRACE( "ResMgrContainer: %s -> %s\n", 272*cdf0e10cSrcweir OUStringToOString( it->first, osl_getThreadTextEncoding() ).getStr(), 273*cdf0e10cSrcweir OUStringToOString( it->second.aFileURL, osl_getThreadTextEncoding() ).getStr() ); 274*cdf0e10cSrcweir } 275*cdf0e10cSrcweir #endif 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir // set default language 278*cdf0e10cSrcweir LanguageType nLang = MsLangId::getSystemUILanguage(); 279*cdf0e10cSrcweir MsLangId::convertLanguageToLocale(nLang, m_aDefLocale); 280*cdf0e10cSrcweir } 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir InternalResMgr* ResMgrContainer::getResMgr( const OUString& rPrefix, 283*cdf0e10cSrcweir com::sun::star::lang::Locale& rLocale, 284*cdf0e10cSrcweir bool bForceNewInstance 285*cdf0e10cSrcweir ) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir com::sun::star::lang::Locale aLocale( rLocale ); 288*cdf0e10cSrcweir OUStringBuffer aSearch( rPrefix.getLength() + 16 ); 289*cdf0e10cSrcweir std::hash_map< OUString, ContainerElement, OUStringHash >::iterator it = m_aResFiles.end(); 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir int nTries = 0; 292*cdf0e10cSrcweir if( aLocale.Language.getLength() > 0 ) 293*cdf0e10cSrcweir nTries = 1; 294*cdf0e10cSrcweir if( aLocale.Country.getLength() > 0 ) 295*cdf0e10cSrcweir nTries = 2; 296*cdf0e10cSrcweir if( aLocale.Variant.getLength() > 0 ) 297*cdf0e10cSrcweir nTries = 3; 298*cdf0e10cSrcweir while( nTries-- ) 299*cdf0e10cSrcweir { 300*cdf0e10cSrcweir aSearch.append( rPrefix ); 301*cdf0e10cSrcweir if( nTries > -1 ) 302*cdf0e10cSrcweir { 303*cdf0e10cSrcweir aSearch.append( aLocale.Language ); 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir if( nTries > 0 ) 306*cdf0e10cSrcweir { 307*cdf0e10cSrcweir aSearch.append( sal_Unicode('-') ); 308*cdf0e10cSrcweir aSearch.append( aLocale.Country ); 309*cdf0e10cSrcweir } 310*cdf0e10cSrcweir if( nTries > 1 ) 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir aSearch.append( sal_Unicode('-') ); 313*cdf0e10cSrcweir aSearch.append( aLocale.Variant ); 314*cdf0e10cSrcweir } 315*cdf0e10cSrcweir it = m_aResFiles.find( aSearch.makeStringAndClear() ); 316*cdf0e10cSrcweir if( it != m_aResFiles.end() ) 317*cdf0e10cSrcweir { 318*cdf0e10cSrcweir // ensure InternalResMgr existance 319*cdf0e10cSrcweir if( ! it->second.pResMgr ) 320*cdf0e10cSrcweir { 321*cdf0e10cSrcweir InternalResMgr* pImp = 322*cdf0e10cSrcweir new InternalResMgr( it->second.aFileURL, rPrefix, it->first, aLocale ); 323*cdf0e10cSrcweir if( ! pImp->Create() ) 324*cdf0e10cSrcweir { 325*cdf0e10cSrcweir delete pImp; 326*cdf0e10cSrcweir continue; 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir it->second.pResMgr = pImp; 329*cdf0e10cSrcweir } 330*cdf0e10cSrcweir break; 331*cdf0e10cSrcweir } 332*cdf0e10cSrcweir if( nTries == 0 && !aLocale.Language.equalsIgnoreAsciiCaseAscii( "en" ) ) 333*cdf0e10cSrcweir { 334*cdf0e10cSrcweir // locale fallback failed 335*cdf0e10cSrcweir // fallback to en-US locale 336*cdf0e10cSrcweir nTries = 2; 337*cdf0e10cSrcweir aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) ); 338*cdf0e10cSrcweir aLocale.Country = OUString( RTL_CONSTASCII_USTRINGPARAM( "US" ) ); 339*cdf0e10cSrcweir aLocale.Variant = OUString(); 340*cdf0e10cSrcweir } 341*cdf0e10cSrcweir } 342*cdf0e10cSrcweir // try if there is anything with this prefix at all 343*cdf0e10cSrcweir if( it == m_aResFiles.end() ) 344*cdf0e10cSrcweir { 345*cdf0e10cSrcweir aLocale = com::sun::star::lang::Locale(); 346*cdf0e10cSrcweir it = m_aResFiles.find( rPrefix ); 347*cdf0e10cSrcweir if( it == m_aResFiles.end() ) 348*cdf0e10cSrcweir { 349*cdf0e10cSrcweir for( it = m_aResFiles.begin(); it != m_aResFiles.end(); ++it ) 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir if( it->first.matchIgnoreAsciiCase( rPrefix ) ) 352*cdf0e10cSrcweir { 353*cdf0e10cSrcweir // ensure InternalResMgr existance 354*cdf0e10cSrcweir if( ! it->second.pResMgr ) 355*cdf0e10cSrcweir { 356*cdf0e10cSrcweir InternalResMgr* pImp = 357*cdf0e10cSrcweir new InternalResMgr( it->second.aFileURL, 358*cdf0e10cSrcweir rPrefix, 359*cdf0e10cSrcweir it->first, 360*cdf0e10cSrcweir aLocale ); 361*cdf0e10cSrcweir if( ! pImp->Create() ) 362*cdf0e10cSrcweir { 363*cdf0e10cSrcweir delete pImp; 364*cdf0e10cSrcweir continue; 365*cdf0e10cSrcweir } 366*cdf0e10cSrcweir it->second.pResMgr = pImp; 367*cdf0e10cSrcweir } 368*cdf0e10cSrcweir // try to guess locale 369*cdf0e10cSrcweir sal_Int32 nIndex = rPrefix.getLength(); 370*cdf0e10cSrcweir aLocale.Language = it->first.getToken( 0, '-', nIndex ); 371*cdf0e10cSrcweir if( nIndex > 0 ) 372*cdf0e10cSrcweir aLocale.Country = it->first.getToken( 0, '-', nIndex ); 373*cdf0e10cSrcweir if( nIndex > 0 ) 374*cdf0e10cSrcweir aLocale.Variant = it->first.getToken( 0, '-', nIndex ); 375*cdf0e10cSrcweir break; 376*cdf0e10cSrcweir } 377*cdf0e10cSrcweir } 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir // give up 381*cdf0e10cSrcweir if( it == m_aResFiles.end() ) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir OUStringBuffer sKey = rPrefix; 384*cdf0e10cSrcweir sKey.append( rLocale.Language ); 385*cdf0e10cSrcweir if( rLocale.Country.getLength() ) 386*cdf0e10cSrcweir { 387*cdf0e10cSrcweir sKey.append( sal_Unicode('-') ); 388*cdf0e10cSrcweir sKey.append( rLocale.Country ); 389*cdf0e10cSrcweir } 390*cdf0e10cSrcweir if( rLocale.Variant.getLength() ) 391*cdf0e10cSrcweir { 392*cdf0e10cSrcweir sKey.append( sal_Unicode('-') ); 393*cdf0e10cSrcweir sKey.append( rLocale.Variant ); 394*cdf0e10cSrcweir } // if( aLocale.Variant.getLength() ) 395*cdf0e10cSrcweir ::rtl::OUString sURL = sKey.makeStringAndClear(); 396*cdf0e10cSrcweir sURL += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".res")); 397*cdf0e10cSrcweir if ( m_aResFiles.find(sURL) == m_aResFiles.end() ) 398*cdf0e10cSrcweir { 399*cdf0e10cSrcweir m_aResFiles[ sURL ].aFileURL = sURL; 400*cdf0e10cSrcweir return getResMgr(rPrefix,rLocale,bForceNewInstance); 401*cdf0e10cSrcweir } // if ( m_aResFiles.find(sURL) == m_aResFiles.end() ) 402*cdf0e10cSrcweir return NULL; 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir rLocale = aLocale; 406*cdf0e10cSrcweir // at this point it->second.pResMgr must be filled either by creating a new one 407*cdf0e10cSrcweir // (then the refcount is still 0) or because we already had one 408*cdf0e10cSrcweir InternalResMgr* pImp = it->second.pResMgr; 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir if( it->second.nRefCount == 0 ) 411*cdf0e10cSrcweir it->second.nLoadCount++; 412*cdf0e10cSrcweir 413*cdf0e10cSrcweir // for SimpleResMgr 414*cdf0e10cSrcweir if( bForceNewInstance ) 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir if( it->second.nRefCount == 0 ) 417*cdf0e10cSrcweir { 418*cdf0e10cSrcweir // shortcut: the match algorithm already created the InternalResMgr 419*cdf0e10cSrcweir // take it instead of creating yet another one 420*cdf0e10cSrcweir it->second.pResMgr = NULL; 421*cdf0e10cSrcweir pImp->bSingular = true; 422*cdf0e10cSrcweir } 423*cdf0e10cSrcweir else 424*cdf0e10cSrcweir { 425*cdf0e10cSrcweir pImp = new InternalResMgr( it->second.aFileURL, rPrefix, it->first, aLocale ); 426*cdf0e10cSrcweir pImp->bSingular = true; 427*cdf0e10cSrcweir if( !pImp->Create() ) 428*cdf0e10cSrcweir { 429*cdf0e10cSrcweir delete pImp; 430*cdf0e10cSrcweir pImp = NULL; 431*cdf0e10cSrcweir } 432*cdf0e10cSrcweir else 433*cdf0e10cSrcweir it->second.nLoadCount++; 434*cdf0e10cSrcweir } 435*cdf0e10cSrcweir } 436*cdf0e10cSrcweir else 437*cdf0e10cSrcweir it->second.nRefCount++; 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir return pImp; 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir InternalResMgr* ResMgrContainer::getNextFallback( InternalResMgr* pMgr ) 443*cdf0e10cSrcweir { 444*cdf0e10cSrcweir com::sun::star::lang::Locale aLocale = pMgr->aLocale; 445*cdf0e10cSrcweir if( aLocale.Variant.getLength() ) 446*cdf0e10cSrcweir aLocale.Variant = OUString(); 447*cdf0e10cSrcweir else if( aLocale.Country.getLength() ) 448*cdf0e10cSrcweir aLocale.Country = OUString(); 449*cdf0e10cSrcweir else if( ! aLocale.Language.equalsIgnoreAsciiCaseAscii( "en" ) ) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) ); 452*cdf0e10cSrcweir aLocale.Country = OUString( RTL_CONSTASCII_USTRINGPARAM( "US" ) ); 453*cdf0e10cSrcweir } 454*cdf0e10cSrcweir InternalResMgr* pNext = getResMgr( pMgr->aPrefix, aLocale, pMgr->bSingular ); 455*cdf0e10cSrcweir // prevent recursion 456*cdf0e10cSrcweir if( pNext == pMgr || pNext->aResName.equals( pMgr->aResName ) ) 457*cdf0e10cSrcweir { 458*cdf0e10cSrcweir if( pNext->bSingular ) 459*cdf0e10cSrcweir delete pNext; 460*cdf0e10cSrcweir pNext = NULL; 461*cdf0e10cSrcweir } 462*cdf0e10cSrcweir return pNext; 463*cdf0e10cSrcweir } 464*cdf0e10cSrcweir 465*cdf0e10cSrcweir void ResMgrContainer::freeResMgr( InternalResMgr* pResMgr ) 466*cdf0e10cSrcweir { 467*cdf0e10cSrcweir if( pResMgr->bSingular ) 468*cdf0e10cSrcweir delete pResMgr; 469*cdf0e10cSrcweir else 470*cdf0e10cSrcweir { 471*cdf0e10cSrcweir std::hash_map< OUString, ContainerElement, OUStringHash >::iterator it = 472*cdf0e10cSrcweir m_aResFiles.find( pResMgr->aResName ); 473*cdf0e10cSrcweir if( it != m_aResFiles.end() ) 474*cdf0e10cSrcweir { 475*cdf0e10cSrcweir DBG_ASSERT( it->second.nRefCount > 0, "InternalResMgr freed too often" ); 476*cdf0e10cSrcweir if( it->second.nRefCount > 0 ) 477*cdf0e10cSrcweir it->second.nRefCount--; 478*cdf0e10cSrcweir if( it->second.nRefCount == 0 ) 479*cdf0e10cSrcweir { 480*cdf0e10cSrcweir delete it->second.pResMgr; 481*cdf0e10cSrcweir it->second.pResMgr = NULL; 482*cdf0e10cSrcweir } 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir } 485*cdf0e10cSrcweir } 486*cdf0e10cSrcweir 487*cdf0e10cSrcweir // ======================================================================= 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir void Resource::TestRes() 490*cdf0e10cSrcweir { 491*cdf0e10cSrcweir if( m_pResMgr ) 492*cdf0e10cSrcweir m_pResMgr->TestStack( this ); 493*cdf0e10cSrcweir } 494*cdf0e10cSrcweir 495*cdf0e10cSrcweir struct ImpContent 496*cdf0e10cSrcweir { 497*cdf0e10cSrcweir sal_uInt64 nTypeAndId; 498*cdf0e10cSrcweir sal_uInt32 nOffset; 499*cdf0e10cSrcweir }; 500*cdf0e10cSrcweir 501*cdf0e10cSrcweir struct ImpContentLessCompare : public ::std::binary_function< ImpContent, ImpContent, bool> 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir inline bool operator() (const ImpContent& lhs, const ImpContent& rhs) const 504*cdf0e10cSrcweir { 505*cdf0e10cSrcweir return lhs.nTypeAndId < rhs.nTypeAndId; 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir }; 508*cdf0e10cSrcweir 509*cdf0e10cSrcweir struct ImpContentMixLessCompare : public ::std::binary_function< ImpContent, sal_uInt64, bool> 510*cdf0e10cSrcweir { 511*cdf0e10cSrcweir inline bool operator() (const ImpContent& lhs, const sal_uInt64& rhs) const 512*cdf0e10cSrcweir { 513*cdf0e10cSrcweir return lhs.nTypeAndId < rhs; 514*cdf0e10cSrcweir } 515*cdf0e10cSrcweir inline bool operator() (const sal_uInt64& lhs, const ImpContent& rhs) const 516*cdf0e10cSrcweir { 517*cdf0e10cSrcweir return lhs < rhs.nTypeAndId; 518*cdf0e10cSrcweir } 519*cdf0e10cSrcweir }; 520*cdf0e10cSrcweir 521*cdf0e10cSrcweir 522*cdf0e10cSrcweir // ======================================================================= 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir static ResHookProc pImplResHookProc = 0; 525*cdf0e10cSrcweir 526*cdf0e10cSrcweir // ======================================================================= 527*cdf0e10cSrcweir 528*cdf0e10cSrcweir SvStream * InternalResMgr::GetBitmapStream( sal_uInt32 nId ) 529*cdf0e10cSrcweir { 530*cdf0e10cSrcweir // Anfang der Strings suchen 531*cdf0e10cSrcweir ImpContent * pFind = ::std::lower_bound(pContent, 532*cdf0e10cSrcweir pContent + nEntries, 533*cdf0e10cSrcweir ((sal_uInt64(RT_SYS_BITMAP) << 32) | nId), 534*cdf0e10cSrcweir ImpContentMixLessCompare()); 535*cdf0e10cSrcweir if ( (pFind != (pContent + nEntries)) && (pFind->nTypeAndId == ((sal_uInt64(RT_SYS_BITMAP) << 32) | nId)) ) 536*cdf0e10cSrcweir { 537*cdf0e10cSrcweir pStm->Seek( pFind->nOffset ); 538*cdf0e10cSrcweir return pStm; 539*cdf0e10cSrcweir } 540*cdf0e10cSrcweir return NULL; 541*cdf0e10cSrcweir } 542*cdf0e10cSrcweir 543*cdf0e10cSrcweir // ----------------------------------------------------------------------- 544*cdf0e10cSrcweir 545*cdf0e10cSrcweir InternalResMgr::InternalResMgr( const OUString& rFileURL, 546*cdf0e10cSrcweir const OUString& rPrefix, 547*cdf0e10cSrcweir const OUString& rResName, 548*cdf0e10cSrcweir const com::sun::star::lang::Locale& rLocale ) 549*cdf0e10cSrcweir : pContent( NULL ) 550*cdf0e10cSrcweir , pStringBlock( NULL ) 551*cdf0e10cSrcweir , pStm( NULL ) 552*cdf0e10cSrcweir , bEqual2Content( sal_True ) 553*cdf0e10cSrcweir , nEntries( 0 ) 554*cdf0e10cSrcweir , aFileName( rFileURL ) 555*cdf0e10cSrcweir , aPrefix( rPrefix ) 556*cdf0e10cSrcweir , aResName( rResName ) 557*cdf0e10cSrcweir , bSingular( false ) 558*cdf0e10cSrcweir , aLocale( rLocale ) 559*cdf0e10cSrcweir , pResUseDump( 0 ) 560*cdf0e10cSrcweir { 561*cdf0e10cSrcweir } 562*cdf0e10cSrcweir 563*cdf0e10cSrcweir // ----------------------------------------------------------------------- 564*cdf0e10cSrcweir 565*cdf0e10cSrcweir InternalResMgr::~InternalResMgr() 566*cdf0e10cSrcweir { 567*cdf0e10cSrcweir rtl_freeMemory(pContent); 568*cdf0e10cSrcweir rtl_freeMemory(pStringBlock); 569*cdf0e10cSrcweir delete pStm; 570*cdf0e10cSrcweir 571*cdf0e10cSrcweir #ifdef DBG_UTIL 572*cdf0e10cSrcweir if( pResUseDump ) 573*cdf0e10cSrcweir { 574*cdf0e10cSrcweir const sal_Char* pLogFile = getenv( "STAR_RESOURCE_LOGGING" ); 575*cdf0e10cSrcweir if ( pLogFile ) 576*cdf0e10cSrcweir { 577*cdf0e10cSrcweir SvFileStream aStm( UniString( pLogFile, RTL_TEXTENCODING_ASCII_US ), STREAM_WRITE ); 578*cdf0e10cSrcweir aStm.Seek( STREAM_SEEK_TO_END ); 579*cdf0e10cSrcweir ByteString aLine( "FileName: " ); 580*cdf0e10cSrcweir aLine.Append( ByteString( OUStringToOString( aFileName, RTL_TEXTENCODING_UTF8 ) ) ); 581*cdf0e10cSrcweir aStm.WriteLine( aLine ); 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir for( std::hash_map<sal_uInt64, int>::const_iterator it = pResUseDump->begin(); 584*cdf0e10cSrcweir it != pResUseDump->end(); ++it ) 585*cdf0e10cSrcweir { 586*cdf0e10cSrcweir sal_uInt64 nKeyId = it->first; 587*cdf0e10cSrcweir aLine.Assign( "Type/Id: " ); 588*cdf0e10cSrcweir aLine.Append( ByteString::CreateFromInt32( sal::static_int_cast< sal_Int32 >((nKeyId >> 32) & 0xFFFFFFFF) ) ); 589*cdf0e10cSrcweir aLine.Append( '/' ); 590*cdf0e10cSrcweir aLine.Append( ByteString::CreateFromInt32( sal::static_int_cast< sal_Int32 >(nKeyId & 0xFFFFFFFF) ) ); 591*cdf0e10cSrcweir aStm.WriteLine( aLine ); 592*cdf0e10cSrcweir } 593*cdf0e10cSrcweir } 594*cdf0e10cSrcweir } 595*cdf0e10cSrcweir #endif 596*cdf0e10cSrcweir 597*cdf0e10cSrcweir delete pResUseDump; 598*cdf0e10cSrcweir } 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir // ----------------------------------------------------------------------- 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir 603*cdf0e10cSrcweir sal_Bool InternalResMgr::Create() 604*cdf0e10cSrcweir { 605*cdf0e10cSrcweir ResMgrContainer::get(); 606*cdf0e10cSrcweir sal_Bool bDone = sal_False; 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir pStm = new SvFileStream( aFileName, (STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE) ); 609*cdf0e10cSrcweir if( pStm->GetError() == 0 ) 610*cdf0e10cSrcweir { 611*cdf0e10cSrcweir sal_Int32 lContLen = 0; 612*cdf0e10cSrcweir 613*cdf0e10cSrcweir pStm->Seek( STREAM_SEEK_TO_END ); 614*cdf0e10cSrcweir /* 615*cdf0e10cSrcweir if( ( pInternalResMgr->pHead = (RSHEADER_TYPE *)mmap( 0, nResourceFileSize, 616*cdf0e10cSrcweir PROT_READ, MAP_PRIVATE, 617*cdf0e10cSrcweir fRes, 0 ) ) != (RSHEADER_TYPE *)-1) 618*cdf0e10cSrcweir */ 619*cdf0e10cSrcweir pStm->SeekRel( - (int)sizeof( lContLen ) ); 620*cdf0e10cSrcweir pStm->Read( &lContLen, sizeof( lContLen ) ); 621*cdf0e10cSrcweir // is bigendian, swab to the right endian 622*cdf0e10cSrcweir lContLen = ResMgr::GetLong( &lContLen ); 623*cdf0e10cSrcweir pStm->SeekRel( -lContLen ); 624*cdf0e10cSrcweir // allocate stored ImpContent data (12 bytes per unit) 625*cdf0e10cSrcweir sal_uInt8* pContentBuf = (sal_uInt8*)rtl_allocateMemory( lContLen ); 626*cdf0e10cSrcweir pStm->Read( pContentBuf, lContLen ); 627*cdf0e10cSrcweir // allocate ImpContent space (sizeof(ImpContent) per unit, not necessarily 12) 628*cdf0e10cSrcweir pContent = (ImpContent *)rtl_allocateMemory( sizeof(ImpContent)*lContLen/12 ); 629*cdf0e10cSrcweir // Auf die Anzahl der ImpContent k�rzen 630*cdf0e10cSrcweir nEntries = (sal_uInt32)lContLen / 12; 631*cdf0e10cSrcweir bEqual2Content = sal_True; // Die Daten der Resourcen liegen 632*cdf0e10cSrcweir // genauso wie das Inhaltsverzeichnis 633*cdf0e10cSrcweir sal_Bool bSorted = sal_True; 634*cdf0e10cSrcweir if( nEntries ) 635*cdf0e10cSrcweir { 636*cdf0e10cSrcweir #ifdef DBG_UTIL 637*cdf0e10cSrcweir const sal_Char* pLogFile = getenv( "STAR_RESOURCE_LOGGING" ); 638*cdf0e10cSrcweir if ( pLogFile ) 639*cdf0e10cSrcweir { 640*cdf0e10cSrcweir pResUseDump = new std::hash_map<sal_uInt64, int>; 641*cdf0e10cSrcweir for( sal_uInt32 i = 0; i < nEntries; ++i ) 642*cdf0e10cSrcweir (*pResUseDump)[pContent[i].nTypeAndId] = 1; 643*cdf0e10cSrcweir } 644*cdf0e10cSrcweir #endif 645*cdf0e10cSrcweir // swap the content to the right endian 646*cdf0e10cSrcweir pContent[0].nTypeAndId = ResMgr::GetUInt64( pContentBuf ); 647*cdf0e10cSrcweir pContent[0].nOffset = ResMgr::GetLong( pContentBuf+8 ); 648*cdf0e10cSrcweir sal_uInt32 nCount = nEntries - 1; 649*cdf0e10cSrcweir for( sal_uInt32 i = 0,j=1; i < nCount; ++i,++j ) 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir // swap the content to the right endian 652*cdf0e10cSrcweir pContent[j].nTypeAndId = ResMgr::GetUInt64( pContentBuf + (12*j) ); 653*cdf0e10cSrcweir pContent[j].nOffset = ResMgr::GetLong( pContentBuf + (12*j+8) ); 654*cdf0e10cSrcweir if( pContent[i].nTypeAndId >= pContent[j].nTypeAndId ) 655*cdf0e10cSrcweir bSorted = sal_False; 656*cdf0e10cSrcweir if( (pContent[i].nTypeAndId & 0xFFFFFFFF00000000LL) == (pContent[j].nTypeAndId & 0xFFFFFFFF00000000LL) 657*cdf0e10cSrcweir && pContent[i].nOffset >= pContent[j].nOffset ) 658*cdf0e10cSrcweir bEqual2Content = sal_False; 659*cdf0e10cSrcweir } 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir rtl_freeMemory( pContentBuf ); 662*cdf0e10cSrcweir #ifndef OS2 663*cdf0e10cSrcweir OSL_ENSURE( bSorted, "content not sorted" ); 664*cdf0e10cSrcweir #endif 665*cdf0e10cSrcweir OSL_ENSURE( bEqual2Content, "resource structure wrong" ); 666*cdf0e10cSrcweir if( !bSorted ) 667*cdf0e10cSrcweir ::std::sort(pContent,pContent+nEntries,ImpContentLessCompare()); 668*cdf0e10cSrcweir // qsort( pContent, nEntries, sizeof( ImpContent ), Compare ); 669*cdf0e10cSrcweir 670*cdf0e10cSrcweir bDone = sal_True; 671*cdf0e10cSrcweir } 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir return bDone; 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir // ----------------------------------------------------------------------- 677*cdf0e10cSrcweir 678*cdf0e10cSrcweir sal_Bool InternalResMgr::IsGlobalAvailable( RESOURCE_TYPE nRT, sal_uInt32 nId ) const 679*cdf0e10cSrcweir { 680*cdf0e10cSrcweir // Anfang der Strings suchen 681*cdf0e10cSrcweir sal_uInt64 nValue = ((sal_uInt64(nRT) << 32) | nId); 682*cdf0e10cSrcweir ImpContent * pFind = ::std::lower_bound(pContent, 683*cdf0e10cSrcweir pContent + nEntries, 684*cdf0e10cSrcweir nValue, 685*cdf0e10cSrcweir ImpContentMixLessCompare()); 686*cdf0e10cSrcweir return (pFind != (pContent + nEntries)) && (pFind->nTypeAndId == nValue); 687*cdf0e10cSrcweir } 688*cdf0e10cSrcweir 689*cdf0e10cSrcweir // ----------------------------------------------------------------------- 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir void* InternalResMgr::LoadGlobalRes( RESOURCE_TYPE nRT, sal_uInt32 nId, 692*cdf0e10cSrcweir void **pResHandle ) 693*cdf0e10cSrcweir { 694*cdf0e10cSrcweir #ifdef DBG_UTIL 695*cdf0e10cSrcweir if( pResUseDump ) 696*cdf0e10cSrcweir pResUseDump->erase( (sal_uInt64(nRT) << 32) | nId ); 697*cdf0e10cSrcweir #endif 698*cdf0e10cSrcweir // Anfang der Strings suchen 699*cdf0e10cSrcweir sal_uInt64 nValue = ((sal_uInt64(nRT) << 32) | nId); 700*cdf0e10cSrcweir ImpContent* pEnd = (pContent + nEntries); 701*cdf0e10cSrcweir ImpContent* pFind = ::std::lower_bound( pContent, 702*cdf0e10cSrcweir pEnd, 703*cdf0e10cSrcweir nValue, 704*cdf0e10cSrcweir ImpContentMixLessCompare()); 705*cdf0e10cSrcweir if( pFind && (pFind != pEnd) && (pFind->nTypeAndId == nValue) ) 706*cdf0e10cSrcweir { 707*cdf0e10cSrcweir if( nRT == RSC_STRING && bEqual2Content ) 708*cdf0e10cSrcweir { 709*cdf0e10cSrcweir // String Optimierung 710*cdf0e10cSrcweir if( !pStringBlock ) 711*cdf0e10cSrcweir { 712*cdf0e10cSrcweir // Anfang der Strings suchen 713*cdf0e10cSrcweir ImpContent * pFirst = pFind; 714*cdf0e10cSrcweir ImpContent * pLast = pFirst; 715*cdf0e10cSrcweir while( pFirst > pContent && ((pFirst -1)->nTypeAndId >> 32) == RSC_STRING ) 716*cdf0e10cSrcweir --pFirst; 717*cdf0e10cSrcweir while( pLast < pEnd && (pLast->nTypeAndId >> 32) == RSC_STRING ) 718*cdf0e10cSrcweir ++pLast; 719*cdf0e10cSrcweir nOffCorrection = pFirst->nOffset; 720*cdf0e10cSrcweir sal_uInt32 nSize; 721*cdf0e10cSrcweir --pLast; 722*cdf0e10cSrcweir pStm->Seek( pLast->nOffset ); 723*cdf0e10cSrcweir RSHEADER_TYPE aHdr; 724*cdf0e10cSrcweir pStm->Read( &aHdr, sizeof( aHdr ) ); 725*cdf0e10cSrcweir nSize = pLast->nOffset + aHdr.GetGlobOff() - nOffCorrection; 726*cdf0e10cSrcweir pStringBlock = (sal_uInt8*)rtl_allocateMemory( nSize ); 727*cdf0e10cSrcweir pStm->Seek( pFirst->nOffset ); 728*cdf0e10cSrcweir pStm->Read( pStringBlock, nSize ); 729*cdf0e10cSrcweir } 730*cdf0e10cSrcweir *pResHandle = pStringBlock; 731*cdf0e10cSrcweir return (sal_uInt8*)pStringBlock + pFind->nOffset - nOffCorrection; 732*cdf0e10cSrcweir } // if( nRT == RSC_STRING && bEqual2Content ) 733*cdf0e10cSrcweir else 734*cdf0e10cSrcweir { 735*cdf0e10cSrcweir *pResHandle = 0; 736*cdf0e10cSrcweir RSHEADER_TYPE aHeader; 737*cdf0e10cSrcweir pStm->Seek( pFind->nOffset ); 738*cdf0e10cSrcweir pStm->Read( &aHeader, sizeof( RSHEADER_TYPE ) ); 739*cdf0e10cSrcweir void * pRes = rtl_allocateMemory( aHeader.GetGlobOff() ); 740*cdf0e10cSrcweir memcpy( pRes, &aHeader, sizeof( RSHEADER_TYPE ) ); 741*cdf0e10cSrcweir pStm->Read( (sal_uInt8*)pRes + sizeof( RSHEADER_TYPE ), 742*cdf0e10cSrcweir aHeader.GetGlobOff() - sizeof( RSHEADER_TYPE ) ); 743*cdf0e10cSrcweir return pRes; 744*cdf0e10cSrcweir } 745*cdf0e10cSrcweir } // if( pFind && (pFind != pEnd) && (pFind->nTypeAndId == nValue) ) 746*cdf0e10cSrcweir *pResHandle = 0; 747*cdf0e10cSrcweir //Resource holen 748*cdf0e10cSrcweir return NULL; 749*cdf0e10cSrcweir } 750*cdf0e10cSrcweir 751*cdf0e10cSrcweir // ----------------------------------------------------------------------- 752*cdf0e10cSrcweir 753*cdf0e10cSrcweir void InternalResMgr::FreeGlobalRes( void * pResHandle, void * pResource ) 754*cdf0e10cSrcweir { 755*cdf0e10cSrcweir if ( !pResHandle ) 756*cdf0e10cSrcweir // REsource wurde extra allokiert 757*cdf0e10cSrcweir rtl_freeMemory(pResource); 758*cdf0e10cSrcweir } 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir // ======================================================================= 761*cdf0e10cSrcweir 762*cdf0e10cSrcweir #ifdef DBG_UTIL 763*cdf0e10cSrcweir 764*cdf0e10cSrcweir UniString GetTypeRes_Impl( const ResId& rTypeId ) 765*cdf0e10cSrcweir { 766*cdf0e10cSrcweir // Funktion verlassen, falls Resourcefehler in dieser Funktion 767*cdf0e10cSrcweir static int bInUse = sal_False; 768*cdf0e10cSrcweir UniString aTypStr( UniString::CreateFromInt32( rTypeId.GetId() ) ); 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir if ( !bInUse ) 771*cdf0e10cSrcweir { 772*cdf0e10cSrcweir bInUse = sal_True; 773*cdf0e10cSrcweir 774*cdf0e10cSrcweir ResId aResId( sal_uInt32(RSCVERSION_ID), *rTypeId.GetResMgr() ); 775*cdf0e10cSrcweir aResId.SetRT( RSC_VERSIONCONTROL ); 776*cdf0e10cSrcweir 777*cdf0e10cSrcweir if ( rTypeId.GetResMgr()->GetResource( aResId ) ) 778*cdf0e10cSrcweir { 779*cdf0e10cSrcweir rTypeId.SetRT( RSC_STRING ); 780*cdf0e10cSrcweir if ( rTypeId.GetResMgr()->IsAvailable( rTypeId ) ) 781*cdf0e10cSrcweir { 782*cdf0e10cSrcweir aTypStr = UniString( rTypeId ); 783*cdf0e10cSrcweir // Versions Resource Klassenzeiger ans Ende setzen 784*cdf0e10cSrcweir rTypeId.GetResMgr()->Increment( sizeof( RSHEADER_TYPE ) ); 785*cdf0e10cSrcweir } 786*cdf0e10cSrcweir } 787*cdf0e10cSrcweir bInUse = sal_False; 788*cdf0e10cSrcweir } 789*cdf0e10cSrcweir 790*cdf0e10cSrcweir return aTypStr; 791*cdf0e10cSrcweir } 792*cdf0e10cSrcweir 793*cdf0e10cSrcweir // ----------------------------------------------------------------------- 794*cdf0e10cSrcweir 795*cdf0e10cSrcweir void ResMgr::RscError_Impl( const sal_Char* pMessage, ResMgr* pResMgr, 796*cdf0e10cSrcweir RESOURCE_TYPE nRT, sal_uInt32 nId, 797*cdf0e10cSrcweir std::vector< ImpRCStack >& rResStack, int nDepth ) 798*cdf0e10cSrcweir { 799*cdf0e10cSrcweir // create a separate ResMgr with its own stack 800*cdf0e10cSrcweir // first get a second reference of the InternalResMgr 801*cdf0e10cSrcweir InternalResMgr* pImp = 802*cdf0e10cSrcweir ResMgrContainer::get().getResMgr( pResMgr->pImpRes->aPrefix, 803*cdf0e10cSrcweir pResMgr->pImpRes->aLocale, 804*cdf0e10cSrcweir true ); 805*cdf0e10cSrcweir 806*cdf0e10cSrcweir ResMgr* pNewResMgr = new ResMgr( pImp ); 807*cdf0e10cSrcweir 808*cdf0e10cSrcweir ByteString aStr = OUStringToOString( pResMgr->GetFileName(), RTL_TEXTENCODING_UTF8 ); 809*cdf0e10cSrcweir if ( aStr.Len() ) 810*cdf0e10cSrcweir aStr += '\n'; 811*cdf0e10cSrcweir 812*cdf0e10cSrcweir aStr.Append( "Class: " ); 813*cdf0e10cSrcweir aStr.Append( ByteString( GetTypeRes_Impl( ResId( nRT, *pNewResMgr ) ), RTL_TEXTENCODING_UTF8 ) ); 814*cdf0e10cSrcweir aStr.Append( ", Id: " ); 815*cdf0e10cSrcweir aStr.Append( ByteString::CreateFromInt32( (long)nId ) ); 816*cdf0e10cSrcweir aStr.Append( ". " ); 817*cdf0e10cSrcweir aStr.Append( pMessage ); 818*cdf0e10cSrcweir 819*cdf0e10cSrcweir aStr.Append( "\nResource Stack\n" ); 820*cdf0e10cSrcweir while( nDepth > 0 ) 821*cdf0e10cSrcweir { 822*cdf0e10cSrcweir aStr.Append( "Class: " ); 823*cdf0e10cSrcweir aStr.Append( ByteString( GetTypeRes_Impl( ResId( rResStack[nDepth].pResource->GetRT(), *pNewResMgr ) ), RTL_TEXTENCODING_UTF8 ) ); 824*cdf0e10cSrcweir aStr.Append( ", Id: " ); 825*cdf0e10cSrcweir aStr.Append( ByteString::CreateFromInt32( (long)rResStack[nDepth].pResource->GetId() ) ); 826*cdf0e10cSrcweir nDepth--; 827*cdf0e10cSrcweir } 828*cdf0e10cSrcweir 829*cdf0e10cSrcweir // clean up 830*cdf0e10cSrcweir delete pNewResMgr; 831*cdf0e10cSrcweir 832*cdf0e10cSrcweir DBG_ERROR( aStr.GetBuffer() ); 833*cdf0e10cSrcweir } 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir #endif 836*cdf0e10cSrcweir 837*cdf0e10cSrcweir // ======================================================================= 838*cdf0e10cSrcweir 839*cdf0e10cSrcweir static void RscException_Impl() 840*cdf0e10cSrcweir { 841*cdf0e10cSrcweir switch ( vos::OSignalHandler::raise( OSL_SIGNAL_USER_RESOURCEFAILURE, (void*)"" ) ) 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir case vos::OSignalHandler::TAction_CallNextHandler: 844*cdf0e10cSrcweir abort(); 845*cdf0e10cSrcweir 846*cdf0e10cSrcweir case vos::OSignalHandler::TAction_Ignore: 847*cdf0e10cSrcweir return; 848*cdf0e10cSrcweir 849*cdf0e10cSrcweir case vos::OSignalHandler::TAction_AbortApplication: 850*cdf0e10cSrcweir abort(); 851*cdf0e10cSrcweir 852*cdf0e10cSrcweir case vos::OSignalHandler::TAction_KillApplication: 853*cdf0e10cSrcweir exit(-1); 854*cdf0e10cSrcweir } 855*cdf0e10cSrcweir } 856*cdf0e10cSrcweir 857*cdf0e10cSrcweir // ======================================================================= 858*cdf0e10cSrcweir 859*cdf0e10cSrcweir void ImpRCStack::Init( ResMgr* pMgr, const Resource* pObj, sal_uInt32 Id ) 860*cdf0e10cSrcweir { 861*cdf0e10cSrcweir pResource = NULL; 862*cdf0e10cSrcweir pClassRes = NULL; 863*cdf0e10cSrcweir Flags = RC_NOTYPE; 864*cdf0e10cSrcweir aResHandle = NULL; 865*cdf0e10cSrcweir pResObj = pObj; 866*cdf0e10cSrcweir nId = Id & ~RSC_DONTRELEASE; //TLX: Besser Init aendern 867*cdf0e10cSrcweir pResMgr = pMgr; 868*cdf0e10cSrcweir if ( !(Id & RSC_DONTRELEASE) ) 869*cdf0e10cSrcweir Flags |= RC_AUTORELEASE; 870*cdf0e10cSrcweir } 871*cdf0e10cSrcweir 872*cdf0e10cSrcweir // ----------------------------------------------------------------------- 873*cdf0e10cSrcweir 874*cdf0e10cSrcweir void ImpRCStack::Clear() 875*cdf0e10cSrcweir { 876*cdf0e10cSrcweir pResource = NULL; 877*cdf0e10cSrcweir pClassRes = NULL; 878*cdf0e10cSrcweir Flags = RC_NOTYPE; 879*cdf0e10cSrcweir aResHandle = NULL; 880*cdf0e10cSrcweir pResObj = NULL; 881*cdf0e10cSrcweir nId = 0; 882*cdf0e10cSrcweir pResMgr = NULL; 883*cdf0e10cSrcweir } 884*cdf0e10cSrcweir 885*cdf0e10cSrcweir // ----------------------------------------------------------------------- 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir static RSHEADER_TYPE* LocalResource( const ImpRCStack* pStack, 888*cdf0e10cSrcweir RESOURCE_TYPE nRTType, 889*cdf0e10cSrcweir sal_uInt32 nId ) 890*cdf0e10cSrcweir { 891*cdf0e10cSrcweir // Gibt die Position der Resource zurueck, wenn sie gefunden wurde. 892*cdf0e10cSrcweir // Ansonsten gibt die Funktion Null zurueck. 893*cdf0e10cSrcweir RSHEADER_TYPE* pTmp; // Zeiger auf Kind-Resourceobjekte 894*cdf0e10cSrcweir RSHEADER_TYPE* pEnd; // Zeiger auf das Ende der Resource 895*cdf0e10cSrcweir 896*cdf0e10cSrcweir if ( pStack->pResource && pStack->pClassRes ) 897*cdf0e10cSrcweir { 898*cdf0e10cSrcweir pTmp = (RSHEADER_TYPE*) 899*cdf0e10cSrcweir ((sal_uInt8*)pStack->pResource + pStack->pResource->GetLocalOff()); 900*cdf0e10cSrcweir pEnd = (RSHEADER_TYPE*) 901*cdf0e10cSrcweir ((sal_uInt8*)pStack->pResource + pStack->pResource->GetGlobOff()); 902*cdf0e10cSrcweir while ( pTmp != pEnd ) 903*cdf0e10cSrcweir { 904*cdf0e10cSrcweir if ( pTmp->GetRT() == nRTType && pTmp->GetId() == nId ) 905*cdf0e10cSrcweir return pTmp; 906*cdf0e10cSrcweir pTmp = (RSHEADER_TYPE*)((sal_uInt8*)pTmp + pTmp->GetGlobOff()); 907*cdf0e10cSrcweir } 908*cdf0e10cSrcweir } 909*cdf0e10cSrcweir 910*cdf0e10cSrcweir return NULL; 911*cdf0e10cSrcweir } 912*cdf0e10cSrcweir 913*cdf0e10cSrcweir // ======================================================================= 914*cdf0e10cSrcweir 915*cdf0e10cSrcweir void* ResMgr::pEmptyBuffer = NULL; 916*cdf0e10cSrcweir 917*cdf0e10cSrcweir void* ResMgr::getEmptyBuffer() 918*cdf0e10cSrcweir { 919*cdf0e10cSrcweir if( ! pEmptyBuffer ) 920*cdf0e10cSrcweir pEmptyBuffer = rtl_allocateZeroMemory( 1024 ); 921*cdf0e10cSrcweir return pEmptyBuffer; 922*cdf0e10cSrcweir } 923*cdf0e10cSrcweir 924*cdf0e10cSrcweir void ResMgr::DestroyAllResMgr() 925*cdf0e10cSrcweir { 926*cdf0e10cSrcweir { 927*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 928*cdf0e10cSrcweir if( pEmptyBuffer ) 929*cdf0e10cSrcweir { 930*cdf0e10cSrcweir rtl_freeMemory( pEmptyBuffer ); 931*cdf0e10cSrcweir pEmptyBuffer = NULL; 932*cdf0e10cSrcweir } 933*cdf0e10cSrcweir ResMgrContainer::release(); 934*cdf0e10cSrcweir } 935*cdf0e10cSrcweir delete pResMgrMutex; 936*cdf0e10cSrcweir pResMgrMutex = NULL; 937*cdf0e10cSrcweir } 938*cdf0e10cSrcweir 939*cdf0e10cSrcweir // ----------------------------------------------------------------------- 940*cdf0e10cSrcweir 941*cdf0e10cSrcweir void ResMgr::Init( const OUString& rFileName ) 942*cdf0e10cSrcweir { 943*cdf0e10cSrcweir (void) rFileName; // avoid warning about unused parameter 944*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 945*cdf0e10cSrcweir 946*cdf0e10cSrcweir if ( !pImpRes ) 947*cdf0e10cSrcweir { 948*cdf0e10cSrcweir #ifdef DBG_UTIL 949*cdf0e10cSrcweir ByteString aStr( "Resourcefile not found:\n" ); 950*cdf0e10cSrcweir aStr += ByteString( OUStringToOString( rFileName, RTL_TEXTENCODING_UTF8 ) ); 951*cdf0e10cSrcweir DBG_ERROR( aStr.GetBuffer() ); 952*cdf0e10cSrcweir #endif 953*cdf0e10cSrcweir RscException_Impl(); 954*cdf0e10cSrcweir } 955*cdf0e10cSrcweir #ifdef DBG_UTIL 956*cdf0e10cSrcweir else 957*cdf0e10cSrcweir { 958*cdf0e10cSrcweir void* aResHandle = 0; // Hilfvariable fuer Resource 959*cdf0e10cSrcweir void* pVoid; // Zeiger auf die Resource 960*cdf0e10cSrcweir 961*cdf0e10cSrcweir pVoid = pImpRes->LoadGlobalRes( RSC_VERSIONCONTROL, RSCVERSION_ID, 962*cdf0e10cSrcweir &aResHandle ); 963*cdf0e10cSrcweir if ( pVoid ) 964*cdf0e10cSrcweir pImpRes->FreeGlobalRes( aResHandle, pVoid ); 965*cdf0e10cSrcweir else 966*cdf0e10cSrcweir { 967*cdf0e10cSrcweir ByteString aStr( "Wrong version:\n" ); 968*cdf0e10cSrcweir aStr += ByteString( OUStringToOString( pImpRes->aFileName, RTL_TEXTENCODING_UTF8 ) ); 969*cdf0e10cSrcweir DbgError( aStr.GetBuffer() ); 970*cdf0e10cSrcweir } 971*cdf0e10cSrcweir } 972*cdf0e10cSrcweir #endif 973*cdf0e10cSrcweir nCurStack = -1; 974*cdf0e10cSrcweir aStack.clear(); 975*cdf0e10cSrcweir pFallbackResMgr = pOriginalResMgr = NULL; 976*cdf0e10cSrcweir incStack(); 977*cdf0e10cSrcweir } 978*cdf0e10cSrcweir 979*cdf0e10cSrcweir // ----------------------------------------------------------------------- 980*cdf0e10cSrcweir 981*cdf0e10cSrcweir ResMgr::ResMgr( InternalResMgr * pImpMgr ) 982*cdf0e10cSrcweir { 983*cdf0e10cSrcweir pImpRes = pImpMgr; 984*cdf0e10cSrcweir Init( pImpMgr->aFileName ); 985*cdf0e10cSrcweir } 986*cdf0e10cSrcweir 987*cdf0e10cSrcweir // ----------------------------------------------------------------------- 988*cdf0e10cSrcweir 989*cdf0e10cSrcweir ResMgr::~ResMgr() 990*cdf0e10cSrcweir { 991*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 992*cdf0e10cSrcweir 993*cdf0e10cSrcweir ResMgrContainer::get().freeResMgr( pImpRes ); 994*cdf0e10cSrcweir 995*cdf0e10cSrcweir // clean up possible left rc stack frames 996*cdf0e10cSrcweir while( nCurStack > 0 ) 997*cdf0e10cSrcweir { 998*cdf0e10cSrcweir if( ( aStack[nCurStack].Flags & (RC_GLOBAL | RC_NOTFOUND) ) == RC_GLOBAL ) 999*cdf0e10cSrcweir pImpRes->FreeGlobalRes( aStack[nCurStack].aResHandle, 1000*cdf0e10cSrcweir aStack[nCurStack].pResource ); 1001*cdf0e10cSrcweir nCurStack--; 1002*cdf0e10cSrcweir } 1003*cdf0e10cSrcweir } 1004*cdf0e10cSrcweir 1005*cdf0e10cSrcweir 1006*cdf0e10cSrcweir void ResMgr::incStack() 1007*cdf0e10cSrcweir { 1008*cdf0e10cSrcweir nCurStack++; 1009*cdf0e10cSrcweir if( nCurStack >= int(aStack.size()) ) 1010*cdf0e10cSrcweir aStack.push_back( ImpRCStack() ); 1011*cdf0e10cSrcweir aStack[nCurStack].Clear(); 1012*cdf0e10cSrcweir 1013*cdf0e10cSrcweir DBG_ASSERT( nCurStack < 32, "Resource stack unreasonably large" ); 1014*cdf0e10cSrcweir } 1015*cdf0e10cSrcweir 1016*cdf0e10cSrcweir void ResMgr::decStack() 1017*cdf0e10cSrcweir { 1018*cdf0e10cSrcweir DBG_ASSERT( nCurStack > 0, "resource stack underrun !" ); 1019*cdf0e10cSrcweir if( (aStack[nCurStack].Flags & RC_FALLBACK_UP) ) 1020*cdf0e10cSrcweir { 1021*cdf0e10cSrcweir nCurStack--; 1022*cdf0e10cSrcweir // warning: this will delete *this, see below 1023*cdf0e10cSrcweir pOriginalResMgr->decStack(); 1024*cdf0e10cSrcweir } 1025*cdf0e10cSrcweir else 1026*cdf0e10cSrcweir { 1027*cdf0e10cSrcweir ImpRCStack& rTop = aStack[nCurStack]; 1028*cdf0e10cSrcweir if( (rTop.Flags & RC_FALLBACK_DOWN) ) 1029*cdf0e10cSrcweir { 1030*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1 1031*cdf0e10cSrcweir OSL_TRACE( "returning from fallback %s\n", 1032*cdf0e10cSrcweir OUStringToOString(pFallbackResMgr->GetFileName(), osl_getThreadTextEncoding() ).getStr() ); 1033*cdf0e10cSrcweir #endif 1034*cdf0e10cSrcweir delete pFallbackResMgr; 1035*cdf0e10cSrcweir pFallbackResMgr = NULL; 1036*cdf0e10cSrcweir } 1037*cdf0e10cSrcweir nCurStack--; 1038*cdf0e10cSrcweir } 1039*cdf0e10cSrcweir } 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir #ifdef DBG_UTIL 1042*cdf0e10cSrcweir 1043*cdf0e10cSrcweir void ResMgr::TestStack( const Resource* pResObj ) 1044*cdf0e10cSrcweir { 1045*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1046*cdf0e10cSrcweir 1047*cdf0e10cSrcweir if ( DbgIsResource() ) 1048*cdf0e10cSrcweir { 1049*cdf0e10cSrcweir for( int i = 1; i <= nCurStack; ++i ) 1050*cdf0e10cSrcweir { 1051*cdf0e10cSrcweir if ( aStack[i].pResObj == pResObj ) 1052*cdf0e10cSrcweir { 1053*cdf0e10cSrcweir #ifdef DBG_UTIL 1054*cdf0e10cSrcweir RscError_Impl( "Resource not freed! ", this, 1055*cdf0e10cSrcweir aStack[i].pResource->GetRT(), 1056*cdf0e10cSrcweir aStack[i].pResource->GetId(), 1057*cdf0e10cSrcweir aStack, i-1 ); 1058*cdf0e10cSrcweir #endif 1059*cdf0e10cSrcweir } 1060*cdf0e10cSrcweir } 1061*cdf0e10cSrcweir } 1062*cdf0e10cSrcweir } 1063*cdf0e10cSrcweir 1064*cdf0e10cSrcweir #else 1065*cdf0e10cSrcweir 1066*cdf0e10cSrcweir void ResMgr::TestStack( const Resource* ) 1067*cdf0e10cSrcweir { 1068*cdf0e10cSrcweir } 1069*cdf0e10cSrcweir 1070*cdf0e10cSrcweir #endif 1071*cdf0e10cSrcweir 1072*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1073*cdf0e10cSrcweir sal_Bool ResMgr::IsAvailable( const ResId& rId, const Resource* pResObj ) const 1074*cdf0e10cSrcweir { 1075*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1076*cdf0e10cSrcweir 1077*cdf0e10cSrcweir sal_Bool bAvailable = sal_False; 1078*cdf0e10cSrcweir RSHEADER_TYPE* pClassRes = rId.GetpResource(); 1079*cdf0e10cSrcweir RESOURCE_TYPE nRT = rId.GetRT2(); 1080*cdf0e10cSrcweir sal_uInt32 nId = rId.GetId(); 1081*cdf0e10cSrcweir const ResMgr* pMgr = rId.GetResMgr(); 1082*cdf0e10cSrcweir 1083*cdf0e10cSrcweir if ( !pMgr ) 1084*cdf0e10cSrcweir pMgr = this; 1085*cdf0e10cSrcweir 1086*cdf0e10cSrcweir if( pMgr->pFallbackResMgr ) 1087*cdf0e10cSrcweir { 1088*cdf0e10cSrcweir ResId aId( rId ); 1089*cdf0e10cSrcweir aId.SetResMgr( NULL ); 1090*cdf0e10cSrcweir return pMgr->pFallbackResMgr->IsAvailable( aId, pResObj ); 1091*cdf0e10cSrcweir } 1092*cdf0e10cSrcweir 1093*cdf0e10cSrcweir if ( !pResObj || pResObj == pMgr->aStack[pMgr->nCurStack].pResObj ) 1094*cdf0e10cSrcweir { 1095*cdf0e10cSrcweir if ( !pClassRes ) 1096*cdf0e10cSrcweir pClassRes = LocalResource( &pMgr->aStack[pMgr->nCurStack], nRT, nId ); 1097*cdf0e10cSrcweir if ( pClassRes ) 1098*cdf0e10cSrcweir { 1099*cdf0e10cSrcweir if ( pClassRes->GetRT() == nRT ) 1100*cdf0e10cSrcweir bAvailable = sal_True; 1101*cdf0e10cSrcweir } 1102*cdf0e10cSrcweir } 1103*cdf0e10cSrcweir 1104*cdf0e10cSrcweir // vieleicht globale Resource 1105*cdf0e10cSrcweir if ( !pClassRes ) 1106*cdf0e10cSrcweir bAvailable = pMgr->pImpRes->IsGlobalAvailable( nRT, nId ); 1107*cdf0e10cSrcweir 1108*cdf0e10cSrcweir return bAvailable; 1109*cdf0e10cSrcweir } 1110*cdf0e10cSrcweir 1111*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1112*cdf0e10cSrcweir 1113*cdf0e10cSrcweir void* ResMgr::GetClass() 1114*cdf0e10cSrcweir { 1115*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1116*cdf0e10cSrcweir 1117*cdf0e10cSrcweir if( pFallbackResMgr ) 1118*cdf0e10cSrcweir return pFallbackResMgr->GetClass(); 1119*cdf0e10cSrcweir 1120*cdf0e10cSrcweir return aStack[nCurStack].pClassRes; 1121*cdf0e10cSrcweir } 1122*cdf0e10cSrcweir 1123*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1124*cdf0e10cSrcweir 1125*cdf0e10cSrcweir sal_Bool ResMgr::GetResource( const ResId& rId, const Resource* pResObj ) 1126*cdf0e10cSrcweir { 1127*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1128*cdf0e10cSrcweir 1129*cdf0e10cSrcweir if( pFallbackResMgr ) 1130*cdf0e10cSrcweir { 1131*cdf0e10cSrcweir ResId aId( rId ); 1132*cdf0e10cSrcweir aId.SetResMgr( NULL ); 1133*cdf0e10cSrcweir return pFallbackResMgr->GetResource( aId, pResObj ); 1134*cdf0e10cSrcweir } 1135*cdf0e10cSrcweir 1136*cdf0e10cSrcweir ResMgr* pMgr = rId.GetResMgr(); 1137*cdf0e10cSrcweir if ( pMgr && (this != pMgr) ) 1138*cdf0e10cSrcweir return pMgr->GetResource( rId, pResObj ); 1139*cdf0e10cSrcweir 1140*cdf0e10cSrcweir // normally Increment will pop the context; this is 1141*cdf0e10cSrcweir // not possible in RC_NOTFOUND case, so pop a frame here 1142*cdf0e10cSrcweir ImpRCStack* pTop = &aStack[nCurStack]; 1143*cdf0e10cSrcweir if( (pTop->Flags & RC_NOTFOUND) ) 1144*cdf0e10cSrcweir { 1145*cdf0e10cSrcweir decStack(); 1146*cdf0e10cSrcweir } 1147*cdf0e10cSrcweir 1148*cdf0e10cSrcweir RSHEADER_TYPE* pClassRes = rId.GetpResource(); 1149*cdf0e10cSrcweir RESOURCE_TYPE nRT = rId.GetRT2(); 1150*cdf0e10cSrcweir sal_uInt32 nId = rId.GetId(); 1151*cdf0e10cSrcweir 1152*cdf0e10cSrcweir incStack(); 1153*cdf0e10cSrcweir pTop = &aStack[nCurStack]; 1154*cdf0e10cSrcweir pTop->Init( pMgr, pResObj, nId | 1155*cdf0e10cSrcweir (rId.IsAutoRelease() ? 0 : RSC_DONTRELEASE) ); 1156*cdf0e10cSrcweir 1157*cdf0e10cSrcweir if ( pClassRes ) 1158*cdf0e10cSrcweir { 1159*cdf0e10cSrcweir if ( pClassRes->GetRT() == nRT ) 1160*cdf0e10cSrcweir pTop->pClassRes = pClassRes; 1161*cdf0e10cSrcweir else 1162*cdf0e10cSrcweir { 1163*cdf0e10cSrcweir #ifdef DBG_UTIL 1164*cdf0e10cSrcweir RscError_Impl( "Different class and resource type!", 1165*cdf0e10cSrcweir this, nRT, nId, aStack, nCurStack-1 ); 1166*cdf0e10cSrcweir #endif 1167*cdf0e10cSrcweir pTop->Flags |= RC_NOTFOUND; 1168*cdf0e10cSrcweir pTop->pClassRes = getEmptyBuffer(); 1169*cdf0e10cSrcweir pTop->pResource = (RSHEADER_TYPE*)pTop->pClassRes; 1170*cdf0e10cSrcweir return sal_False; 1171*cdf0e10cSrcweir } 1172*cdf0e10cSrcweir } 1173*cdf0e10cSrcweir else 1174*cdf0e10cSrcweir { 1175*cdf0e10cSrcweir OSL_ENSURE( nCurStack > 0, "stack of 1 to shallow" ); 1176*cdf0e10cSrcweir pTop->pClassRes = LocalResource( &aStack[nCurStack-1], nRT, nId ); 1177*cdf0e10cSrcweir } 1178*cdf0e10cSrcweir 1179*cdf0e10cSrcweir if ( pTop->pClassRes ) 1180*cdf0e10cSrcweir // lokale Resource, nicht system Resource 1181*cdf0e10cSrcweir pTop->pResource = (RSHEADER_TYPE *)pTop->pClassRes; 1182*cdf0e10cSrcweir else 1183*cdf0e10cSrcweir { 1184*cdf0e10cSrcweir pTop->pClassRes = pImpRes->LoadGlobalRes( nRT, nId, &pTop->aResHandle ); 1185*cdf0e10cSrcweir if ( pTop->pClassRes ) 1186*cdf0e10cSrcweir { 1187*cdf0e10cSrcweir pTop->Flags |= RC_GLOBAL; 1188*cdf0e10cSrcweir pTop->pResource = (RSHEADER_TYPE *)pTop->pClassRes; 1189*cdf0e10cSrcweir } 1190*cdf0e10cSrcweir else 1191*cdf0e10cSrcweir { 1192*cdf0e10cSrcweir // try to get a fallback resource 1193*cdf0e10cSrcweir pFallbackResMgr = CreateFallbackResMgr( rId, pResObj ); 1194*cdf0e10cSrcweir if( pFallbackResMgr ) 1195*cdf0e10cSrcweir { 1196*cdf0e10cSrcweir pTop->Flags |= RC_FALLBACK_DOWN; 1197*cdf0e10cSrcweir #ifdef DBG_UTIL 1198*cdf0e10cSrcweir ByteString aMess( "found resource " ); 1199*cdf0e10cSrcweir aMess.Append( ByteString::CreateFromInt32( nId ) ); 1200*cdf0e10cSrcweir aMess.Append( " in fallback " ); 1201*cdf0e10cSrcweir aMess.Append( ByteString( OUStringToOString( pFallbackResMgr->GetFileName(), osl_getThreadTextEncoding() ) ) ); 1202*cdf0e10cSrcweir aMess.Append( "\n" ); 1203*cdf0e10cSrcweir RscError_Impl( aMess.GetBuffer(), 1204*cdf0e10cSrcweir this, nRT, nId, aStack, nCurStack-1 ); 1205*cdf0e10cSrcweir #endif 1206*cdf0e10cSrcweir } 1207*cdf0e10cSrcweir else 1208*cdf0e10cSrcweir { 1209*cdf0e10cSrcweir #ifdef DBG_UTIL 1210*cdf0e10cSrcweir RscError_Impl( "Cannot load resource! ", 1211*cdf0e10cSrcweir this, nRT, nId, aStack, nCurStack-1 ); 1212*cdf0e10cSrcweir #endif 1213*cdf0e10cSrcweir pTop->Flags |= RC_NOTFOUND; 1214*cdf0e10cSrcweir pTop->pClassRes = getEmptyBuffer(); 1215*cdf0e10cSrcweir pTop->pResource = (RSHEADER_TYPE*)pTop->pClassRes; 1216*cdf0e10cSrcweir return sal_False; 1217*cdf0e10cSrcweir } 1218*cdf0e10cSrcweir } 1219*cdf0e10cSrcweir } 1220*cdf0e10cSrcweir 1221*cdf0e10cSrcweir return sal_True; 1222*cdf0e10cSrcweir } 1223*cdf0e10cSrcweir 1224*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1225*cdf0e10cSrcweir 1226*cdf0e10cSrcweir void * ResMgr::GetResourceSkipHeader( const ResId& rResId, ResMgr ** ppResMgr ) 1227*cdf0e10cSrcweir { 1228*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1229*cdf0e10cSrcweir 1230*cdf0e10cSrcweir DBG_ASSERT( rResId.GetResMgr(), "illegal ResId without ResMgr" ); 1231*cdf0e10cSrcweir *ppResMgr = rResId.GetResMgr(); 1232*cdf0e10cSrcweir if( *ppResMgr ) 1233*cdf0e10cSrcweir { 1234*cdf0e10cSrcweir (*ppResMgr)->GetResource( rResId ); 1235*cdf0e10cSrcweir (*ppResMgr)->Increment( sizeof( RSHEADER_TYPE ) ); 1236*cdf0e10cSrcweir return (*ppResMgr)->GetClass(); 1237*cdf0e10cSrcweir } 1238*cdf0e10cSrcweir return getEmptyBuffer(); 1239*cdf0e10cSrcweir } 1240*cdf0e10cSrcweir 1241*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1242*cdf0e10cSrcweir 1243*cdf0e10cSrcweir void ResMgr::PopContext( const Resource* pResObj ) 1244*cdf0e10cSrcweir { 1245*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1246*cdf0e10cSrcweir 1247*cdf0e10cSrcweir if( pFallbackResMgr ) 1248*cdf0e10cSrcweir { 1249*cdf0e10cSrcweir pFallbackResMgr->PopContext( pResObj ); 1250*cdf0e10cSrcweir return; 1251*cdf0e10cSrcweir } 1252*cdf0e10cSrcweir 1253*cdf0e10cSrcweir #ifdef DBG_UTIL 1254*cdf0e10cSrcweir if ( DbgIsResource() ) 1255*cdf0e10cSrcweir { 1256*cdf0e10cSrcweir if ( (aStack[nCurStack].pResObj != pResObj) || nCurStack == 0 ) 1257*cdf0e10cSrcweir { 1258*cdf0e10cSrcweir RscError_Impl( "Cannot free resource! ", this, 1259*cdf0e10cSrcweir RSC_NOTYPE, 0, aStack, nCurStack ); 1260*cdf0e10cSrcweir } 1261*cdf0e10cSrcweir } 1262*cdf0e10cSrcweir #endif 1263*cdf0e10cSrcweir 1264*cdf0e10cSrcweir if ( nCurStack > 0 ) 1265*cdf0e10cSrcweir { 1266*cdf0e10cSrcweir ImpRCStack* pTop = &aStack[nCurStack]; 1267*cdf0e10cSrcweir #ifdef DBG_UTIL 1268*cdf0e10cSrcweir if ( DbgIsResource() && !(pTop->Flags & RC_NOTFOUND) ) 1269*cdf0e10cSrcweir { 1270*cdf0e10cSrcweir void* pRes = (sal_uInt8*)pTop->pResource + 1271*cdf0e10cSrcweir pTop->pResource->GetLocalOff(); 1272*cdf0e10cSrcweir 1273*cdf0e10cSrcweir if ( pTop->pClassRes != pRes ) 1274*cdf0e10cSrcweir { 1275*cdf0e10cSrcweir RscError_Impl( "Classpointer not at the end!", 1276*cdf0e10cSrcweir this, pTop->pResource->GetRT(), 1277*cdf0e10cSrcweir pTop->pResource->GetId(), 1278*cdf0e10cSrcweir aStack, nCurStack-1 ); 1279*cdf0e10cSrcweir } 1280*cdf0e10cSrcweir } 1281*cdf0e10cSrcweir #endif 1282*cdf0e10cSrcweir 1283*cdf0e10cSrcweir // Resource freigeben 1284*cdf0e10cSrcweir if( (pTop->Flags & (RC_GLOBAL | RC_NOTFOUND)) == RC_GLOBAL ) 1285*cdf0e10cSrcweir // kann auch Fremd-Ressource sein 1286*cdf0e10cSrcweir pImpRes->FreeGlobalRes( pTop->aResHandle, pTop->pResource ); 1287*cdf0e10cSrcweir decStack(); 1288*cdf0e10cSrcweir } 1289*cdf0e10cSrcweir } 1290*cdf0e10cSrcweir 1291*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1292*cdf0e10cSrcweir 1293*cdf0e10cSrcweir RSHEADER_TYPE* ResMgr::CreateBlock( const ResId& rId ) 1294*cdf0e10cSrcweir { 1295*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1296*cdf0e10cSrcweir 1297*cdf0e10cSrcweir if( pFallbackResMgr ) 1298*cdf0e10cSrcweir { 1299*cdf0e10cSrcweir ResId aId( rId ); 1300*cdf0e10cSrcweir aId.SetResMgr( NULL ); 1301*cdf0e10cSrcweir return pFallbackResMgr->CreateBlock( aId ); 1302*cdf0e10cSrcweir } 1303*cdf0e10cSrcweir 1304*cdf0e10cSrcweir RSHEADER_TYPE* pHeader = NULL; 1305*cdf0e10cSrcweir if ( GetResource( rId ) ) 1306*cdf0e10cSrcweir { 1307*cdf0e10cSrcweir // Der Zeiger steht am Anfang, deswegen zeigt der Klassen-Pointer 1308*cdf0e10cSrcweir // auf den Header und die restliche Groesse ist die Gesammte. 1309*cdf0e10cSrcweir pHeader = (RSHEADER_TYPE*)rtl_allocateMemory( GetRemainSize() ); 1310*cdf0e10cSrcweir memcpy( pHeader, GetClass(), GetRemainSize() ); 1311*cdf0e10cSrcweir Increment( pHeader->GetLocalOff() ); //ans Ende setzen 1312*cdf0e10cSrcweir if ( pHeader->GetLocalOff() != pHeader->GetGlobOff() ) 1313*cdf0e10cSrcweir // Hat Sub-Ressourcen, deshalb extra freigeben 1314*cdf0e10cSrcweir PopContext(); 1315*cdf0e10cSrcweir } 1316*cdf0e10cSrcweir 1317*cdf0e10cSrcweir return pHeader; 1318*cdf0e10cSrcweir } 1319*cdf0e10cSrcweir 1320*cdf0e10cSrcweir // ------------------------------------------------------------------ 1321*cdf0e10cSrcweir 1322*cdf0e10cSrcweir sal_Int16 ResMgr::GetShort( void * pShort ) 1323*cdf0e10cSrcweir { 1324*cdf0e10cSrcweir return ((*((sal_uInt8*)pShort + 0) << 8) | 1325*cdf0e10cSrcweir (*((sal_uInt8*)pShort + 1) << 0) ); 1326*cdf0e10cSrcweir } 1327*cdf0e10cSrcweir 1328*cdf0e10cSrcweir // ------------------------------------------------------------------ 1329*cdf0e10cSrcweir 1330*cdf0e10cSrcweir sal_Int32 ResMgr::GetLong( void * pLong ) 1331*cdf0e10cSrcweir { 1332*cdf0e10cSrcweir return ((*((sal_uInt8*)pLong + 0) << 24) | 1333*cdf0e10cSrcweir (*((sal_uInt8*)pLong + 1) << 16) | 1334*cdf0e10cSrcweir (*((sal_uInt8*)pLong + 2) << 8) | 1335*cdf0e10cSrcweir (*((sal_uInt8*)pLong + 3) << 0) ); 1336*cdf0e10cSrcweir } 1337*cdf0e10cSrcweir 1338*cdf0e10cSrcweir // ------------------------------------------------------------------ 1339*cdf0e10cSrcweir 1340*cdf0e10cSrcweir sal_uInt64 ResMgr::GetUInt64( void* pDatum ) 1341*cdf0e10cSrcweir { 1342*cdf0e10cSrcweir return ((sal_uInt64(*((sal_uInt8*)pDatum + 0)) << 56) | 1343*cdf0e10cSrcweir (sal_uInt64(*((sal_uInt8*)pDatum + 1)) << 48) | 1344*cdf0e10cSrcweir (sal_uInt64(*((sal_uInt8*)pDatum + 2)) << 40) | 1345*cdf0e10cSrcweir (sal_uInt64(*((sal_uInt8*)pDatum + 3)) << 32) | 1346*cdf0e10cSrcweir (sal_uInt64(*((sal_uInt8*)pDatum + 4)) << 24) | 1347*cdf0e10cSrcweir (sal_uInt64(*((sal_uInt8*)pDatum + 5)) << 16) | 1348*cdf0e10cSrcweir (sal_uInt64(*((sal_uInt8*)pDatum + 6)) << 8) | 1349*cdf0e10cSrcweir (sal_uInt64(*((sal_uInt8*)pDatum + 7)) << 0) ); 1350*cdf0e10cSrcweir } 1351*cdf0e10cSrcweir 1352*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1353*cdf0e10cSrcweir sal_uInt32 ResMgr::GetStringWithoutHook( UniString& rStr, const sal_uInt8* pStr ) 1354*cdf0e10cSrcweir { 1355*cdf0e10cSrcweir sal_uInt32 nLen=0; 1356*cdf0e10cSrcweir sal_uInt32 nRet = GetStringSize( pStr, nLen ); 1357*cdf0e10cSrcweir UniString aString( (sal_Char*)pStr, RTL_TEXTENCODING_UTF8, 1358*cdf0e10cSrcweir RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE | 1359*cdf0e10cSrcweir RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT | 1360*cdf0e10cSrcweir RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT ); 1361*cdf0e10cSrcweir rStr = aString; 1362*cdf0e10cSrcweir return nRet; 1363*cdf0e10cSrcweir } 1364*cdf0e10cSrcweir 1365*cdf0e10cSrcweir sal_uInt32 ResMgr::GetString( UniString& rStr, const sal_uInt8* pStr ) 1366*cdf0e10cSrcweir { 1367*cdf0e10cSrcweir UniString aString; 1368*cdf0e10cSrcweir sal_uInt32 nRet = GetStringWithoutHook( aString, pStr ); 1369*cdf0e10cSrcweir if ( pImplResHookProc ) 1370*cdf0e10cSrcweir pImplResHookProc( aString ); 1371*cdf0e10cSrcweir rStr = aString; 1372*cdf0e10cSrcweir return nRet; 1373*cdf0e10cSrcweir } 1374*cdf0e10cSrcweir 1375*cdf0e10cSrcweir sal_uInt32 ResMgr::GetByteString( rtl::OString& rStr, const sal_uInt8* pStr ) 1376*cdf0e10cSrcweir { 1377*cdf0e10cSrcweir sal_uInt32 nLen=0; 1378*cdf0e10cSrcweir sal_uInt32 nRet = GetStringSize( pStr, nLen ); 1379*cdf0e10cSrcweir rStr = rtl::OString( (const sal_Char*)pStr, nLen ); 1380*cdf0e10cSrcweir return nRet; 1381*cdf0e10cSrcweir } 1382*cdf0e10cSrcweir 1383*cdf0e10cSrcweir // ------------------------------------------------------------------ 1384*cdf0e10cSrcweir 1385*cdf0e10cSrcweir sal_uInt32 ResMgr::GetStringSize( const sal_uInt8* pStr, sal_uInt32& nLen ) 1386*cdf0e10cSrcweir { 1387*cdf0e10cSrcweir nLen = static_cast< sal_uInt32 >( strlen( (const char*)pStr ) ); 1388*cdf0e10cSrcweir return GetStringSize( nLen ); 1389*cdf0e10cSrcweir } 1390*cdf0e10cSrcweir 1391*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1392*cdf0e10cSrcweir 1393*cdf0e10cSrcweir sal_uInt32 ResMgr::GetRemainSize() 1394*cdf0e10cSrcweir { 1395*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1396*cdf0e10cSrcweir 1397*cdf0e10cSrcweir if( pFallbackResMgr ) 1398*cdf0e10cSrcweir return pFallbackResMgr->GetRemainSize(); 1399*cdf0e10cSrcweir 1400*cdf0e10cSrcweir const ImpRCStack& rTop = aStack[nCurStack]; 1401*cdf0e10cSrcweir return (sal_uInt32)((long)(sal_uInt8 *)rTop.pResource + 1402*cdf0e10cSrcweir rTop.pResource->GetLocalOff() - 1403*cdf0e10cSrcweir (long)(sal_uInt8 *)rTop.pClassRes); 1404*cdf0e10cSrcweir } 1405*cdf0e10cSrcweir 1406*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1407*cdf0e10cSrcweir 1408*cdf0e10cSrcweir void* ResMgr::Increment( sal_uInt32 nSize ) 1409*cdf0e10cSrcweir { 1410*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1411*cdf0e10cSrcweir 1412*cdf0e10cSrcweir if( pFallbackResMgr ) 1413*cdf0e10cSrcweir return pFallbackResMgr->Increment( nSize ); 1414*cdf0e10cSrcweir 1415*cdf0e10cSrcweir ImpRCStack& rStack = aStack[nCurStack]; 1416*cdf0e10cSrcweir if( (rStack.Flags & RC_NOTFOUND) ) 1417*cdf0e10cSrcweir return rStack.pClassRes; 1418*cdf0e10cSrcweir 1419*cdf0e10cSrcweir sal_uInt8* pClassRes = (sal_uInt8*)rStack.pClassRes + nSize; 1420*cdf0e10cSrcweir 1421*cdf0e10cSrcweir rStack.pClassRes = pClassRes; 1422*cdf0e10cSrcweir 1423*cdf0e10cSrcweir RSHEADER_TYPE* pRes = rStack.pResource; 1424*cdf0e10cSrcweir 1425*cdf0e10cSrcweir sal_uInt32 nLocalOff = pRes->GetLocalOff(); 1426*cdf0e10cSrcweir if ( (pRes->GetGlobOff() == nLocalOff) && 1427*cdf0e10cSrcweir (((char*)pRes + nLocalOff) == rStack.pClassRes) && 1428*cdf0e10cSrcweir (rStack.Flags & RC_AUTORELEASE)) 1429*cdf0e10cSrcweir { 1430*cdf0e10cSrcweir PopContext( rStack.pResObj ); 1431*cdf0e10cSrcweir } 1432*cdf0e10cSrcweir 1433*cdf0e10cSrcweir return pClassRes; 1434*cdf0e10cSrcweir } 1435*cdf0e10cSrcweir 1436*cdf0e10cSrcweir ResMgr* ResMgr::CreateFallbackResMgr( const ResId& rId, const Resource* pResource ) 1437*cdf0e10cSrcweir { 1438*cdf0e10cSrcweir ResMgr *pFallback = NULL; 1439*cdf0e10cSrcweir if( nCurStack > 0 ) 1440*cdf0e10cSrcweir { 1441*cdf0e10cSrcweir // get the next fallback level in resource file scope 1442*cdf0e10cSrcweir InternalResMgr* pRes = ResMgrContainer::get().getNextFallback( pImpRes ); 1443*cdf0e10cSrcweir if( pRes ) 1444*cdf0e10cSrcweir { 1445*cdf0e10cSrcweir // check that the fallback locale is not already in the chain of 1446*cdf0e10cSrcweir // fallbacks - prevent fallback loops 1447*cdf0e10cSrcweir ResMgr* pResMgr = this; 1448*cdf0e10cSrcweir while( pResMgr && 1449*cdf0e10cSrcweir ( pResMgr->pImpRes->aLocale.Language != pRes->aLocale.Language || 1450*cdf0e10cSrcweir pResMgr->pImpRes->aLocale.Country != pRes->aLocale.Country || 1451*cdf0e10cSrcweir pResMgr->pImpRes->aLocale.Variant != pRes->aLocale.Variant ) 1452*cdf0e10cSrcweir ) 1453*cdf0e10cSrcweir { 1454*cdf0e10cSrcweir pResMgr = pResMgr->pOriginalResMgr; 1455*cdf0e10cSrcweir } 1456*cdf0e10cSrcweir if( pResMgr ) 1457*cdf0e10cSrcweir { 1458*cdf0e10cSrcweir // found a recursion, no fallback possible 1459*cdf0e10cSrcweir ResMgrContainer::get().freeResMgr( pRes ); 1460*cdf0e10cSrcweir return NULL; 1461*cdf0e10cSrcweir } 1462*cdf0e10cSrcweir OSL_TRACE( "trying fallback: %s\n", OUStringToOString( pRes->aFileName, osl_getThreadTextEncoding() ).getStr() ); 1463*cdf0e10cSrcweir pFallback = new ResMgr( pRes ); 1464*cdf0e10cSrcweir pFallback->pOriginalResMgr = this; 1465*cdf0e10cSrcweir // try to recreate the resource stack 1466*cdf0e10cSrcweir bool bHaveStack = true; 1467*cdf0e10cSrcweir for( int i = 1; i < nCurStack; i++ ) 1468*cdf0e10cSrcweir { 1469*cdf0e10cSrcweir if( !aStack[i].pResource ) 1470*cdf0e10cSrcweir { 1471*cdf0e10cSrcweir bHaveStack = false; 1472*cdf0e10cSrcweir break; 1473*cdf0e10cSrcweir } 1474*cdf0e10cSrcweir ResId aId( aStack[i].pResource->GetId(), *pFallbackResMgr ); 1475*cdf0e10cSrcweir aId.SetRT( aStack[i].pResource->GetRT() ); 1476*cdf0e10cSrcweir if( !pFallback->GetResource( aId ) ) 1477*cdf0e10cSrcweir { 1478*cdf0e10cSrcweir bHaveStack = false; 1479*cdf0e10cSrcweir break; 1480*cdf0e10cSrcweir } 1481*cdf0e10cSrcweir } 1482*cdf0e10cSrcweir if( bHaveStack ) 1483*cdf0e10cSrcweir { 1484*cdf0e10cSrcweir ResId aId( rId.GetId(), *pFallback ); 1485*cdf0e10cSrcweir aId.SetRT( rId.GetRT() ); 1486*cdf0e10cSrcweir if( !pFallback->GetResource( aId, pResource ) ) 1487*cdf0e10cSrcweir bHaveStack = false; 1488*cdf0e10cSrcweir else 1489*cdf0e10cSrcweir pFallback->aStack[pFallback->nCurStack].Flags |= RC_FALLBACK_UP; 1490*cdf0e10cSrcweir } 1491*cdf0e10cSrcweir if( !bHaveStack ) 1492*cdf0e10cSrcweir { 1493*cdf0e10cSrcweir delete pFallback; 1494*cdf0e10cSrcweir pFallback = NULL; 1495*cdf0e10cSrcweir } 1496*cdf0e10cSrcweir } 1497*cdf0e10cSrcweir } 1498*cdf0e10cSrcweir return pFallback; 1499*cdf0e10cSrcweir } 1500*cdf0e10cSrcweir 1501*cdf0e10cSrcweir //--------------------------------------------------------------------------- 1502*cdf0e10cSrcweir // 1503*cdf0e10cSrcweir // method left here for SDK compatibility, 1504*cdf0e10cSrcweir // used in "framework/source/services/substitutepathvars.cxx" 1505*cdf0e10cSrcweir // 1506*cdf0e10cSrcweir // phone numbers no longer in use for resource files 1507*cdf0e10cSrcweir // 1508*cdf0e10cSrcweir //--------------------------------------------------------------------------- 1509*cdf0e10cSrcweir 1510*cdf0e10cSrcweir const char* ResMgr::GetLang( LanguageType& nType, sal_uInt16 nPrio ) 1511*cdf0e10cSrcweir { 1512*cdf0e10cSrcweir if ( nType == LANGUAGE_SYSTEM || nType == LANGUAGE_DONTKNOW ) 1513*cdf0e10cSrcweir nType = MsLangId::getSystemUILanguage(); 1514*cdf0e10cSrcweir 1515*cdf0e10cSrcweir if ( nPrio == 0 ) 1516*cdf0e10cSrcweir { 1517*cdf0e10cSrcweir switch ( nType ) 1518*cdf0e10cSrcweir { 1519*cdf0e10cSrcweir case LANGUAGE_DANISH: 1520*cdf0e10cSrcweir return "45"; 1521*cdf0e10cSrcweir 1522*cdf0e10cSrcweir case LANGUAGE_DUTCH: 1523*cdf0e10cSrcweir case LANGUAGE_DUTCH_BELGIAN: 1524*cdf0e10cSrcweir return "31"; 1525*cdf0e10cSrcweir 1526*cdf0e10cSrcweir case LANGUAGE_ENGLISH: 1527*cdf0e10cSrcweir case LANGUAGE_ENGLISH_UK: 1528*cdf0e10cSrcweir case LANGUAGE_ENGLISH_EIRE: 1529*cdf0e10cSrcweir case LANGUAGE_ENGLISH_SAFRICA: 1530*cdf0e10cSrcweir case LANGUAGE_ENGLISH_JAMAICA: 1531*cdf0e10cSrcweir case LANGUAGE_ENGLISH_BELIZE: 1532*cdf0e10cSrcweir case LANGUAGE_ENGLISH_TRINIDAD: 1533*cdf0e10cSrcweir case LANGUAGE_ENGLISH_ZIMBABWE: 1534*cdf0e10cSrcweir case LANGUAGE_ENGLISH_PHILIPPINES: 1535*cdf0e10cSrcweir return "44"; 1536*cdf0e10cSrcweir 1537*cdf0e10cSrcweir case LANGUAGE_ENGLISH_US: 1538*cdf0e10cSrcweir case LANGUAGE_ENGLISH_CAN: 1539*cdf0e10cSrcweir return "01"; 1540*cdf0e10cSrcweir 1541*cdf0e10cSrcweir case LANGUAGE_ENGLISH_AUS: 1542*cdf0e10cSrcweir case LANGUAGE_ENGLISH_NZ: 1543*cdf0e10cSrcweir return "61"; 1544*cdf0e10cSrcweir case LANGUAGE_ESTONIAN: 1545*cdf0e10cSrcweir return "77"; 1546*cdf0e10cSrcweir 1547*cdf0e10cSrcweir 1548*cdf0e10cSrcweir case LANGUAGE_FINNISH: 1549*cdf0e10cSrcweir return "35"; 1550*cdf0e10cSrcweir 1551*cdf0e10cSrcweir case LANGUAGE_FRENCH_CANADIAN: 1552*cdf0e10cSrcweir return "02"; 1553*cdf0e10cSrcweir 1554*cdf0e10cSrcweir case LANGUAGE_FRENCH: 1555*cdf0e10cSrcweir case LANGUAGE_FRENCH_BELGIAN: 1556*cdf0e10cSrcweir case LANGUAGE_FRENCH_SWISS: 1557*cdf0e10cSrcweir case LANGUAGE_FRENCH_LUXEMBOURG: 1558*cdf0e10cSrcweir case LANGUAGE_FRENCH_MONACO: 1559*cdf0e10cSrcweir return "33"; 1560*cdf0e10cSrcweir 1561*cdf0e10cSrcweir case LANGUAGE_GERMAN: 1562*cdf0e10cSrcweir case LANGUAGE_GERMAN_SWISS: 1563*cdf0e10cSrcweir case LANGUAGE_GERMAN_AUSTRIAN: 1564*cdf0e10cSrcweir case LANGUAGE_GERMAN_LUXEMBOURG: 1565*cdf0e10cSrcweir case LANGUAGE_GERMAN_LIECHTENSTEIN: 1566*cdf0e10cSrcweir return "49"; 1567*cdf0e10cSrcweir 1568*cdf0e10cSrcweir case LANGUAGE_ITALIAN: 1569*cdf0e10cSrcweir case LANGUAGE_ITALIAN_SWISS: 1570*cdf0e10cSrcweir return "39"; 1571*cdf0e10cSrcweir 1572*cdf0e10cSrcweir case LANGUAGE_NORWEGIAN: 1573*cdf0e10cSrcweir case LANGUAGE_NORWEGIAN_BOKMAL: 1574*cdf0e10cSrcweir return "47"; 1575*cdf0e10cSrcweir 1576*cdf0e10cSrcweir case LANGUAGE_PORTUGUESE: 1577*cdf0e10cSrcweir return "03"; 1578*cdf0e10cSrcweir 1579*cdf0e10cSrcweir case LANGUAGE_PORTUGUESE_BRAZILIAN: 1580*cdf0e10cSrcweir return "55"; 1581*cdf0e10cSrcweir 1582*cdf0e10cSrcweir case LANGUAGE_SPANISH_DATED: 1583*cdf0e10cSrcweir case LANGUAGE_SPANISH_MEXICAN: 1584*cdf0e10cSrcweir case LANGUAGE_SPANISH_MODERN: 1585*cdf0e10cSrcweir case LANGUAGE_SPANISH_GUATEMALA: 1586*cdf0e10cSrcweir case LANGUAGE_SPANISH_COSTARICA: 1587*cdf0e10cSrcweir case LANGUAGE_SPANISH_PANAMA: 1588*cdf0e10cSrcweir case LANGUAGE_SPANISH_DOMINICAN_REPUBLIC: 1589*cdf0e10cSrcweir case LANGUAGE_SPANISH_VENEZUELA: 1590*cdf0e10cSrcweir case LANGUAGE_SPANISH_COLOMBIA: 1591*cdf0e10cSrcweir case LANGUAGE_SPANISH_PERU: 1592*cdf0e10cSrcweir case LANGUAGE_SPANISH_ARGENTINA: 1593*cdf0e10cSrcweir case LANGUAGE_SPANISH_ECUADOR: 1594*cdf0e10cSrcweir case LANGUAGE_SPANISH_CHILE: 1595*cdf0e10cSrcweir case LANGUAGE_SPANISH_URUGUAY: 1596*cdf0e10cSrcweir case LANGUAGE_SPANISH_PARAGUAY: 1597*cdf0e10cSrcweir case LANGUAGE_SPANISH_BOLIVIA: 1598*cdf0e10cSrcweir return "34"; 1599*cdf0e10cSrcweir 1600*cdf0e10cSrcweir case LANGUAGE_SWEDISH: 1601*cdf0e10cSrcweir return "46"; 1602*cdf0e10cSrcweir 1603*cdf0e10cSrcweir case LANGUAGE_POLISH: 1604*cdf0e10cSrcweir return "48"; 1605*cdf0e10cSrcweir case LANGUAGE_CZECH: 1606*cdf0e10cSrcweir return "42"; 1607*cdf0e10cSrcweir case LANGUAGE_SLOVENIAN: 1608*cdf0e10cSrcweir return "50"; 1609*cdf0e10cSrcweir case LANGUAGE_HUNGARIAN: 1610*cdf0e10cSrcweir return "36"; 1611*cdf0e10cSrcweir case LANGUAGE_RUSSIAN: 1612*cdf0e10cSrcweir return "07"; 1613*cdf0e10cSrcweir case LANGUAGE_SLOVAK: 1614*cdf0e10cSrcweir return "43"; 1615*cdf0e10cSrcweir case LANGUAGE_GREEK: 1616*cdf0e10cSrcweir return "30"; 1617*cdf0e10cSrcweir case LANGUAGE_TURKISH: 1618*cdf0e10cSrcweir return "90"; 1619*cdf0e10cSrcweir 1620*cdf0e10cSrcweir case LANGUAGE_CHINESE_SIMPLIFIED: 1621*cdf0e10cSrcweir return "86"; 1622*cdf0e10cSrcweir case LANGUAGE_CHINESE_TRADITIONAL: 1623*cdf0e10cSrcweir return "88"; 1624*cdf0e10cSrcweir case LANGUAGE_JAPANESE: 1625*cdf0e10cSrcweir return "81"; 1626*cdf0e10cSrcweir case LANGUAGE_KOREAN: 1627*cdf0e10cSrcweir case LANGUAGE_KOREAN_JOHAB: 1628*cdf0e10cSrcweir return "82"; 1629*cdf0e10cSrcweir case LANGUAGE_THAI: 1630*cdf0e10cSrcweir return "66"; 1631*cdf0e10cSrcweir case LANGUAGE_HINDI: 1632*cdf0e10cSrcweir return "91"; 1633*cdf0e10cSrcweir 1634*cdf0e10cSrcweir case LANGUAGE_ARABIC_PRIMARY_ONLY: 1635*cdf0e10cSrcweir case LANGUAGE_ARABIC_IRAQ: 1636*cdf0e10cSrcweir case LANGUAGE_ARABIC_EGYPT: 1637*cdf0e10cSrcweir case LANGUAGE_ARABIC_LIBYA: 1638*cdf0e10cSrcweir case LANGUAGE_ARABIC_ALGERIA: 1639*cdf0e10cSrcweir case LANGUAGE_ARABIC_MOROCCO: 1640*cdf0e10cSrcweir case LANGUAGE_ARABIC_TUNISIA: 1641*cdf0e10cSrcweir case LANGUAGE_ARABIC_OMAN: 1642*cdf0e10cSrcweir case LANGUAGE_ARABIC_YEMEN: 1643*cdf0e10cSrcweir case LANGUAGE_ARABIC_SYRIA: 1644*cdf0e10cSrcweir case LANGUAGE_ARABIC_JORDAN: 1645*cdf0e10cSrcweir case LANGUAGE_ARABIC_LEBANON: 1646*cdf0e10cSrcweir case LANGUAGE_ARABIC_KUWAIT: 1647*cdf0e10cSrcweir case LANGUAGE_ARABIC_UAE: 1648*cdf0e10cSrcweir case LANGUAGE_ARABIC_BAHRAIN: 1649*cdf0e10cSrcweir case LANGUAGE_ARABIC_QATAR: 1650*cdf0e10cSrcweir return "96"; 1651*cdf0e10cSrcweir 1652*cdf0e10cSrcweir case LANGUAGE_HEBREW: 1653*cdf0e10cSrcweir return "97"; 1654*cdf0e10cSrcweir 1655*cdf0e10cSrcweir case LANGUAGE_CATALAN: 1656*cdf0e10cSrcweir return "37"; 1657*cdf0e10cSrcweir 1658*cdf0e10cSrcweir default: 1659*cdf0e10cSrcweir return "99"; 1660*cdf0e10cSrcweir } 1661*cdf0e10cSrcweir } 1662*cdf0e10cSrcweir else if ( nPrio == 1 ) 1663*cdf0e10cSrcweir { 1664*cdf0e10cSrcweir switch ( nType ) 1665*cdf0e10cSrcweir { 1666*cdf0e10cSrcweir case LANGUAGE_FRENCH_CANADIAN: 1667*cdf0e10cSrcweir return "33"; 1668*cdf0e10cSrcweir 1669*cdf0e10cSrcweir case LANGUAGE_PORTUGUESE_BRAZILIAN: 1670*cdf0e10cSrcweir return "03"; 1671*cdf0e10cSrcweir 1672*cdf0e10cSrcweir default: 1673*cdf0e10cSrcweir return NULL; 1674*cdf0e10cSrcweir } 1675*cdf0e10cSrcweir } 1676*cdf0e10cSrcweir else if ( nPrio == 2 ) 1677*cdf0e10cSrcweir return "01"; 1678*cdf0e10cSrcweir else if ( nPrio == 3 ) 1679*cdf0e10cSrcweir return "44"; 1680*cdf0e10cSrcweir else if ( nPrio == 4 ) 1681*cdf0e10cSrcweir return "49"; 1682*cdf0e10cSrcweir else 1683*cdf0e10cSrcweir return "99"; 1684*cdf0e10cSrcweir } 1685*cdf0e10cSrcweir 1686*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1687*cdf0e10cSrcweir 1688*cdf0e10cSrcweir ResMgr* ResMgr::CreateResMgr( const sal_Char* pPrefixName, 1689*cdf0e10cSrcweir com::sun::star::lang::Locale aLocale ) 1690*cdf0e10cSrcweir { 1691*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1692*cdf0e10cSrcweir 1693*cdf0e10cSrcweir OUString aPrefix( pPrefixName, strlen( pPrefixName ), osl_getThreadTextEncoding() ); 1694*cdf0e10cSrcweir 1695*cdf0e10cSrcweir if( ! aLocale.Language.getLength() ) 1696*cdf0e10cSrcweir aLocale = ResMgrContainer::get().getDefLocale(); 1697*cdf0e10cSrcweir 1698*cdf0e10cSrcweir InternalResMgr* pImp = ResMgrContainer::get().getResMgr( aPrefix, aLocale ); 1699*cdf0e10cSrcweir return pImp ? new ResMgr( pImp ) : NULL; 1700*cdf0e10cSrcweir } 1701*cdf0e10cSrcweir 1702*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1703*cdf0e10cSrcweir 1704*cdf0e10cSrcweir ResMgr* ResMgr::SearchCreateResMgr( 1705*cdf0e10cSrcweir const sal_Char* pPrefixName, 1706*cdf0e10cSrcweir com::sun::star::lang::Locale& rLocale ) 1707*cdf0e10cSrcweir { 1708*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1709*cdf0e10cSrcweir 1710*cdf0e10cSrcweir OUString aPrefix( pPrefixName, strlen( pPrefixName ), osl_getThreadTextEncoding() ); 1711*cdf0e10cSrcweir 1712*cdf0e10cSrcweir if( ! rLocale.Language.getLength() ) 1713*cdf0e10cSrcweir rLocale = ResMgrContainer::get().getDefLocale(); 1714*cdf0e10cSrcweir 1715*cdf0e10cSrcweir InternalResMgr* pImp = ResMgrContainer::get().getResMgr( aPrefix, rLocale ); 1716*cdf0e10cSrcweir return pImp ? new ResMgr( pImp ) : NULL; 1717*cdf0e10cSrcweir } 1718*cdf0e10cSrcweir 1719*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1720*cdf0e10cSrcweir 1721*cdf0e10cSrcweir sal_Int16 ResMgr::ReadShort() 1722*cdf0e10cSrcweir { 1723*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1724*cdf0e10cSrcweir 1725*cdf0e10cSrcweir if( pFallbackResMgr ) 1726*cdf0e10cSrcweir return pFallbackResMgr->ReadShort(); 1727*cdf0e10cSrcweir 1728*cdf0e10cSrcweir sal_Int16 n = GetShort( GetClass() ); 1729*cdf0e10cSrcweir Increment( sizeof( sal_Int16 ) ); 1730*cdf0e10cSrcweir return n; 1731*cdf0e10cSrcweir } 1732*cdf0e10cSrcweir 1733*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1734*cdf0e10cSrcweir 1735*cdf0e10cSrcweir sal_Int32 ResMgr::ReadLong() 1736*cdf0e10cSrcweir { 1737*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1738*cdf0e10cSrcweir 1739*cdf0e10cSrcweir if( pFallbackResMgr ) 1740*cdf0e10cSrcweir return pFallbackResMgr->ReadLong(); 1741*cdf0e10cSrcweir 1742*cdf0e10cSrcweir sal_Int32 n = GetLong( GetClass() ); 1743*cdf0e10cSrcweir Increment( sizeof( sal_Int32 ) ); 1744*cdf0e10cSrcweir return n; 1745*cdf0e10cSrcweir } 1746*cdf0e10cSrcweir 1747*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1748*cdf0e10cSrcweir 1749*cdf0e10cSrcweir UniString ResMgr::ReadStringWithoutHook() 1750*cdf0e10cSrcweir { 1751*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1752*cdf0e10cSrcweir 1753*cdf0e10cSrcweir if( pFallbackResMgr ) 1754*cdf0e10cSrcweir return pFallbackResMgr->ReadStringWithoutHook(); 1755*cdf0e10cSrcweir 1756*cdf0e10cSrcweir UniString aRet; 1757*cdf0e10cSrcweir 1758*cdf0e10cSrcweir const ImpRCStack& rTop = aStack[nCurStack]; 1759*cdf0e10cSrcweir if( (rTop.Flags & RC_NOTFOUND) ) 1760*cdf0e10cSrcweir { 1761*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 1762*cdf0e10cSrcweir aRet = OUString( RTL_CONSTASCII_USTRINGPARAM( "<resource not found>" ) ); 1763*cdf0e10cSrcweir #endif 1764*cdf0e10cSrcweir } 1765*cdf0e10cSrcweir else 1766*cdf0e10cSrcweir Increment( GetStringWithoutHook( aRet, (const sal_uInt8*)GetClass() ) ); 1767*cdf0e10cSrcweir 1768*cdf0e10cSrcweir return aRet; 1769*cdf0e10cSrcweir } 1770*cdf0e10cSrcweir 1771*cdf0e10cSrcweir UniString ResMgr::ReadString() 1772*cdf0e10cSrcweir { 1773*cdf0e10cSrcweir UniString aRet = ReadStringWithoutHook(); 1774*cdf0e10cSrcweir if ( pImplResHookProc ) 1775*cdf0e10cSrcweir pImplResHookProc( aRet ); 1776*cdf0e10cSrcweir return aRet; 1777*cdf0e10cSrcweir } 1778*cdf0e10cSrcweir 1779*cdf0e10cSrcweir rtl::OString ResMgr::ReadByteString() 1780*cdf0e10cSrcweir { 1781*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1782*cdf0e10cSrcweir 1783*cdf0e10cSrcweir if( pFallbackResMgr ) 1784*cdf0e10cSrcweir return pFallbackResMgr->ReadByteString(); 1785*cdf0e10cSrcweir 1786*cdf0e10cSrcweir rtl::OString aRet; 1787*cdf0e10cSrcweir 1788*cdf0e10cSrcweir const ImpRCStack& rTop = aStack[nCurStack]; 1789*cdf0e10cSrcweir if( (rTop.Flags & RC_NOTFOUND) ) 1790*cdf0e10cSrcweir { 1791*cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0 1792*cdf0e10cSrcweir aRet = OString( "<resource not found>" ); 1793*cdf0e10cSrcweir #endif 1794*cdf0e10cSrcweir } 1795*cdf0e10cSrcweir else 1796*cdf0e10cSrcweir Increment( GetByteString( aRet, (const sal_uInt8*)GetClass() ) ); 1797*cdf0e10cSrcweir 1798*cdf0e10cSrcweir return aRet; 1799*cdf0e10cSrcweir } 1800*cdf0e10cSrcweir 1801*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1802*cdf0e10cSrcweir 1803*cdf0e10cSrcweir rtl::OString ResMgr::GetAutoHelpId() 1804*cdf0e10cSrcweir { 1805*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1806*cdf0e10cSrcweir 1807*cdf0e10cSrcweir if( pFallbackResMgr ) 1808*cdf0e10cSrcweir return pFallbackResMgr->GetAutoHelpId(); 1809*cdf0e10cSrcweir 1810*cdf0e10cSrcweir OSL_ENSURE( nCurStack, "resource stack empty in Auto help id generation" ); 1811*cdf0e10cSrcweir if( nCurStack < 1 || nCurStack > 2 ) 1812*cdf0e10cSrcweir return rtl::OString(); 1813*cdf0e10cSrcweir 1814*cdf0e10cSrcweir // prepare HID, start with resource prefix 1815*cdf0e10cSrcweir rtl::OStringBuffer aHID( 32 ); 1816*cdf0e10cSrcweir aHID.append( rtl::OUStringToOString( pImpRes->aPrefix, RTL_TEXTENCODING_UTF8 ) ); 1817*cdf0e10cSrcweir aHID.append( '.' ); 1818*cdf0e10cSrcweir 1819*cdf0e10cSrcweir // append type 1820*cdf0e10cSrcweir const ImpRCStack *pRC = StackTop(); 1821*cdf0e10cSrcweir OSL_ENSURE( pRC, "missing resource stack level" ); 1822*cdf0e10cSrcweir 1823*cdf0e10cSrcweir if ( nCurStack == 1 ) 1824*cdf0e10cSrcweir { 1825*cdf0e10cSrcweir // auto help ids for top level windows 1826*cdf0e10cSrcweir switch( pRC->pResource->GetRT() ) { 1827*cdf0e10cSrcweir case RSC_DOCKINGWINDOW: aHID.append( "DockingWindow" ); break; 1828*cdf0e10cSrcweir case RSC_WORKWIN: aHID.append( "WorkWindow" ); break; 1829*cdf0e10cSrcweir case RSC_MODELESSDIALOG: aHID.append( "ModelessDialog" ); break; 1830*cdf0e10cSrcweir case RSC_FLOATINGWINDOW: aHID.append( "FloatingWindow" ); break; 1831*cdf0e10cSrcweir case RSC_MODALDIALOG: aHID.append( "ModalDialog" ); break; 1832*cdf0e10cSrcweir case RSC_TABPAGE: aHID.append( "TabPage" ); break; 1833*cdf0e10cSrcweir default: return rtl::OString(); 1834*cdf0e10cSrcweir } 1835*cdf0e10cSrcweir } 1836*cdf0e10cSrcweir else 1837*cdf0e10cSrcweir { 1838*cdf0e10cSrcweir // only controls with the following parents get auto help ids 1839*cdf0e10cSrcweir const ImpRCStack *pRC1 = StackTop(1); 1840*cdf0e10cSrcweir switch( pRC1->pResource->GetRT() ) { 1841*cdf0e10cSrcweir case RSC_DOCKINGWINDOW: 1842*cdf0e10cSrcweir case RSC_WORKWIN: 1843*cdf0e10cSrcweir case RSC_MODELESSDIALOG: 1844*cdf0e10cSrcweir case RSC_FLOATINGWINDOW: 1845*cdf0e10cSrcweir case RSC_MODALDIALOG: 1846*cdf0e10cSrcweir case RSC_TABPAGE: 1847*cdf0e10cSrcweir // intentionally no breaks! 1848*cdf0e10cSrcweir // auto help ids for controls 1849*cdf0e10cSrcweir switch( pRC->pResource->GetRT() ) { 1850*cdf0e10cSrcweir case RSC_TABCONTROL: aHID.append( "TabControl" ); break; 1851*cdf0e10cSrcweir case RSC_RADIOBUTTON: aHID.append( "RadioButton" ); break; 1852*cdf0e10cSrcweir case RSC_CHECKBOX: aHID.append( "CheckBox" ); break; 1853*cdf0e10cSrcweir case RSC_TRISTATEBOX: aHID.append( "TriStateBox" ); break; 1854*cdf0e10cSrcweir case RSC_EDIT: aHID.append( "Edit" ); break; 1855*cdf0e10cSrcweir case RSC_MULTILINEEDIT: aHID.append( "MultiLineEdit" ); break; 1856*cdf0e10cSrcweir case RSC_MULTILISTBOX: aHID.append( "MultiListBox" ); break; 1857*cdf0e10cSrcweir case RSC_LISTBOX: aHID.append( "ListBox" ); break; 1858*cdf0e10cSrcweir case RSC_COMBOBOX: aHID.append( "ComboBox" ); break; 1859*cdf0e10cSrcweir case RSC_PUSHBUTTON: aHID.append( "PushButton" ); break; 1860*cdf0e10cSrcweir case RSC_SPINFIELD: aHID.append( "SpinField" ); break; 1861*cdf0e10cSrcweir case RSC_PATTERNFIELD: aHID.append( "PatternField" ); break; 1862*cdf0e10cSrcweir case RSC_NUMERICFIELD: aHID.append( "NumericField" ); break; 1863*cdf0e10cSrcweir case RSC_METRICFIELD: aHID.append( "MetricField" ); break; 1864*cdf0e10cSrcweir case RSC_CURRENCYFIELD: aHID.append( "CurrencyField" ); break; 1865*cdf0e10cSrcweir case RSC_DATEFIELD: aHID.append( "DateField" ); break; 1866*cdf0e10cSrcweir case RSC_TIMEFIELD: aHID.append( "TimeField" ); break; 1867*cdf0e10cSrcweir case RSC_IMAGERADIOBUTTON: aHID.append( "ImageRadioButton" ); break; 1868*cdf0e10cSrcweir case RSC_NUMERICBOX: aHID.append( "NumericBox" ); break; 1869*cdf0e10cSrcweir case RSC_METRICBOX: aHID.append( "MetricBox" ); break; 1870*cdf0e10cSrcweir case RSC_CURRENCYBOX: aHID.append( "CurrencyBox" ); break; 1871*cdf0e10cSrcweir case RSC_DATEBOX: aHID.append( "DateBox" ); break; 1872*cdf0e10cSrcweir case RSC_TIMEBOX: aHID.append( "TimeBox" ); break; 1873*cdf0e10cSrcweir case RSC_IMAGEBUTTON: aHID.append( "ImageButton" ); break; 1874*cdf0e10cSrcweir case RSC_MENUBUTTON: aHID.append( "MenuButton" ); break; 1875*cdf0e10cSrcweir case RSC_MOREBUTTON: aHID.append( "MoreButton" ); break; 1876*cdf0e10cSrcweir default: 1877*cdf0e10cSrcweir // no type, no auto HID 1878*cdf0e10cSrcweir return rtl::OString(); 1879*cdf0e10cSrcweir } 1880*cdf0e10cSrcweir break; 1881*cdf0e10cSrcweir default: 1882*cdf0e10cSrcweir return rtl::OString(); 1883*cdf0e10cSrcweir } 1884*cdf0e10cSrcweir } 1885*cdf0e10cSrcweir 1886*cdf0e10cSrcweir // append resource id hierarchy 1887*cdf0e10cSrcweir for( int nOff = nCurStack-1; nOff >= 0; nOff-- ) 1888*cdf0e10cSrcweir { 1889*cdf0e10cSrcweir aHID.append( '.' ); 1890*cdf0e10cSrcweir pRC = StackTop( nOff ); 1891*cdf0e10cSrcweir 1892*cdf0e10cSrcweir OSL_ENSURE( pRC->pResource, "missing resource in resource stack level !" ); 1893*cdf0e10cSrcweir if( pRC->pResource ) 1894*cdf0e10cSrcweir aHID.append( sal_Int32( pRC->pResource->GetId() ) ); 1895*cdf0e10cSrcweir } 1896*cdf0e10cSrcweir 1897*cdf0e10cSrcweir return aHID.makeStringAndClear(); 1898*cdf0e10cSrcweir } 1899*cdf0e10cSrcweir 1900*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1901*cdf0e10cSrcweir 1902*cdf0e10cSrcweir void ResMgr::SetReadStringHook( ResHookProc pProc ) 1903*cdf0e10cSrcweir { 1904*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1905*cdf0e10cSrcweir pImplResHookProc = pProc; 1906*cdf0e10cSrcweir } 1907*cdf0e10cSrcweir 1908*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1909*cdf0e10cSrcweir 1910*cdf0e10cSrcweir ResHookProc ResMgr::GetReadStringHook() 1911*cdf0e10cSrcweir { 1912*cdf0e10cSrcweir return pImplResHookProc; 1913*cdf0e10cSrcweir } 1914*cdf0e10cSrcweir 1915*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1916*cdf0e10cSrcweir 1917*cdf0e10cSrcweir void ResMgr::SetDefaultLocale( const com::sun::star::lang::Locale& rLocale ) 1918*cdf0e10cSrcweir { 1919*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1920*cdf0e10cSrcweir ResMgrContainer::get().setDefLocale( rLocale ); 1921*cdf0e10cSrcweir } 1922*cdf0e10cSrcweir 1923*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1924*cdf0e10cSrcweir 1925*cdf0e10cSrcweir const OUString& ResMgr::GetFileName() const 1926*cdf0e10cSrcweir { 1927*cdf0e10cSrcweir return pImpRes->aFileName; 1928*cdf0e10cSrcweir } 1929*cdf0e10cSrcweir 1930*cdf0e10cSrcweir // ======================================================================= 1931*cdf0e10cSrcweir 1932*cdf0e10cSrcweir SimpleResMgr::SimpleResMgr( const sal_Char* pPrefixName, 1933*cdf0e10cSrcweir const ::com::sun::star::lang::Locale& rLocale ) 1934*cdf0e10cSrcweir { 1935*cdf0e10cSrcweir OUString aPrefix( pPrefixName, strlen( pPrefixName ), osl_getThreadTextEncoding() ); 1936*cdf0e10cSrcweir com::sun::star::lang::Locale aLocale( rLocale ); 1937*cdf0e10cSrcweir 1938*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1939*cdf0e10cSrcweir if( ! aLocale.Language.getLength() ) 1940*cdf0e10cSrcweir aLocale = ResMgrContainer::get().getDefLocale(); 1941*cdf0e10cSrcweir 1942*cdf0e10cSrcweir m_pResImpl = ResMgrContainer::get().getResMgr( aPrefix, aLocale, true ); 1943*cdf0e10cSrcweir DBG_ASSERT( m_pResImpl, "SimpleResMgr::SimpleResMgr : have no impl class !" ); 1944*cdf0e10cSrcweir } 1945*cdf0e10cSrcweir 1946*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1947*cdf0e10cSrcweir SimpleResMgr::SimpleResMgr( const ::rtl::OUString& _rPrefixName, ::com::sun::star::lang::Locale& _inout_Locale ) 1948*cdf0e10cSrcweir { 1949*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard( getResMgrMutex() ); 1950*cdf0e10cSrcweir m_pResImpl = ResMgrContainer::get().getResMgr( _rPrefixName, _inout_Locale, true ); 1951*cdf0e10cSrcweir } 1952*cdf0e10cSrcweir 1953*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1954*cdf0e10cSrcweir SimpleResMgr::~SimpleResMgr() 1955*cdf0e10cSrcweir { 1956*cdf0e10cSrcweir delete m_pResImpl; 1957*cdf0e10cSrcweir } 1958*cdf0e10cSrcweir 1959*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1960*cdf0e10cSrcweir SimpleResMgr* SimpleResMgr::Create( const sal_Char* pPrefixName, com::sun::star::lang::Locale aLocale ) 1961*cdf0e10cSrcweir { 1962*cdf0e10cSrcweir return new SimpleResMgr( pPrefixName, aLocale ); 1963*cdf0e10cSrcweir } 1964*cdf0e10cSrcweir 1965*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1966*cdf0e10cSrcweir bool SimpleResMgr::IsAvailable( RESOURCE_TYPE _resourceType, sal_uInt32 _resourceId ) 1967*cdf0e10cSrcweir { 1968*cdf0e10cSrcweir vos::OGuard aGuard(m_aAccessSafety); 1969*cdf0e10cSrcweir 1970*cdf0e10cSrcweir if ( ( RSC_STRING != _resourceType ) && ( RSC_RESOURCE != _resourceType ) ) 1971*cdf0e10cSrcweir return false; 1972*cdf0e10cSrcweir 1973*cdf0e10cSrcweir DBG_ASSERT( m_pResImpl, "SimpleResMgr::IsAvailable: have no impl class !" ); 1974*cdf0e10cSrcweir return m_pResImpl->IsGlobalAvailable( _resourceType, _resourceId ); 1975*cdf0e10cSrcweir } 1976*cdf0e10cSrcweir 1977*cdf0e10cSrcweir // ----------------------------------------------------------------------- 1978*cdf0e10cSrcweir UniString SimpleResMgr::ReadString( sal_uInt32 nId ) 1979*cdf0e10cSrcweir { 1980*cdf0e10cSrcweir vos::OGuard aGuard(m_aAccessSafety); 1981*cdf0e10cSrcweir 1982*cdf0e10cSrcweir DBG_ASSERT( m_pResImpl, "SimpleResMgr::ReadString : have no impl class !" ); 1983*cdf0e10cSrcweir // perhaps constructed with an invalid filename ? 1984*cdf0e10cSrcweir 1985*cdf0e10cSrcweir UniString sReturn; 1986*cdf0e10cSrcweir if ( !m_pResImpl ) 1987*cdf0e10cSrcweir return sReturn; 1988*cdf0e10cSrcweir 1989*cdf0e10cSrcweir void* pResHandle = NULL; 1990*cdf0e10cSrcweir InternalResMgr* pFallback = m_pResImpl; 1991*cdf0e10cSrcweir RSHEADER_TYPE* pResHeader = (RSHEADER_TYPE*)m_pResImpl->LoadGlobalRes( RSC_STRING, nId, &pResHandle ); 1992*cdf0e10cSrcweir if ( !pResHeader ) 1993*cdf0e10cSrcweir { 1994*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() ); 1995*cdf0e10cSrcweir 1996*cdf0e10cSrcweir // try fallback 1997*cdf0e10cSrcweir while( ! pResHandle && pFallback ) 1998*cdf0e10cSrcweir { 1999*cdf0e10cSrcweir InternalResMgr* pOldFallback = pFallback; 2000*cdf0e10cSrcweir pFallback = ResMgrContainer::get().getNextFallback( pFallback ); 2001*cdf0e10cSrcweir if( pOldFallback != m_pResImpl ) 2002*cdf0e10cSrcweir ResMgrContainer::get().freeResMgr( pOldFallback ); 2003*cdf0e10cSrcweir if( pFallback ) 2004*cdf0e10cSrcweir { 2005*cdf0e10cSrcweir // handle possible recursion 2006*cdf0e10cSrcweir if( pFallback->aLocale.Language != m_pResImpl->aLocale.Language || 2007*cdf0e10cSrcweir pFallback->aLocale.Country != m_pResImpl->aLocale.Country || 2008*cdf0e10cSrcweir pFallback->aLocale.Variant != m_pResImpl->aLocale.Variant ) 2009*cdf0e10cSrcweir { 2010*cdf0e10cSrcweir pResHeader = (RSHEADER_TYPE*)pFallback->LoadGlobalRes( RSC_STRING, nId, &pResHandle ); 2011*cdf0e10cSrcweir } 2012*cdf0e10cSrcweir else 2013*cdf0e10cSrcweir { 2014*cdf0e10cSrcweir ResMgrContainer::get().freeResMgr( pFallback ); 2015*cdf0e10cSrcweir pFallback = NULL; 2016*cdf0e10cSrcweir } 2017*cdf0e10cSrcweir } 2018*cdf0e10cSrcweir } 2019*cdf0e10cSrcweir if( ! pResHandle ) 2020*cdf0e10cSrcweir // no such resource 2021*cdf0e10cSrcweir return sReturn; 2022*cdf0e10cSrcweir } 2023*cdf0e10cSrcweir 2024*cdf0e10cSrcweir // sal_uIntPtr nLen = pResHeader->GetLocalOff() - sizeof(RSHEADER_TYPE); 2025*cdf0e10cSrcweir ResMgr::GetString( sReturn, (const sal_uInt8*)(pResHeader+1) ); 2026*cdf0e10cSrcweir 2027*cdf0e10cSrcweir // not neccessary with te current implementation which holds the string table permanently, but to be sure .... 2028*cdf0e10cSrcweir // note: pFallback cannot be NULL here and is either the fallback or m_pResImpl 2029*cdf0e10cSrcweir pFallback->FreeGlobalRes( pResHeader, pResHandle ); 2030*cdf0e10cSrcweir if( m_pResImpl != pFallback ) 2031*cdf0e10cSrcweir { 2032*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() ); 2033*cdf0e10cSrcweir 2034*cdf0e10cSrcweir ResMgrContainer::get().freeResMgr( pFallback ); 2035*cdf0e10cSrcweir } 2036*cdf0e10cSrcweir return sReturn; 2037*cdf0e10cSrcweir } 2038*cdf0e10cSrcweir 2039*cdf0e10cSrcweir // ----------------------------------------------------------------------- 2040*cdf0e10cSrcweir 2041*cdf0e10cSrcweir const ::com::sun::star::lang::Locale& SimpleResMgr::GetLocale() const 2042*cdf0e10cSrcweir { 2043*cdf0e10cSrcweir DBG_ASSERT( IsValid(), "SimpleResMgr::ReadBlob: invalid, this will crash!" ); 2044*cdf0e10cSrcweir return m_pResImpl->aLocale; 2045*cdf0e10cSrcweir } 2046*cdf0e10cSrcweir 2047*cdf0e10cSrcweir // ----------------------------------------------------------------------- 2048*cdf0e10cSrcweir 2049*cdf0e10cSrcweir sal_uInt32 SimpleResMgr::ReadBlob( sal_uInt32 nId, void** pBuffer ) 2050*cdf0e10cSrcweir { 2051*cdf0e10cSrcweir vos::OGuard aGuard(m_aAccessSafety); 2052*cdf0e10cSrcweir 2053*cdf0e10cSrcweir DBG_ASSERT( m_pResImpl, "SimpleResMgr::ReadBlob : have no impl class !" ); 2054*cdf0e10cSrcweir 2055*cdf0e10cSrcweir // perhaps constructed with an invalid filename ? 2056*cdf0e10cSrcweir DBG_ASSERT( pBuffer, "SimpleResMgr::ReadBlob : invalid argument !" ); 2057*cdf0e10cSrcweir *pBuffer = NULL; 2058*cdf0e10cSrcweir 2059*cdf0e10cSrcweir void* pResHandle = NULL; 2060*cdf0e10cSrcweir InternalResMgr* pFallback = m_pResImpl; 2061*cdf0e10cSrcweir RSHEADER_TYPE* pResHeader = (RSHEADER_TYPE*)m_pResImpl->LoadGlobalRes( RSC_RESOURCE, nId, &pResHandle ); 2062*cdf0e10cSrcweir DBG_ASSERT( pResHeader, "SimpleResMgr::ReadBlob : couldn't find the resource with the given id !" ); 2063*cdf0e10cSrcweir 2064*cdf0e10cSrcweir if ( !pResHeader ) 2065*cdf0e10cSrcweir { 2066*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() ); 2067*cdf0e10cSrcweir 2068*cdf0e10cSrcweir // try fallback 2069*cdf0e10cSrcweir while( ! pResHandle && pFallback ) 2070*cdf0e10cSrcweir { 2071*cdf0e10cSrcweir InternalResMgr* pOldFallback = pFallback; 2072*cdf0e10cSrcweir pFallback = ResMgrContainer::get().getNextFallback( pFallback ); 2073*cdf0e10cSrcweir if( pOldFallback != m_pResImpl ) 2074*cdf0e10cSrcweir ResMgrContainer::get().freeResMgr( pOldFallback ); 2075*cdf0e10cSrcweir if( pFallback ) 2076*cdf0e10cSrcweir { 2077*cdf0e10cSrcweir // handle possible recursion 2078*cdf0e10cSrcweir if( pFallback->aLocale.Language != m_pResImpl->aLocale.Language || 2079*cdf0e10cSrcweir pFallback->aLocale.Country != m_pResImpl->aLocale.Country || 2080*cdf0e10cSrcweir pFallback->aLocale.Variant != m_pResImpl->aLocale.Variant ) 2081*cdf0e10cSrcweir { 2082*cdf0e10cSrcweir pResHeader = (RSHEADER_TYPE*)pFallback->LoadGlobalRes( RSC_RESOURCE, nId, &pResHandle ); 2083*cdf0e10cSrcweir } 2084*cdf0e10cSrcweir else 2085*cdf0e10cSrcweir { 2086*cdf0e10cSrcweir ResMgrContainer::get().freeResMgr( pFallback ); 2087*cdf0e10cSrcweir pFallback = NULL; 2088*cdf0e10cSrcweir } 2089*cdf0e10cSrcweir } 2090*cdf0e10cSrcweir } 2091*cdf0e10cSrcweir if( ! pResHandle ) 2092*cdf0e10cSrcweir // no exception handling, this would require the locking of the solar mutex which isn't allowed within this class 2093*cdf0e10cSrcweir return 0; 2094*cdf0e10cSrcweir } 2095*cdf0e10cSrcweir 2096*cdf0e10cSrcweir DBG_ASSERT( pResHandle == NULL, "SimpleResMgr::ReadBlob : behaviour of LoadGlobalRes changed !" ); 2097*cdf0e10cSrcweir // if pResHandle is not NULL the FreeBlob wouldn't have to delete the pointer given as pBuffer, but 2098*cdf0e10cSrcweir // FreeBlob doesn't know that so it would probably crash .... 2099*cdf0e10cSrcweir 2100*cdf0e10cSrcweir sal_uInt32 nRemaining = pResHeader->GetLocalOff() - sizeof(RSHEADER_TYPE); 2101*cdf0e10cSrcweir *pBuffer = (void*)(((sal_uInt8*)pResHeader) + sizeof(RSHEADER_TYPE)); 2102*cdf0e10cSrcweir 2103*cdf0e10cSrcweir // free an eventual fallback InternalResMgr 2104*cdf0e10cSrcweir if( m_pResImpl != pFallback ) 2105*cdf0e10cSrcweir { 2106*cdf0e10cSrcweir osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() ); 2107*cdf0e10cSrcweir 2108*cdf0e10cSrcweir ResMgrContainer::get().freeResMgr( pFallback ); 2109*cdf0e10cSrcweir } 2110*cdf0e10cSrcweir 2111*cdf0e10cSrcweir return nRemaining; 2112*cdf0e10cSrcweir } 2113*cdf0e10cSrcweir 2114*cdf0e10cSrcweir // ----------------------------------------------------------------------- 2115*cdf0e10cSrcweir 2116*cdf0e10cSrcweir void SimpleResMgr::FreeBlob( void* pBuffer ) 2117*cdf0e10cSrcweir { 2118*cdf0e10cSrcweir void* pCompleteBuffer = (void*)(((sal_uInt8*)pBuffer) - sizeof(RSHEADER_TYPE)); 2119*cdf0e10cSrcweir rtl_freeMemory(pCompleteBuffer); 2120*cdf0e10cSrcweir } 2121