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