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