2010-10-14 08:27:31 +02:00
|
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2000-09-18 16:07:07 +00:00
|
|
|
|
/*************************************************************************
|
|
|
|
|
*
|
2008-04-11 12:55:09 +00:00
|
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*
|
2010-02-12 15:01:35 +01:00
|
|
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*
|
2008-04-11 12:55:09 +00:00
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*
|
2008-04-11 12:55:09 +00:00
|
|
|
|
* This file is part of OpenOffice.org.
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*
|
2008-04-11 12:55:09 +00:00
|
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
|
* only, as published by the Free Software Foundation.
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*
|
2008-04-11 12:55:09 +00:00
|
|
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU Lesser General Public License version 3 for more details
|
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*
|
2008-04-11 12:55:09 +00:00
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
|
* for a copy of the LGPLv3 License.
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*
|
|
|
|
|
************************************************************************/
|
|
|
|
|
|
2006-09-17 00:00:10 +00:00
|
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
|
#include "precompiled_tools.hxx"
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
2007-06-27 21:17:20 +00:00
|
|
|
|
#include <tools/debug.hxx>
|
|
|
|
|
#include <tools/table.hxx>
|
|
|
|
|
#include <tools/stream.hxx>
|
|
|
|
|
#include <tools/resmgr.hxx>
|
|
|
|
|
#include <tools/rc.hxx>
|
|
|
|
|
#include <tools/rcid.h>
|
2004-06-17 12:12:20 +00:00
|
|
|
|
#include <osl/endian.h>
|
2000-11-16 13:21:17 +00:00
|
|
|
|
#include <osl/process.h>
|
2005-01-03 16:14:02 +00:00
|
|
|
|
#include <osl/thread.h>
|
2000-11-16 13:21:17 +00:00
|
|
|
|
#include <osl/file.hxx>
|
2005-01-03 16:14:02 +00:00
|
|
|
|
#include <osl/mutex.hxx>
|
2010-10-11 01:26:24 -05:00
|
|
|
|
#include <osl/signal.h>
|
2005-01-03 16:14:02 +00:00
|
|
|
|
#include <rtl/ustrbuf.hxx>
|
2007-06-27 21:17:20 +00:00
|
|
|
|
#include <tools/urlobj.hxx>
|
2004-06-25 16:13:01 +00:00
|
|
|
|
#include <rtl/instance.hxx>
|
2008-03-18 11:27:59 +00:00
|
|
|
|
#include <rtl/bootstrap.hxx>
|
2006-04-07 15:17:13 +00:00
|
|
|
|
#include <i18npool/mslangid.hxx>
|
2007-06-27 21:17:20 +00:00
|
|
|
|
#include <tools/simplerm.hxx>
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2007-06-27 21:17:20 +00:00
|
|
|
|
#include <tools/isofallback.hxx>
|
2004-06-25 14:04:28 +00:00
|
|
|
|
|
2003-03-27 16:05:12 +00:00
|
|
|
|
#include <functional>
|
|
|
|
|
#include <algorithm>
|
2011-02-03 16:55:17 -07:00
|
|
|
|
#include <boost/unordered_map.hpp>
|
2005-01-03 16:14:02 +00:00
|
|
|
|
#include <list>
|
2007-03-05 14:19:00 +00:00
|
|
|
|
#include <set>
|
2003-03-27 16:05:12 +00:00
|
|
|
|
|
2001-07-05 09:58:16 +00:00
|
|
|
|
#ifdef UNX
|
|
|
|
|
#define SEARCH_PATH_DELIMITER_CHAR_STRING ":"
|
|
|
|
|
#define SEARCH_PATH_DELIMITER ':'
|
|
|
|
|
#else
|
|
|
|
|
#define SEARCH_PATH_DELIMITER_CHAR_STRING ";"
|
|
|
|
|
#define SEARCH_PATH_DELIMITER ';'
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#define SEARCH_PATH_DELIMITER_STRING ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SEARCH_PATH_DELIMITER_CHAR_STRING ) )
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
using namespace rtl;
|
|
|
|
|
using namespace osl;
|
|
|
|
|
|
|
|
|
|
// for thread safety
|
|
|
|
|
static osl::Mutex* pResMgrMutex = NULL;
|
|
|
|
|
static osl::Mutex& getResMgrMutex()
|
2004-06-17 12:12:20 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if( !pResMgrMutex )
|
|
|
|
|
{
|
|
|
|
|
osl::Guard<osl::Mutex> aGuard( *osl::Mutex::getGlobalMutex() );
|
|
|
|
|
if( ! pResMgrMutex )
|
|
|
|
|
pResMgrMutex = new osl::Mutex();
|
|
|
|
|
}
|
|
|
|
|
return *pResMgrMutex;
|
2004-06-17 12:12:20 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
struct ImpContent;
|
|
|
|
|
class InternalResMgr
|
|
|
|
|
{
|
|
|
|
|
friend class ResMgr;
|
|
|
|
|
friend class SimpleResMgr;
|
|
|
|
|
friend class ResMgrContainer;
|
|
|
|
|
|
|
|
|
|
ImpContent * pContent;
|
|
|
|
|
UINT32 nOffCorrection;
|
|
|
|
|
BYTE * pStringBlock;
|
|
|
|
|
SvStream * pStm;
|
|
|
|
|
BOOL bEqual2Content;
|
|
|
|
|
UINT32 nEntries;
|
|
|
|
|
OUString aFileName;
|
|
|
|
|
OUString aPrefix;
|
|
|
|
|
OUString aResName;
|
|
|
|
|
bool bSingular;
|
|
|
|
|
com::sun::star::lang::Locale aLocale;
|
2011-02-03 16:55:17 -07:00
|
|
|
|
boost::unordered_map<sal_uInt64, int>* pResUseDump;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
InternalResMgr( const OUString& rFileURL,
|
|
|
|
|
const OUString& aPrefix,
|
|
|
|
|
const OUString& aResName,
|
|
|
|
|
const com::sun::star::lang::Locale& rLocale );
|
|
|
|
|
~InternalResMgr();
|
|
|
|
|
BOOL Create();
|
|
|
|
|
|
|
|
|
|
BOOL IsGlobalAvailable( RESOURCE_TYPE nRT, sal_uInt32 nId ) const;
|
|
|
|
|
void * LoadGlobalRes( RESOURCE_TYPE nRT, sal_uInt32 nId,
|
|
|
|
|
void **pResHandle );
|
|
|
|
|
public:
|
|
|
|
|
void FreeGlobalRes( void *, void * );
|
|
|
|
|
|
|
|
|
|
SvStream * GetBitmapStream( sal_uInt32 nResId );
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
|
|
class ResMgrContainer
|
2004-06-17 12:12:20 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
static ResMgrContainer* pOneInstance;
|
|
|
|
|
|
|
|
|
|
struct ContainerElement
|
|
|
|
|
{
|
|
|
|
|
InternalResMgr* pResMgr;
|
|
|
|
|
OUString aFileURL;
|
|
|
|
|
int nRefCount;
|
|
|
|
|
int nLoadCount;
|
|
|
|
|
|
|
|
|
|
ContainerElement() :
|
|
|
|
|
pResMgr( NULL ),
|
|
|
|
|
nRefCount( 0 ),
|
|
|
|
|
nLoadCount( 0 )
|
|
|
|
|
{}
|
|
|
|
|
};
|
|
|
|
|
|
2011-02-03 16:55:17 -07:00
|
|
|
|
boost::unordered_map< OUString, ContainerElement, OUStringHash> m_aResFiles;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
com::sun::star::lang::Locale m_aDefLocale;
|
|
|
|
|
|
|
|
|
|
ResMgrContainer() { init(); }
|
|
|
|
|
~ResMgrContainer();
|
|
|
|
|
|
|
|
|
|
void init();
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
static ResMgrContainer& get();
|
|
|
|
|
static void release();
|
|
|
|
|
|
|
|
|
|
InternalResMgr* getResMgr( const OUString& rPrefix,
|
|
|
|
|
com::sun::star::lang::Locale& rLocale,
|
|
|
|
|
bool bForceNewInstance = false
|
|
|
|
|
);
|
|
|
|
|
InternalResMgr* getNextFallback( InternalResMgr* pResMgr );
|
|
|
|
|
|
|
|
|
|
void freeResMgr( InternalResMgr* pResMgr );
|
|
|
|
|
|
|
|
|
|
void setDefLocale( const com::sun::star::lang::Locale& rLocale )
|
|
|
|
|
{ m_aDefLocale = rLocale; }
|
|
|
|
|
const com::sun::star::lang::Locale& getDefLocale() const
|
|
|
|
|
{ return m_aDefLocale; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
ResMgrContainer* ResMgrContainer::pOneInstance = NULL;
|
|
|
|
|
|
|
|
|
|
ResMgrContainer& ResMgrContainer::get()
|
|
|
|
|
{
|
|
|
|
|
if( ! pOneInstance )
|
|
|
|
|
pOneInstance = new ResMgrContainer();
|
|
|
|
|
return *pOneInstance;
|
2004-06-17 12:12:20 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
ResMgrContainer::~ResMgrContainer()
|
2004-06-17 12:12:20 +00:00
|
|
|
|
{
|
2011-02-03 16:55:17 -07:00
|
|
|
|
for( boost::unordered_map< OUString, ContainerElement, OUStringHash >::iterator it =
|
2005-01-03 16:14:02 +00:00
|
|
|
|
m_aResFiles.begin(); it != m_aResFiles.end(); ++it )
|
|
|
|
|
{
|
2006-03-29 11:43:16 +00:00
|
|
|
|
OSL_TRACE( "Resource file %s loaded %d times\n",
|
2005-01-03 16:14:02 +00:00
|
|
|
|
OUStringToOString( it->second.aFileURL, osl_getThreadTextEncoding() ).getStr(),
|
|
|
|
|
it->second.nLoadCount );
|
|
|
|
|
delete it->second.pResMgr;
|
|
|
|
|
}
|
2004-06-17 12:12:20 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
void ResMgrContainer::release()
|
2004-06-17 12:12:20 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
delete pOneInstance;
|
|
|
|
|
pOneInstance = NULL;
|
2004-06-17 12:12:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
void ResMgrContainer::init()
|
|
|
|
|
{
|
|
|
|
|
// get resource path
|
|
|
|
|
std::list< OUString > aDirs;
|
|
|
|
|
sal_Int32 nIndex = 0;
|
|
|
|
|
|
2008-03-18 11:27:59 +00:00
|
|
|
|
// 1. fixed locations
|
|
|
|
|
rtl::OUString uri(
|
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program/resource"));
|
|
|
|
|
rtl::Bootstrap::expandMacros(uri);
|
|
|
|
|
aDirs.push_back(uri);
|
|
|
|
|
uri = rtl::OUString(
|
|
|
|
|
RTL_CONSTASCII_USTRINGPARAM("$OOO_BASE_DIR/program/resource"));
|
|
|
|
|
rtl::Bootstrap::expandMacros(uri);
|
|
|
|
|
aDirs.push_back(uri);
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
// 2. in STAR_RESOURCEPATH
|
|
|
|
|
const sal_Char* pEnv = getenv( "STAR_RESOURCEPATH" );
|
|
|
|
|
if( pEnv )
|
|
|
|
|
{
|
|
|
|
|
OUString aEnvPath( OStringToOUString( OString( pEnv ), osl_getThreadTextEncoding() ) );
|
|
|
|
|
nIndex = 0;
|
|
|
|
|
while( nIndex >= 0 )
|
|
|
|
|
{
|
|
|
|
|
OUString aPathElement( aEnvPath.getToken( 0, SEARCH_PATH_DELIMITER, nIndex ) );
|
|
|
|
|
if( aPathElement.getLength() )
|
|
|
|
|
{
|
|
|
|
|
OUString aFileURL;
|
|
|
|
|
File::getFileURLFromSystemPath( aPathElement, aFileURL );
|
|
|
|
|
aDirs.push_back( aFileURL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// collect all possible resource files
|
|
|
|
|
for( std::list< OUString >::const_iterator dir_it = aDirs.begin(); dir_it != aDirs.end(); ++dir_it )
|
|
|
|
|
{
|
|
|
|
|
Directory aDir( *dir_it );
|
|
|
|
|
if( aDir.open() == FileBase::E_None )
|
|
|
|
|
{
|
|
|
|
|
DirectoryItem aItem;
|
|
|
|
|
while( aDir.getNextItem( aItem ) == FileBase::E_None )
|
|
|
|
|
{
|
|
|
|
|
FileStatus aStatus(FileStatusMask_FileName);
|
|
|
|
|
if( aItem.getFileStatus( aStatus ) == FileBase::E_None )
|
|
|
|
|
{
|
|
|
|
|
OUString aFileName = aStatus.getFileName();
|
|
|
|
|
if( aFileName.getLength() < 5 )
|
|
|
|
|
continue;
|
|
|
|
|
if( ! aFileName.endsWithIgnoreAsciiCaseAsciiL( ".res", 4 ) )
|
|
|
|
|
continue;
|
|
|
|
|
OUString aResName = aFileName.copy( 0, aFileName.getLength()-4 );
|
|
|
|
|
if( m_aResFiles.find( aResName ) != m_aResFiles.end() )
|
|
|
|
|
continue;
|
|
|
|
|
OUStringBuffer aURL( dir_it->getLength() + aFileName.getLength() + 1 );
|
|
|
|
|
aURL.append( *dir_it );
|
|
|
|
|
if( !dir_it->endsWithIgnoreAsciiCaseAsciiL( "/", 1 ) )
|
|
|
|
|
aURL.append( sal_Unicode('/') );
|
|
|
|
|
aURL.append( aFileName );
|
|
|
|
|
m_aResFiles[ aResName ].aFileURL = aURL.makeStringAndClear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#if OSL_DEBUG_LEVEL > 1
|
|
|
|
|
else
|
2006-03-29 11:43:16 +00:00
|
|
|
|
OSL_TRACE( "opening dir %s failed\n", OUStringToOString( *dir_it, osl_getThreadTextEncoding() ).getStr() );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
#if OSL_DEBUG_LEVEL > 1
|
2011-02-03 16:55:17 -07:00
|
|
|
|
for( boost::unordered_map< OUString, ContainerElement, OUStringHash >::const_iterator it =
|
2005-01-03 16:14:02 +00:00
|
|
|
|
m_aResFiles.begin(); it != m_aResFiles.end(); ++it )
|
|
|
|
|
{
|
2006-03-29 11:43:16 +00:00
|
|
|
|
OSL_TRACE( "ResMgrContainer: %s -> %s\n",
|
2005-01-03 16:14:02 +00:00
|
|
|
|
OUStringToOString( it->first, osl_getThreadTextEncoding() ).getStr(),
|
|
|
|
|
OUStringToOString( it->second.aFileURL, osl_getThreadTextEncoding() ).getStr() );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2008-12-12 12:52:51 +00:00
|
|
|
|
|
|
|
|
|
// set default language
|
|
|
|
|
LanguageType nLang = MsLangId::getSystemUILanguage();
|
|
|
|
|
MsLangId::convertLanguageToLocale(nLang, m_aDefLocale);
|
2005-01-03 16:14:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InternalResMgr* ResMgrContainer::getResMgr( const OUString& rPrefix,
|
|
|
|
|
com::sun::star::lang::Locale& rLocale,
|
|
|
|
|
bool bForceNewInstance
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
com::sun::star::lang::Locale aLocale( rLocale );
|
|
|
|
|
OUStringBuffer aSearch( rPrefix.getLength() + 16 );
|
2011-02-03 16:55:17 -07:00
|
|
|
|
boost::unordered_map< OUString, ContainerElement, OUStringHash >::iterator it = m_aResFiles.end();
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
2006-03-29 11:43:16 +00:00
|
|
|
|
int nTries = 0;
|
|
|
|
|
if( aLocale.Language.getLength() > 0 )
|
|
|
|
|
nTries = 1;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if( aLocale.Country.getLength() > 0 )
|
|
|
|
|
nTries = 2;
|
|
|
|
|
if( aLocale.Variant.getLength() > 0 )
|
|
|
|
|
nTries = 3;
|
|
|
|
|
while( nTries-- )
|
|
|
|
|
{
|
|
|
|
|
aSearch.append( rPrefix );
|
2006-03-29 11:43:16 +00:00
|
|
|
|
if( nTries > -1 )
|
|
|
|
|
{
|
|
|
|
|
aSearch.append( aLocale.Language );
|
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if( nTries > 0 )
|
|
|
|
|
{
|
|
|
|
|
aSearch.append( sal_Unicode('-') );
|
|
|
|
|
aSearch.append( aLocale.Country );
|
|
|
|
|
}
|
|
|
|
|
if( nTries > 1 )
|
|
|
|
|
{
|
|
|
|
|
aSearch.append( sal_Unicode('-') );
|
|
|
|
|
aSearch.append( aLocale.Variant );
|
|
|
|
|
}
|
|
|
|
|
it = m_aResFiles.find( aSearch.makeStringAndClear() );
|
|
|
|
|
if( it != m_aResFiles.end() )
|
|
|
|
|
{
|
|
|
|
|
// ensure InternalResMgr existance
|
|
|
|
|
if( ! it->second.pResMgr )
|
|
|
|
|
{
|
|
|
|
|
InternalResMgr* pImp =
|
|
|
|
|
new InternalResMgr( it->second.aFileURL, rPrefix, it->first, aLocale );
|
|
|
|
|
if( ! pImp->Create() )
|
2007-07-31 15:00:38 +00:00
|
|
|
|
{
|
|
|
|
|
delete pImp;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
continue;
|
2007-07-31 15:00:38 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
it->second.pResMgr = pImp;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if( nTries == 0 && !aLocale.Language.equalsIgnoreAsciiCaseAscii( "en" ) )
|
|
|
|
|
{
|
|
|
|
|
// locale fallback failed
|
|
|
|
|
// fallback to en-US locale
|
|
|
|
|
nTries = 2;
|
|
|
|
|
aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) );
|
|
|
|
|
aLocale.Country = OUString( RTL_CONSTASCII_USTRINGPARAM( "US" ) );
|
2006-03-29 11:43:16 +00:00
|
|
|
|
aLocale.Variant = OUString();
|
2005-01-03 16:14:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// try if there is anything with this prefix at all
|
|
|
|
|
if( it == m_aResFiles.end() )
|
|
|
|
|
{
|
|
|
|
|
aLocale = com::sun::star::lang::Locale();
|
|
|
|
|
it = m_aResFiles.find( rPrefix );
|
|
|
|
|
if( it == m_aResFiles.end() )
|
|
|
|
|
{
|
|
|
|
|
for( it = m_aResFiles.begin(); it != m_aResFiles.end(); ++it )
|
|
|
|
|
{
|
|
|
|
|
if( it->first.matchIgnoreAsciiCase( rPrefix ) )
|
|
|
|
|
{
|
|
|
|
|
// ensure InternalResMgr existance
|
|
|
|
|
if( ! it->second.pResMgr )
|
|
|
|
|
{
|
|
|
|
|
InternalResMgr* pImp =
|
|
|
|
|
new InternalResMgr( it->second.aFileURL,
|
|
|
|
|
rPrefix,
|
|
|
|
|
it->first,
|
|
|
|
|
aLocale );
|
|
|
|
|
if( ! pImp->Create() )
|
2007-07-31 15:00:38 +00:00
|
|
|
|
{
|
|
|
|
|
delete pImp;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
continue;
|
2007-07-31 15:00:38 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
it->second.pResMgr = pImp;
|
|
|
|
|
}
|
|
|
|
|
// try to guess locale
|
|
|
|
|
sal_Int32 nIndex = rPrefix.getLength();
|
|
|
|
|
aLocale.Language = it->first.getToken( 0, '-', nIndex );
|
|
|
|
|
if( nIndex > 0 )
|
|
|
|
|
aLocale.Country = it->first.getToken( 0, '-', nIndex );
|
|
|
|
|
if( nIndex > 0 )
|
|
|
|
|
aLocale.Variant = it->first.getToken( 0, '-', nIndex );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// give up
|
|
|
|
|
if( it == m_aResFiles.end() )
|
2007-07-06 09:12:31 +00:00
|
|
|
|
{
|
|
|
|
|
OUStringBuffer sKey = rPrefix;
|
|
|
|
|
sKey.append( rLocale.Language );
|
|
|
|
|
if( rLocale.Country.getLength() )
|
|
|
|
|
{
|
|
|
|
|
sKey.append( sal_Unicode('-') );
|
|
|
|
|
sKey.append( rLocale.Country );
|
|
|
|
|
}
|
|
|
|
|
if( rLocale.Variant.getLength() )
|
|
|
|
|
{
|
|
|
|
|
sKey.append( sal_Unicode('-') );
|
|
|
|
|
sKey.append( rLocale.Variant );
|
|
|
|
|
} // if( aLocale.Variant.getLength() )
|
|
|
|
|
::rtl::OUString sURL = sKey.makeStringAndClear();
|
|
|
|
|
sURL += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".res"));
|
|
|
|
|
if ( m_aResFiles.find(sURL) == m_aResFiles.end() )
|
|
|
|
|
{
|
|
|
|
|
m_aResFiles[ sURL ].aFileURL = sURL;
|
|
|
|
|
return getResMgr(rPrefix,rLocale,bForceNewInstance);
|
|
|
|
|
} // if ( m_aResFiles.find(sURL) == m_aResFiles.end() )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
return NULL;
|
2007-07-06 09:12:31 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
rLocale = aLocale;
|
|
|
|
|
// at this point it->second.pResMgr must be filled either by creating a new one
|
|
|
|
|
// (then the refcount is still 0) or because we already had one
|
|
|
|
|
InternalResMgr* pImp = it->second.pResMgr;
|
|
|
|
|
|
|
|
|
|
if( it->second.nRefCount == 0 )
|
|
|
|
|
it->second.nLoadCount++;
|
|
|
|
|
|
|
|
|
|
// for SimpleResMgr
|
|
|
|
|
if( bForceNewInstance )
|
|
|
|
|
{
|
|
|
|
|
if( it->second.nRefCount == 0 )
|
|
|
|
|
{
|
|
|
|
|
// shortcut: the match algorithm already created the InternalResMgr
|
|
|
|
|
// take it instead of creating yet another one
|
|
|
|
|
it->second.pResMgr = NULL;
|
|
|
|
|
pImp->bSingular = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pImp = new InternalResMgr( it->second.aFileURL, rPrefix, it->first, aLocale );
|
|
|
|
|
pImp->bSingular = true;
|
|
|
|
|
if( !pImp->Create() )
|
2007-07-31 15:00:38 +00:00
|
|
|
|
{
|
|
|
|
|
delete pImp;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pImp = NULL;
|
2007-07-31 15:00:38 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
else
|
|
|
|
|
it->second.nLoadCount++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
it->second.nRefCount++;
|
|
|
|
|
|
|
|
|
|
return pImp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
InternalResMgr* ResMgrContainer::getNextFallback( InternalResMgr* pMgr )
|
|
|
|
|
{
|
|
|
|
|
com::sun::star::lang::Locale aLocale = pMgr->aLocale;
|
|
|
|
|
if( aLocale.Variant.getLength() )
|
|
|
|
|
aLocale.Variant = OUString();
|
|
|
|
|
else if( aLocale.Country.getLength() )
|
|
|
|
|
aLocale.Country = OUString();
|
|
|
|
|
else if( ! aLocale.Language.equalsIgnoreAsciiCaseAscii( "en" ) )
|
|
|
|
|
{
|
|
|
|
|
aLocale.Language = OUString( RTL_CONSTASCII_USTRINGPARAM( "en" ) );
|
|
|
|
|
aLocale.Country = OUString( RTL_CONSTASCII_USTRINGPARAM( "US" ) );
|
|
|
|
|
}
|
|
|
|
|
InternalResMgr* pNext = getResMgr( pMgr->aPrefix, aLocale, pMgr->bSingular );
|
|
|
|
|
// prevent recursion
|
|
|
|
|
if( pNext == pMgr || pNext->aResName.equals( pMgr->aResName ) )
|
|
|
|
|
{
|
|
|
|
|
if( pNext->bSingular )
|
|
|
|
|
delete pNext;
|
|
|
|
|
pNext = NULL;
|
|
|
|
|
}
|
|
|
|
|
return pNext;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ResMgrContainer::freeResMgr( InternalResMgr* pResMgr )
|
|
|
|
|
{
|
|
|
|
|
if( pResMgr->bSingular )
|
|
|
|
|
delete pResMgr;
|
|
|
|
|
else
|
|
|
|
|
{
|
2011-02-03 16:55:17 -07:00
|
|
|
|
boost::unordered_map< OUString, ContainerElement, OUStringHash >::iterator it =
|
2005-01-03 16:14:02 +00:00
|
|
|
|
m_aResFiles.find( pResMgr->aResName );
|
|
|
|
|
if( it != m_aResFiles.end() )
|
|
|
|
|
{
|
|
|
|
|
DBG_ASSERT( it->second.nRefCount > 0, "InternalResMgr freed too often" );
|
|
|
|
|
if( it->second.nRefCount > 0 )
|
|
|
|
|
it->second.nRefCount--;
|
|
|
|
|
if( it->second.nRefCount == 0 )
|
|
|
|
|
{
|
|
|
|
|
delete it->second.pResMgr;
|
|
|
|
|
it->second.pResMgr = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-17 12:12:20 +00:00
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
// =======================================================================
|
|
|
|
|
|
2004-06-25 16:13:01 +00:00
|
|
|
|
void Resource::TestRes()
|
|
|
|
|
{
|
2007-04-26 08:48:23 +00:00
|
|
|
|
if( m_pResMgr )
|
|
|
|
|
m_pResMgr->TestStack( this );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct ImpContent
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt64 nTypeAndId;
|
2005-03-18 16:45:56 +00:00
|
|
|
|
sal_uInt32 nOffset;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
};
|
|
|
|
|
|
2003-03-27 16:05:12 +00:00
|
|
|
|
struct ImpContentLessCompare : public ::std::binary_function< ImpContent, ImpContent, bool>
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2003-03-27 16:05:12 +00:00
|
|
|
|
inline bool operator() (const ImpContent& lhs, const ImpContent& rhs) const
|
|
|
|
|
{
|
|
|
|
|
return lhs.nTypeAndId < rhs.nTypeAndId;
|
|
|
|
|
}
|
|
|
|
|
};
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
struct ImpContentMixLessCompare : public ::std::binary_function< ImpContent, sal_uInt64, bool>
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
inline bool operator() (const ImpContent& lhs, const sal_uInt64& rhs) const
|
2003-03-27 16:05:12 +00:00
|
|
|
|
{
|
|
|
|
|
return lhs.nTypeAndId < rhs;
|
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
inline bool operator() (const sal_uInt64& lhs, const ImpContent& rhs) const
|
2003-03-27 16:05:12 +00:00
|
|
|
|
{
|
|
|
|
|
return lhs < rhs.nTypeAndId;
|
|
|
|
|
}
|
|
|
|
|
};
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2003-03-27 16:05:12 +00:00
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
// =======================================================================
|
|
|
|
|
|
2000-12-05 18:23:20 +00:00
|
|
|
|
static ResHookProc pImplResHookProc = 0;
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
SvStream * InternalResMgr::GetBitmapStream( sal_uInt32 nId )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
// Anfang der Strings suchen
|
2003-03-27 16:05:12 +00:00
|
|
|
|
ImpContent * pFind = ::std::lower_bound(pContent,
|
|
|
|
|
pContent + nEntries,
|
2005-01-03 16:14:02 +00:00
|
|
|
|
((sal_uInt64(RT_SYS_BITMAP) << 32) | nId),
|
2003-03-27 16:05:12 +00:00
|
|
|
|
ImpContentMixLessCompare());
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if ( (pFind != (pContent + nEntries)) && (pFind->nTypeAndId == ((sal_uInt64(RT_SYS_BITMAP) << 32) | nId)) )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
pStm->Seek( pFind->nOffset );
|
|
|
|
|
return pStm;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
InternalResMgr::InternalResMgr( const OUString& rFileURL,
|
|
|
|
|
const OUString& rPrefix,
|
|
|
|
|
const OUString& rResName,
|
|
|
|
|
const com::sun::star::lang::Locale& rLocale )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
: pContent( NULL )
|
|
|
|
|
, pStringBlock( NULL )
|
|
|
|
|
, pStm( NULL )
|
|
|
|
|
, bEqual2Content( TRUE )
|
|
|
|
|
, nEntries( 0 )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
, aFileName( rFileURL )
|
|
|
|
|
, aPrefix( rPrefix )
|
|
|
|
|
, aResName( rResName )
|
|
|
|
|
, bSingular( false )
|
|
|
|
|
, aLocale( rLocale )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
, pResUseDump( 0 )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
InternalResMgr::~InternalResMgr()
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
rtl_freeMemory(pContent);
|
|
|
|
|
rtl_freeMemory(pStringBlock);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
delete pStm;
|
|
|
|
|
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
if( pResUseDump )
|
|
|
|
|
{
|
|
|
|
|
const sal_Char* pLogFile = getenv( "STAR_RESOURCE_LOGGING" );
|
|
|
|
|
if ( pLogFile )
|
|
|
|
|
{
|
|
|
|
|
SvFileStream aStm( UniString( pLogFile, RTL_TEXTENCODING_ASCII_US ), STREAM_WRITE );
|
|
|
|
|
aStm.Seek( STREAM_SEEK_TO_END );
|
|
|
|
|
ByteString aLine( "FileName: " );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
aLine.Append( ByteString( OUStringToOString( aFileName, RTL_TEXTENCODING_UTF8 ) ) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aStm.WriteLine( aLine );
|
|
|
|
|
|
2011-02-03 16:55:17 -07:00
|
|
|
|
for( boost::unordered_map<sal_uInt64, int>::const_iterator it = pResUseDump->begin();
|
2005-01-03 16:14:02 +00:00
|
|
|
|
it != pResUseDump->end(); ++it )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt64 nKeyId = it->first;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aLine.Assign( "Type/Id: " );
|
2006-06-19 12:48:55 +00:00
|
|
|
|
aLine.Append( ByteString::CreateFromInt32( sal::static_int_cast< sal_Int32 >((nKeyId >> 32) & 0xFFFFFFFF) ) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aLine.Append( '/' );
|
2006-06-19 12:48:55 +00:00
|
|
|
|
aLine.Append( ByteString::CreateFromInt32( sal::static_int_cast< sal_Int32 >(nKeyId & 0xFFFFFFFF) ) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aStm.WriteLine( aLine );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
delete pResUseDump;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BOOL InternalResMgr::Create()
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
ResMgrContainer::get();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
BOOL bDone = FALSE;
|
|
|
|
|
|
|
|
|
|
pStm = new SvFileStream( aFileName, (STREAM_READ | STREAM_SHARE_DENYWRITE | STREAM_NOCREATE) );
|
|
|
|
|
if( pStm->GetError() == 0 )
|
|
|
|
|
{
|
|
|
|
|
INT32 lContLen = 0;
|
|
|
|
|
|
|
|
|
|
pStm->Seek( STREAM_SEEK_TO_END );
|
|
|
|
|
/*
|
|
|
|
|
if( ( pInternalResMgr->pHead = (RSHEADER_TYPE *)mmap( 0, nResourceFileSize,
|
|
|
|
|
PROT_READ, MAP_PRIVATE,
|
|
|
|
|
fRes, 0 ) ) != (RSHEADER_TYPE *)-1)
|
|
|
|
|
*/
|
|
|
|
|
pStm->SeekRel( - (int)sizeof( lContLen ) );
|
|
|
|
|
pStm->Read( &lContLen, sizeof( lContLen ) );
|
|
|
|
|
// is bigendian, swab to the right endian
|
|
|
|
|
lContLen = ResMgr::GetLong( &lContLen );
|
|
|
|
|
pStm->SeekRel( -lContLen );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// allocate stored ImpContent data (12 bytes per unit)
|
|
|
|
|
BYTE* pContentBuf = (BYTE*)rtl_allocateMemory( lContLen );
|
|
|
|
|
pStm->Read( pContentBuf, lContLen );
|
|
|
|
|
// allocate ImpContent space (sizeof(ImpContent) per unit, not necessarily 12)
|
|
|
|
|
pContent = (ImpContent *)rtl_allocateMemory( sizeof(ImpContent)*lContLen/12 );
|
|
|
|
|
// Auf die Anzahl der ImpContent k<>rzen
|
|
|
|
|
nEntries = (UINT32)lContLen / 12;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
bEqual2Content = TRUE; // Die Daten der Resourcen liegen
|
|
|
|
|
// genauso wie das Inhaltsverzeichnis
|
|
|
|
|
BOOL bSorted = TRUE;
|
|
|
|
|
if( nEntries )
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
const sal_Char* pLogFile = getenv( "STAR_RESOURCE_LOGGING" );
|
|
|
|
|
if ( pLogFile )
|
|
|
|
|
{
|
2011-02-03 16:55:17 -07:00
|
|
|
|
pResUseDump = new boost::unordered_map<sal_uInt64, int>;
|
2005-03-18 16:45:56 +00:00
|
|
|
|
for( sal_uInt32 i = 0; i < nEntries; ++i )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
(*pResUseDump)[pContent[i].nTypeAndId] = 1;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
// swap the content to the right endian
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pContent[0].nTypeAndId = ResMgr::GetUInt64( pContentBuf );
|
|
|
|
|
pContent[0].nOffset = ResMgr::GetLong( pContentBuf+8 );
|
2005-03-18 16:45:56 +00:00
|
|
|
|
sal_uInt32 nCount = nEntries - 1;
|
|
|
|
|
for( sal_uInt32 i = 0,j=1; i < nCount; ++i,++j )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
// swap the content to the right endian
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pContent[j].nTypeAndId = ResMgr::GetUInt64( pContentBuf + (12*j) );
|
|
|
|
|
pContent[j].nOffset = ResMgr::GetLong( pContentBuf + (12*j+8) );
|
2003-03-27 16:05:12 +00:00
|
|
|
|
if( pContent[i].nTypeAndId >= pContent[j].nTypeAndId )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
bSorted = FALSE;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if( (pContent[i].nTypeAndId & 0xFFFFFFFF00000000LL) == (pContent[j].nTypeAndId & 0xFFFFFFFF00000000LL)
|
2003-03-27 16:05:12 +00:00
|
|
|
|
&& pContent[i].nOffset >= pContent[j].nOffset )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
bEqual2Content = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
rtl_freeMemory( pContentBuf );
|
2008-07-22 16:40:03 +00:00
|
|
|
|
#ifndef OS2
|
2005-01-03 16:14:02 +00:00
|
|
|
|
OSL_ENSURE( bSorted, "content not sorted" );
|
2008-07-22 16:40:03 +00:00
|
|
|
|
#endif
|
2005-01-03 16:14:02 +00:00
|
|
|
|
OSL_ENSURE( bEqual2Content, "resource structure wrong" );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
if( !bSorted )
|
2003-03-27 16:05:12 +00:00
|
|
|
|
::std::sort(pContent,pContent+nEntries,ImpContentLessCompare());
|
|
|
|
|
// qsort( pContent, nEntries, sizeof( ImpContent ), Compare );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
bDone = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bDone;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
BOOL InternalResMgr::IsGlobalAvailable( RESOURCE_TYPE nRT, sal_uInt32 nId ) const
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
// Anfang der Strings suchen
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt64 nValue = ((sal_uInt64(nRT) << 32) | nId);
|
2003-03-27 16:05:12 +00:00
|
|
|
|
ImpContent * pFind = ::std::lower_bound(pContent,
|
|
|
|
|
pContent + nEntries,
|
|
|
|
|
nValue,
|
|
|
|
|
ImpContentMixLessCompare());
|
|
|
|
|
return (pFind != (pContent + nEntries)) && (pFind->nTypeAndId == nValue);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
void* InternalResMgr::LoadGlobalRes( RESOURCE_TYPE nRT, sal_uInt32 nId,
|
2000-09-18 16:07:07 +00:00
|
|
|
|
void **pResHandle )
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
if( pResUseDump )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pResUseDump->erase( (sal_uInt64(nRT) << 32) | nId );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
#endif
|
|
|
|
|
// Anfang der Strings suchen
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt64 nValue = ((sal_uInt64(nRT) << 32) | nId);
|
2003-03-27 16:05:12 +00:00
|
|
|
|
ImpContent* pEnd = (pContent + nEntries);
|
|
|
|
|
ImpContent* pFind = ::std::lower_bound( pContent,
|
|
|
|
|
pEnd,
|
|
|
|
|
nValue,
|
|
|
|
|
ImpContentMixLessCompare());
|
2004-08-02 16:26:52 +00:00
|
|
|
|
if( pFind && (pFind != pEnd) && (pFind->nTypeAndId == nValue) )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2004-08-02 16:26:52 +00:00
|
|
|
|
if( nRT == RSC_STRING && bEqual2Content )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2004-08-02 16:26:52 +00:00
|
|
|
|
// String Optimierung
|
|
|
|
|
if( !pStringBlock )
|
|
|
|
|
{
|
|
|
|
|
// Anfang der Strings suchen
|
|
|
|
|
ImpContent * pFirst = pFind;
|
|
|
|
|
ImpContent * pLast = pFirst;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
while( pFirst > pContent && ((pFirst -1)->nTypeAndId >> 32) == RSC_STRING )
|
2004-08-02 16:26:52 +00:00
|
|
|
|
--pFirst;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
while( pLast < pEnd && (pLast->nTypeAndId >> 32) == RSC_STRING )
|
2004-08-02 16:26:52 +00:00
|
|
|
|
++pLast;
|
|
|
|
|
nOffCorrection = pFirst->nOffset;
|
|
|
|
|
UINT32 nSize;
|
|
|
|
|
--pLast;
|
|
|
|
|
pStm->Seek( pLast->nOffset );
|
|
|
|
|
RSHEADER_TYPE aHdr;
|
|
|
|
|
pStm->Read( &aHdr, sizeof( aHdr ) );
|
|
|
|
|
nSize = pLast->nOffset + aHdr.GetGlobOff() - nOffCorrection;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pStringBlock = (BYTE*)rtl_allocateMemory( nSize );
|
2004-08-02 16:26:52 +00:00
|
|
|
|
pStm->Seek( pFirst->nOffset );
|
|
|
|
|
pStm->Read( pStringBlock, nSize );
|
|
|
|
|
}
|
|
|
|
|
*pResHandle = pStringBlock;
|
|
|
|
|
return (BYTE*)pStringBlock + pFind->nOffset - nOffCorrection;
|
|
|
|
|
} // if( nRT == RSC_STRING && bEqual2Content )
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
*pResHandle = 0;
|
|
|
|
|
RSHEADER_TYPE aHeader;
|
|
|
|
|
pStm->Seek( pFind->nOffset );
|
|
|
|
|
pStm->Read( &aHeader, sizeof( RSHEADER_TYPE ) );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
void * pRes = rtl_allocateMemory( aHeader.GetGlobOff() );
|
2004-08-02 16:26:52 +00:00
|
|
|
|
memcpy( pRes, &aHeader, sizeof( RSHEADER_TYPE ) );
|
|
|
|
|
pStm->Read( (BYTE*)pRes + sizeof( RSHEADER_TYPE ),
|
|
|
|
|
aHeader.GetGlobOff() - sizeof( RSHEADER_TYPE ) );
|
|
|
|
|
return pRes;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
2004-08-02 16:26:52 +00:00
|
|
|
|
} // if( pFind && (pFind != pEnd) && (pFind->nTypeAndId == nValue) )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*pResHandle = 0;
|
|
|
|
|
//Resource holen
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void InternalResMgr::FreeGlobalRes( void * pResHandle, void * pResource )
|
|
|
|
|
{
|
|
|
|
|
if ( !pResHandle )
|
|
|
|
|
// REsource wurde extra allokiert
|
2005-01-03 16:14:02 +00:00
|
|
|
|
rtl_freeMemory(pResource);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
|
|
|
|
|
UniString GetTypeRes_Impl( const ResId& rTypeId )
|
|
|
|
|
{
|
|
|
|
|
// Funktion verlassen, falls Resourcefehler in dieser Funktion
|
2002-05-22 13:44:52 +00:00
|
|
|
|
static int bInUse = FALSE;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
UniString aTypStr( UniString::CreateFromInt32( rTypeId.GetId() ) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
if ( !bInUse )
|
|
|
|
|
{
|
|
|
|
|
bInUse = TRUE;
|
|
|
|
|
|
2007-04-26 08:48:23 +00:00
|
|
|
|
ResId aResId( sal_uInt32(RSCVERSION_ID), *rTypeId.GetResMgr() );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aResId.SetRT( RSC_VERSIONCONTROL );
|
|
|
|
|
|
|
|
|
|
if ( rTypeId.GetResMgr()->GetResource( aResId ) )
|
|
|
|
|
{
|
|
|
|
|
rTypeId.SetRT( RSC_STRING );
|
|
|
|
|
if ( rTypeId.GetResMgr()->IsAvailable( rTypeId ) )
|
|
|
|
|
{
|
|
|
|
|
aTypStr = UniString( rTypeId );
|
|
|
|
|
// Versions Resource Klassenzeiger ans Ende setzen
|
2007-04-26 08:48:23 +00:00
|
|
|
|
rTypeId.GetResMgr()->Increment( sizeof( RSHEADER_TYPE ) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bInUse = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return aTypStr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
void ResMgr::RscError_Impl( const sal_Char* pMessage, ResMgr* pResMgr,
|
|
|
|
|
RESOURCE_TYPE nRT, sal_uInt32 nId,
|
|
|
|
|
std::vector< ImpRCStack >& rResStack, int nDepth )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// create a separate ResMgr with its own stack
|
|
|
|
|
// first get a second reference of the InternalResMgr
|
|
|
|
|
InternalResMgr* pImp =
|
|
|
|
|
ResMgrContainer::get().getResMgr( pResMgr->pImpRes->aPrefix,
|
|
|
|
|
pResMgr->pImpRes->aLocale,
|
|
|
|
|
true );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
ResMgr* pNewResMgr = new ResMgr( pImp );
|
|
|
|
|
|
|
|
|
|
ByteString aStr = OUStringToOString( pResMgr->GetFileName(), RTL_TEXTENCODING_UTF8 );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
if ( aStr.Len() )
|
|
|
|
|
aStr += '\n';
|
|
|
|
|
|
|
|
|
|
aStr.Append( "Class: " );
|
2007-04-26 08:48:23 +00:00
|
|
|
|
aStr.Append( ByteString( GetTypeRes_Impl( ResId( nRT, *pNewResMgr ) ), RTL_TEXTENCODING_UTF8 ) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aStr.Append( ", Id: " );
|
|
|
|
|
aStr.Append( ByteString::CreateFromInt32( (long)nId ) );
|
|
|
|
|
aStr.Append( ". " );
|
|
|
|
|
aStr.Append( pMessage );
|
|
|
|
|
|
|
|
|
|
aStr.Append( "\nResource Stack\n" );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
while( nDepth > 0 )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
aStr.Append( "Class: " );
|
2007-04-26 08:48:23 +00:00
|
|
|
|
aStr.Append( ByteString( GetTypeRes_Impl( ResId( rResStack[nDepth].pResource->GetRT(), *pNewResMgr ) ), RTL_TEXTENCODING_UTF8 ) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aStr.Append( ", Id: " );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
aStr.Append( ByteString::CreateFromInt32( (long)rResStack[nDepth].pResource->GetId() ) );
|
|
|
|
|
nDepth--;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// clean up
|
2000-09-18 16:07:07 +00:00
|
|
|
|
delete pNewResMgr;
|
|
|
|
|
|
|
|
|
|
DBG_ERROR( aStr.GetBuffer() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
|
|
static void RscException_Impl()
|
|
|
|
|
{
|
2010-10-11 01:26:24 -05:00
|
|
|
|
switch ( osl_raiseSignal( OSL_SIGNAL_USER_RESOURCEFAILURE, (void*)"" ) )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2010-10-11 01:26:24 -05:00
|
|
|
|
case osl_Signal_ActCallNextHdl:
|
|
|
|
|
abort();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2010-10-11 01:26:24 -05:00
|
|
|
|
case osl_Signal_ActIgnore:
|
|
|
|
|
return;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2010-10-11 01:26:24 -05:00
|
|
|
|
case osl_Signal_ActAbortApp:
|
|
|
|
|
abort();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2010-10-11 01:26:24 -05:00
|
|
|
|
default:
|
|
|
|
|
case osl_Signal_ActKillApp:
|
|
|
|
|
exit(-1);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
void ImpRCStack::Init( ResMgr* pMgr, const Resource* pObj, sal_uInt32 Id )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pResource = NULL;
|
|
|
|
|
pClassRes = NULL;
|
|
|
|
|
Flags = RC_NOTYPE;
|
|
|
|
|
aResHandle = NULL;
|
|
|
|
|
pResObj = pObj;
|
|
|
|
|
nId = Id & ~RSC_DONTRELEASE; //TLX: Besser Init aendern
|
|
|
|
|
pResMgr = pMgr;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
if ( !(Id & RSC_DONTRELEASE) )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
Flags |= RC_AUTORELEASE;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void ImpRCStack::Clear()
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pResource = NULL;
|
|
|
|
|
pClassRes = NULL;
|
|
|
|
|
Flags = RC_NOTYPE;
|
|
|
|
|
aResHandle = NULL;
|
|
|
|
|
pResObj = NULL;
|
|
|
|
|
nId = 0;
|
|
|
|
|
pResMgr = NULL;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
static RSHEADER_TYPE* LocalResource( const ImpRCStack* pStack,
|
|
|
|
|
RESOURCE_TYPE nRTType,
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt32 nId )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
// Gibt die Position der Resource zurueck, wenn sie gefunden wurde.
|
|
|
|
|
// Ansonsten gibt die Funktion Null zurueck.
|
|
|
|
|
RSHEADER_TYPE* pTmp; // Zeiger auf Kind-Resourceobjekte
|
|
|
|
|
RSHEADER_TYPE* pEnd; // Zeiger auf das Ende der Resource
|
|
|
|
|
|
|
|
|
|
if ( pStack->pResource && pStack->pClassRes )
|
|
|
|
|
{
|
|
|
|
|
pTmp = (RSHEADER_TYPE*)
|
|
|
|
|
((BYTE*)pStack->pResource + pStack->pResource->GetLocalOff());
|
|
|
|
|
pEnd = (RSHEADER_TYPE*)
|
|
|
|
|
((BYTE*)pStack->pResource + pStack->pResource->GetGlobOff());
|
|
|
|
|
while ( pTmp != pEnd )
|
|
|
|
|
{
|
|
|
|
|
if ( pTmp->GetRT() == nRTType && pTmp->GetId() == nId )
|
|
|
|
|
return pTmp;
|
|
|
|
|
pTmp = (RSHEADER_TYPE*)((BYTE*)pTmp + pTmp->GetGlobOff());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
void* ResMgr::pEmptyBuffer = NULL;
|
|
|
|
|
|
|
|
|
|
void* ResMgr::getEmptyBuffer()
|
|
|
|
|
{
|
|
|
|
|
if( ! pEmptyBuffer )
|
|
|
|
|
pEmptyBuffer = rtl_allocateZeroMemory( 1024 );
|
|
|
|
|
return pEmptyBuffer;
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
void ResMgr::DestroyAllResMgr()
|
|
|
|
|
{
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
if( pEmptyBuffer )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
rtl_freeMemory( pEmptyBuffer );
|
|
|
|
|
pEmptyBuffer = NULL;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
ResMgrContainer::release();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
delete pResMgrMutex;
|
|
|
|
|
pResMgrMutex = NULL;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
void ResMgr::Init( const OUString& rFileName )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2006-06-19 12:48:55 +00:00
|
|
|
|
(void) rFileName; // avoid warning about unused parameter
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
if ( !pImpRes )
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
ByteString aStr( "Resourcefile not found:\n" );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
aStr += ByteString( OUStringToOString( rFileName, RTL_TEXTENCODING_UTF8 ) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
DBG_ERROR( aStr.GetBuffer() );
|
|
|
|
|
#endif
|
|
|
|
|
RscException_Impl();
|
|
|
|
|
}
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
void* aResHandle = 0; // Hilfvariable fuer Resource
|
|
|
|
|
void* pVoid; // Zeiger auf die Resource
|
|
|
|
|
|
|
|
|
|
pVoid = pImpRes->LoadGlobalRes( RSC_VERSIONCONTROL, RSCVERSION_ID,
|
|
|
|
|
&aResHandle );
|
|
|
|
|
if ( pVoid )
|
|
|
|
|
pImpRes->FreeGlobalRes( aResHandle, pVoid );
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ByteString aStr( "Wrong version:\n" );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
aStr += ByteString( OUStringToOString( pImpRes->aFileName, RTL_TEXTENCODING_UTF8 ) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
DbgError( aStr.GetBuffer() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2005-01-03 16:14:02 +00:00
|
|
|
|
nCurStack = -1;
|
|
|
|
|
aStack.clear();
|
|
|
|
|
pFallbackResMgr = pOriginalResMgr = NULL;
|
|
|
|
|
incStack();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResMgr::ResMgr( InternalResMgr * pImpMgr )
|
|
|
|
|
{
|
|
|
|
|
pImpRes = pImpMgr;
|
|
|
|
|
Init( pImpMgr->aFileName );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResMgr::~ResMgr()
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
ResMgrContainer::get().freeResMgr( pImpRes );
|
|
|
|
|
|
|
|
|
|
// clean up possible left rc stack frames
|
|
|
|
|
while( nCurStack > 0 )
|
|
|
|
|
{
|
|
|
|
|
if( ( aStack[nCurStack].Flags & (RC_GLOBAL | RC_NOTFOUND) ) == RC_GLOBAL )
|
|
|
|
|
pImpRes->FreeGlobalRes( aStack[nCurStack].aResHandle,
|
|
|
|
|
aStack[nCurStack].pResource );
|
|
|
|
|
nCurStack--;
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
void ResMgr::incStack()
|
|
|
|
|
{
|
|
|
|
|
nCurStack++;
|
|
|
|
|
if( nCurStack >= int(aStack.size()) )
|
|
|
|
|
aStack.push_back( ImpRCStack() );
|
|
|
|
|
aStack[nCurStack].Clear();
|
|
|
|
|
|
|
|
|
|
DBG_ASSERT( nCurStack < 32, "Resource stack unreasonably large" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ResMgr::decStack()
|
|
|
|
|
{
|
|
|
|
|
DBG_ASSERT( nCurStack > 0, "resource stack underrun !" );
|
|
|
|
|
if( (aStack[nCurStack].Flags & RC_FALLBACK_UP) )
|
|
|
|
|
{
|
|
|
|
|
nCurStack--;
|
|
|
|
|
// warning: this will delete *this, see below
|
|
|
|
|
pOriginalResMgr->decStack();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2005-03-18 16:45:56 +00:00
|
|
|
|
ImpRCStack& rTop = aStack[nCurStack];
|
|
|
|
|
if( (rTop.Flags & RC_FALLBACK_DOWN) )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
{
|
|
|
|
|
#if OSL_DEBUG_LEVEL > 1
|
2006-03-29 11:43:16 +00:00
|
|
|
|
OSL_TRACE( "returning from fallback %s\n",
|
2005-01-03 16:14:02 +00:00
|
|
|
|
OUStringToOString(pFallbackResMgr->GetFileName(), osl_getThreadTextEncoding() ).getStr() );
|
|
|
|
|
#endif
|
|
|
|
|
delete pFallbackResMgr;
|
|
|
|
|
pFallbackResMgr = NULL;
|
|
|
|
|
}
|
|
|
|
|
nCurStack--;
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
|
|
|
|
|
void ResMgr::TestStack( const Resource* pResObj )
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
if ( DbgIsResource() )
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
for( int i = 1; i <= nCurStack; ++i )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
if ( aStack[i].pResObj == pResObj )
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
RscError_Impl( "Resource not freed! ", this,
|
|
|
|
|
aStack[i].pResource->GetRT(),
|
|
|
|
|
aStack[i].pResource->GetId(),
|
2005-01-03 16:14:02 +00:00
|
|
|
|
aStack, i-1 );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
void ResMgr::TestStack( const Resource* )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-01-18 12:30:47 +00:00
|
|
|
|
// -----------------------------------------------------------------------
|
2000-09-18 16:07:07 +00:00
|
|
|
|
BOOL ResMgr::IsAvailable( const ResId& rId, const Resource* pResObj ) const
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
BOOL bAvailable = FALSE;
|
|
|
|
|
RSHEADER_TYPE* pClassRes = rId.GetpResource();
|
|
|
|
|
RESOURCE_TYPE nRT = rId.GetRT2();
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt32 nId = rId.GetId();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
const ResMgr* pMgr = rId.GetResMgr();
|
|
|
|
|
|
|
|
|
|
if ( !pMgr )
|
|
|
|
|
pMgr = this;
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if( pMgr->pFallbackResMgr )
|
|
|
|
|
{
|
|
|
|
|
ResId aId( rId );
|
|
|
|
|
aId.SetResMgr( NULL );
|
|
|
|
|
return pMgr->pFallbackResMgr->IsAvailable( aId, pResObj );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !pResObj || pResObj == pMgr->aStack[pMgr->nCurStack].pResObj )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
if ( !pClassRes )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pClassRes = LocalResource( &pMgr->aStack[pMgr->nCurStack], nRT, nId );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
if ( pClassRes )
|
|
|
|
|
{
|
|
|
|
|
if ( pClassRes->GetRT() == nRT )
|
|
|
|
|
bAvailable = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// vieleicht globale Resource
|
|
|
|
|
if ( !pClassRes )
|
|
|
|
|
bAvailable = pMgr->pImpRes->IsGlobalAvailable( nRT, nId );
|
|
|
|
|
|
|
|
|
|
return bAvailable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
void* ResMgr::GetClass()
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
return pFallbackResMgr->GetClass();
|
|
|
|
|
|
|
|
|
|
return aStack[nCurStack].pClassRes;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
BOOL ResMgr::GetResource( const ResId& rId, const Resource* pResObj )
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
{
|
|
|
|
|
ResId aId( rId );
|
|
|
|
|
aId.SetResMgr( NULL );
|
|
|
|
|
return pFallbackResMgr->GetResource( aId, pResObj );
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
ResMgr* pMgr = rId.GetResMgr();
|
|
|
|
|
if ( pMgr && (this != pMgr) )
|
|
|
|
|
return pMgr->GetResource( rId, pResObj );
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// normally Increment will pop the context; this is
|
|
|
|
|
// not possible in RC_NOTFOUND case, so pop a frame here
|
|
|
|
|
ImpRCStack* pTop = &aStack[nCurStack];
|
|
|
|
|
if( (pTop->Flags & RC_NOTFOUND) )
|
|
|
|
|
{
|
|
|
|
|
decStack();
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
RSHEADER_TYPE* pClassRes = rId.GetpResource();
|
|
|
|
|
RESOURCE_TYPE nRT = rId.GetRT2();
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt32 nId = rId.GetId();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
incStack();
|
|
|
|
|
pTop = &aStack[nCurStack];
|
2007-04-26 08:48:23 +00:00
|
|
|
|
pTop->Init( pMgr, pResObj, nId |
|
2000-09-18 16:07:07 +00:00
|
|
|
|
(rId.IsAutoRelease() ? 0 : RSC_DONTRELEASE) );
|
|
|
|
|
|
|
|
|
|
if ( pClassRes )
|
|
|
|
|
{
|
|
|
|
|
if ( pClassRes->GetRT() == nRT )
|
|
|
|
|
pTop->pClassRes = pClassRes;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
RscError_Impl( "Different class and resource type!",
|
2005-01-03 16:14:02 +00:00
|
|
|
|
this, nRT, nId, aStack, nCurStack-1 );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
#endif
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pTop->Flags |= RC_NOTFOUND;
|
|
|
|
|
pTop->pClassRes = getEmptyBuffer();
|
|
|
|
|
pTop->pResource = (RSHEADER_TYPE*)pTop->pClassRes;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2005-01-03 16:14:02 +00:00
|
|
|
|
{
|
|
|
|
|
OSL_ENSURE( nCurStack > 0, "stack of 1 to shallow" );
|
|
|
|
|
pTop->pClassRes = LocalResource( &aStack[nCurStack-1], nRT, nId );
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
if ( pTop->pClassRes )
|
|
|
|
|
// lokale Resource, nicht system Resource
|
|
|
|
|
pTop->pResource = (RSHEADER_TYPE *)pTop->pClassRes;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pTop->pClassRes = pImpRes->LoadGlobalRes( nRT, nId, &pTop->aResHandle );
|
|
|
|
|
if ( pTop->pClassRes )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
{
|
|
|
|
|
pTop->Flags |= RC_GLOBAL;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
pTop->pResource = (RSHEADER_TYPE *)pTop->pClassRes;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
else
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// try to get a fallback resource
|
|
|
|
|
pFallbackResMgr = CreateFallbackResMgr( rId, pResObj );
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
{
|
|
|
|
|
pTop->Flags |= RC_FALLBACK_DOWN;
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
ByteString aMess( "found resource " );
|
|
|
|
|
aMess.Append( ByteString::CreateFromInt32( nId ) );
|
|
|
|
|
aMess.Append( " in fallback " );
|
|
|
|
|
aMess.Append( ByteString( OUStringToOString( pFallbackResMgr->GetFileName(), osl_getThreadTextEncoding() ) ) );
|
|
|
|
|
aMess.Append( "\n" );
|
|
|
|
|
RscError_Impl( aMess.GetBuffer(),
|
|
|
|
|
this, nRT, nId, aStack, nCurStack-1 );
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
RscError_Impl( "Cannot load resource! ",
|
|
|
|
|
this, nRT, nId, aStack, nCurStack-1 );
|
|
|
|
|
#endif
|
|
|
|
|
pTop->Flags |= RC_NOTFOUND;
|
|
|
|
|
pTop->pClassRes = getEmptyBuffer();
|
|
|
|
|
pTop->pResource = (RSHEADER_TYPE*)pTop->pClassRes;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void * ResMgr::GetResourceSkipHeader( const ResId& rResId, ResMgr ** ppResMgr )
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
2007-04-26 08:48:23 +00:00
|
|
|
|
DBG_ASSERT( rResId.GetResMgr(), "illegal ResId without ResMgr" );
|
|
|
|
|
*ppResMgr = rResId.GetResMgr();
|
2007-03-05 14:19:00 +00:00
|
|
|
|
if( *ppResMgr )
|
|
|
|
|
{
|
|
|
|
|
(*ppResMgr)->GetResource( rResId );
|
|
|
|
|
(*ppResMgr)->Increment( sizeof( RSHEADER_TYPE ) );
|
2007-04-26 08:48:23 +00:00
|
|
|
|
return (*ppResMgr)->GetClass();
|
2007-03-05 14:19:00 +00:00
|
|
|
|
}
|
2007-04-26 08:48:23 +00:00
|
|
|
|
return getEmptyBuffer();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void ResMgr::PopContext( const Resource* pResObj )
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
{
|
|
|
|
|
pFallbackResMgr->PopContext( pResObj );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
if ( DbgIsResource() )
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if ( (aStack[nCurStack].pResObj != pResObj) || nCurStack == 0 )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
RscError_Impl( "Cannot free resource! ", this,
|
2005-01-03 16:14:02 +00:00
|
|
|
|
RSC_NOTYPE, 0, aStack, nCurStack );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if ( nCurStack > 0 )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
ImpRCStack* pTop = &aStack[nCurStack];
|
2000-09-18 16:07:07 +00:00
|
|
|
|
#ifdef DBG_UTIL
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if ( DbgIsResource() && !(pTop->Flags & RC_NOTFOUND) )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
void* pRes = (BYTE*)pTop->pResource +
|
|
|
|
|
pTop->pResource->GetLocalOff();
|
|
|
|
|
|
|
|
|
|
if ( pTop->pClassRes != pRes )
|
|
|
|
|
{
|
|
|
|
|
RscError_Impl( "Classpointer not at the end!",
|
|
|
|
|
this, pTop->pResource->GetRT(),
|
|
|
|
|
pTop->pResource->GetId(),
|
2005-01-03 16:14:02 +00:00
|
|
|
|
aStack, nCurStack-1 );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Resource freigeben
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if( (pTop->Flags & (RC_GLOBAL | RC_NOTFOUND)) == RC_GLOBAL )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
// kann auch Fremd-Ressource sein
|
|
|
|
|
pImpRes->FreeGlobalRes( pTop->aResHandle, pTop->pResource );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
decStack();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
RSHEADER_TYPE* ResMgr::CreateBlock( const ResId& rId )
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
{
|
|
|
|
|
ResId aId( rId );
|
|
|
|
|
aId.SetResMgr( NULL );
|
|
|
|
|
return pFallbackResMgr->CreateBlock( aId );
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
RSHEADER_TYPE* pHeader = NULL;
|
|
|
|
|
if ( GetResource( rId ) )
|
|
|
|
|
{
|
|
|
|
|
// Der Zeiger steht am Anfang, deswegen zeigt der Klassen-Pointer
|
|
|
|
|
// auf den Header und die restliche Groesse ist die Gesammte.
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pHeader = (RSHEADER_TYPE*)rtl_allocateMemory( GetRemainSize() );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
memcpy( pHeader, GetClass(), GetRemainSize() );
|
|
|
|
|
Increment( pHeader->GetLocalOff() ); //ans Ende setzen
|
|
|
|
|
if ( pHeader->GetLocalOff() != pHeader->GetGlobOff() )
|
|
|
|
|
// Hat Sub-Ressourcen, deshalb extra freigeben
|
|
|
|
|
PopContext();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return pHeader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
INT16 ResMgr::GetShort( void * pShort )
|
|
|
|
|
{
|
2004-06-22 11:46:02 +00:00
|
|
|
|
return ((*((sal_uInt8*)pShort + 0) << 8) |
|
|
|
|
|
(*((sal_uInt8*)pShort + 1) << 0) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
INT32 ResMgr::GetLong( void * pLong )
|
|
|
|
|
{
|
2004-06-22 11:46:02 +00:00
|
|
|
|
return ((*((sal_uInt8*)pLong + 0) << 24) |
|
|
|
|
|
(*((sal_uInt8*)pLong + 1) << 16) |
|
|
|
|
|
(*((sal_uInt8*)pLong + 2) << 8) |
|
|
|
|
|
(*((sal_uInt8*)pLong + 3) << 0) );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
sal_uInt64 ResMgr::GetUInt64( void* pDatum )
|
|
|
|
|
{
|
|
|
|
|
return ((sal_uInt64(*((sal_uInt8*)pDatum + 0)) << 56) |
|
|
|
|
|
(sal_uInt64(*((sal_uInt8*)pDatum + 1)) << 48) |
|
|
|
|
|
(sal_uInt64(*((sal_uInt8*)pDatum + 2)) << 40) |
|
|
|
|
|
(sal_uInt64(*((sal_uInt8*)pDatum + 3)) << 32) |
|
|
|
|
|
(sal_uInt64(*((sal_uInt8*)pDatum + 4)) << 24) |
|
|
|
|
|
(sal_uInt64(*((sal_uInt8*)pDatum + 5)) << 16) |
|
|
|
|
|
(sal_uInt64(*((sal_uInt8*)pDatum + 6)) << 8) |
|
|
|
|
|
(sal_uInt64(*((sal_uInt8*)pDatum + 7)) << 0) );
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
sal_uInt32 ResMgr::GetStringWithoutHook( UniString& rStr, const BYTE* pStr )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt32 nRet = GetStringSize( pStr );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
UniString aString( (sal_Char*)pStr, RTL_TEXTENCODING_UTF8,
|
|
|
|
|
RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE |
|
|
|
|
|
RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
|
|
|
|
|
RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
rStr = aString;
|
|
|
|
|
return nRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sal_uInt32 ResMgr::GetString( UniString& rStr, const BYTE* pStr )
|
|
|
|
|
{
|
|
|
|
|
UniString aString;
|
|
|
|
|
sal_uInt32 nRet = GetStringWithoutHook( aString, pStr );
|
2000-12-05 18:23:20 +00:00
|
|
|
|
if ( pImplResHookProc )
|
|
|
|
|
pImplResHookProc( aString );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
rStr = aString;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
return nRet;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt32 ResMgr::GetStringSize( const BYTE* pStr )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
return GetStringSize( strlen( (const char*)pStr ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt32 ResMgr::GetRemainSize()
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
return pFallbackResMgr->GetRemainSize();
|
|
|
|
|
|
|
|
|
|
const ImpRCStack& rTop = aStack[nCurStack];
|
|
|
|
|
return (sal_uInt32)((long)(BYTE *)rTop.pResource +
|
|
|
|
|
rTop.pResource->GetLocalOff() -
|
|
|
|
|
(long)(BYTE *)rTop.pClassRes);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
void* ResMgr::Increment( sal_uInt32 nSize )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
return pFallbackResMgr->Increment( nSize );
|
|
|
|
|
|
|
|
|
|
ImpRCStack& rStack = aStack[nCurStack];
|
|
|
|
|
if( (rStack.Flags & RC_NOTFOUND) )
|
|
|
|
|
return rStack.pClassRes;
|
|
|
|
|
|
2003-03-27 16:05:12 +00:00
|
|
|
|
BYTE* pClassRes = (BYTE*)rStack.pClassRes + nSize;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2003-03-27 16:05:12 +00:00
|
|
|
|
rStack.pClassRes = pClassRes;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2003-03-27 16:05:12 +00:00
|
|
|
|
RSHEADER_TYPE* pRes = rStack.pResource;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt32 nLocalOff = pRes->GetLocalOff();
|
2003-03-27 16:05:12 +00:00
|
|
|
|
if ( (pRes->GetGlobOff() == nLocalOff) &&
|
|
|
|
|
(((char*)pRes + nLocalOff) == rStack.pClassRes) &&
|
|
|
|
|
(rStack.Flags & RC_AUTORELEASE))
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2003-03-27 16:05:12 +00:00
|
|
|
|
PopContext( rStack.pResObj );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return pClassRes;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
ResMgr* ResMgr::CreateFallbackResMgr( const ResId& rId, const Resource* pResource )
|
|
|
|
|
{
|
|
|
|
|
ResMgr *pFallback = NULL;
|
|
|
|
|
if( nCurStack > 0 )
|
|
|
|
|
{
|
|
|
|
|
// get the next fallback level in resource file scope
|
|
|
|
|
InternalResMgr* pRes = ResMgrContainer::get().getNextFallback( pImpRes );
|
|
|
|
|
if( pRes )
|
|
|
|
|
{
|
|
|
|
|
// check that the fallback locale is not already in the chain of
|
|
|
|
|
// fallbacks - prevent fallback loops
|
|
|
|
|
ResMgr* pResMgr = this;
|
|
|
|
|
while( pResMgr &&
|
|
|
|
|
( pResMgr->pImpRes->aLocale.Language != pRes->aLocale.Language ||
|
|
|
|
|
pResMgr->pImpRes->aLocale.Country != pRes->aLocale.Country ||
|
|
|
|
|
pResMgr->pImpRes->aLocale.Variant != pRes->aLocale.Variant )
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
pResMgr = pResMgr->pOriginalResMgr;
|
|
|
|
|
}
|
|
|
|
|
if( pResMgr )
|
|
|
|
|
{
|
|
|
|
|
// found a recursion, no fallback possible
|
|
|
|
|
ResMgrContainer::get().freeResMgr( pRes );
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2006-03-29 11:43:16 +00:00
|
|
|
|
OSL_TRACE( "trying fallback: %s\n", OUStringToOString( pRes->aFileName, osl_getThreadTextEncoding() ).getStr() );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
pFallback = new ResMgr( pRes );
|
|
|
|
|
pFallback->pOriginalResMgr = this;
|
|
|
|
|
// try to recreate the resource stack
|
|
|
|
|
bool bHaveStack = true;
|
|
|
|
|
for( int i = 1; i < nCurStack; i++ )
|
|
|
|
|
{
|
|
|
|
|
if( !aStack[i].pResource )
|
|
|
|
|
{
|
|
|
|
|
bHaveStack = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2007-04-26 08:48:23 +00:00
|
|
|
|
ResId aId( aStack[i].pResource->GetId(), *pFallbackResMgr );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
aId.SetRT( aStack[i].pResource->GetRT() );
|
|
|
|
|
if( !pFallback->GetResource( aId ) )
|
|
|
|
|
{
|
|
|
|
|
bHaveStack = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( bHaveStack )
|
|
|
|
|
{
|
2008-01-29 15:07:22 +00:00
|
|
|
|
ResId aId( rId.GetId(), *pFallback );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
aId.SetRT( rId.GetRT() );
|
|
|
|
|
if( !pFallback->GetResource( aId, pResource ) )
|
|
|
|
|
bHaveStack = false;
|
|
|
|
|
else
|
|
|
|
|
pFallback->aStack[pFallback->nCurStack].Flags |= RC_FALLBACK_UP;
|
|
|
|
|
}
|
|
|
|
|
if( !bHaveStack )
|
|
|
|
|
{
|
|
|
|
|
delete pFallback;
|
|
|
|
|
pFallback = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return pFallback;
|
|
|
|
|
}
|
|
|
|
|
|
2004-06-25 14:04:28 +00:00
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// method left here for SDK compatibility,
|
|
|
|
|
// used in "framework/source/services/substitutepathvars.cxx"
|
|
|
|
|
//
|
|
|
|
|
// phone numbers no longer in use for resource files
|
|
|
|
|
//
|
|
|
|
|
//---------------------------------------------------------------------------
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
const char* ResMgr::GetLang( LanguageType& nType, USHORT nPrio )
|
|
|
|
|
{
|
|
|
|
|
if ( nType == LANGUAGE_SYSTEM || nType == LANGUAGE_DONTKNOW )
|
2006-04-07 15:17:13 +00:00
|
|
|
|
nType = MsLangId::getSystemUILanguage();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
if ( nPrio == 0 )
|
|
|
|
|
{
|
|
|
|
|
switch ( nType )
|
|
|
|
|
{
|
|
|
|
|
case LANGUAGE_DANISH:
|
|
|
|
|
return "45";
|
|
|
|
|
|
|
|
|
|
case LANGUAGE_DUTCH:
|
|
|
|
|
case LANGUAGE_DUTCH_BELGIAN:
|
|
|
|
|
return "31";
|
|
|
|
|
|
|
|
|
|
case LANGUAGE_ENGLISH:
|
|
|
|
|
case LANGUAGE_ENGLISH_UK:
|
|
|
|
|
case LANGUAGE_ENGLISH_EIRE:
|
|
|
|
|
case LANGUAGE_ENGLISH_SAFRICA:
|
|
|
|
|
case LANGUAGE_ENGLISH_JAMAICA:
|
|
|
|
|
case LANGUAGE_ENGLISH_BELIZE:
|
|
|
|
|
case LANGUAGE_ENGLISH_TRINIDAD:
|
|
|
|
|
case LANGUAGE_ENGLISH_ZIMBABWE:
|
|
|
|
|
case LANGUAGE_ENGLISH_PHILIPPINES:
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "44";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
case LANGUAGE_ENGLISH_US:
|
|
|
|
|
case LANGUAGE_ENGLISH_CAN:
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "01";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
case LANGUAGE_ENGLISH_AUS:
|
|
|
|
|
case LANGUAGE_ENGLISH_NZ:
|
|
|
|
|
return "61";
|
2003-12-17 18:25:19 +00:00
|
|
|
|
case LANGUAGE_ESTONIAN:
|
|
|
|
|
return "77";
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
case LANGUAGE_FINNISH:
|
2002-04-16 11:05:21 +00:00
|
|
|
|
return "35";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
case LANGUAGE_FRENCH_CANADIAN:
|
|
|
|
|
return "02";
|
|
|
|
|
|
|
|
|
|
case LANGUAGE_FRENCH:
|
|
|
|
|
case LANGUAGE_FRENCH_BELGIAN:
|
|
|
|
|
case LANGUAGE_FRENCH_SWISS:
|
|
|
|
|
case LANGUAGE_FRENCH_LUXEMBOURG:
|
|
|
|
|
case LANGUAGE_FRENCH_MONACO:
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "33";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
case LANGUAGE_GERMAN:
|
|
|
|
|
case LANGUAGE_GERMAN_SWISS:
|
|
|
|
|
case LANGUAGE_GERMAN_AUSTRIAN:
|
|
|
|
|
case LANGUAGE_GERMAN_LUXEMBOURG:
|
|
|
|
|
case LANGUAGE_GERMAN_LIECHTENSTEIN:
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "49";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
case LANGUAGE_ITALIAN:
|
|
|
|
|
case LANGUAGE_ITALIAN_SWISS:
|
|
|
|
|
return "39";
|
|
|
|
|
|
|
|
|
|
case LANGUAGE_NORWEGIAN:
|
|
|
|
|
case LANGUAGE_NORWEGIAN_BOKMAL:
|
|
|
|
|
return "47";
|
|
|
|
|
|
|
|
|
|
case LANGUAGE_PORTUGUESE:
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "03";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
case LANGUAGE_PORTUGUESE_BRAZILIAN:
|
|
|
|
|
return "55";
|
|
|
|
|
|
2009-01-06 12:54:16 +00:00
|
|
|
|
case LANGUAGE_SPANISH_DATED:
|
2000-09-18 16:07:07 +00:00
|
|
|
|
case LANGUAGE_SPANISH_MEXICAN:
|
|
|
|
|
case LANGUAGE_SPANISH_MODERN:
|
|
|
|
|
case LANGUAGE_SPANISH_GUATEMALA:
|
|
|
|
|
case LANGUAGE_SPANISH_COSTARICA:
|
|
|
|
|
case LANGUAGE_SPANISH_PANAMA:
|
|
|
|
|
case LANGUAGE_SPANISH_DOMINICAN_REPUBLIC:
|
|
|
|
|
case LANGUAGE_SPANISH_VENEZUELA:
|
|
|
|
|
case LANGUAGE_SPANISH_COLOMBIA:
|
|
|
|
|
case LANGUAGE_SPANISH_PERU:
|
|
|
|
|
case LANGUAGE_SPANISH_ARGENTINA:
|
|
|
|
|
case LANGUAGE_SPANISH_ECUADOR:
|
|
|
|
|
case LANGUAGE_SPANISH_CHILE:
|
|
|
|
|
case LANGUAGE_SPANISH_URUGUAY:
|
|
|
|
|
case LANGUAGE_SPANISH_PARAGUAY:
|
|
|
|
|
case LANGUAGE_SPANISH_BOLIVIA:
|
|
|
|
|
return "34";
|
|
|
|
|
|
|
|
|
|
case LANGUAGE_SWEDISH:
|
|
|
|
|
return "46";
|
|
|
|
|
|
|
|
|
|
case LANGUAGE_POLISH:
|
|
|
|
|
return "48";
|
|
|
|
|
case LANGUAGE_CZECH:
|
|
|
|
|
return "42";
|
2003-12-17 18:25:19 +00:00
|
|
|
|
case LANGUAGE_SLOVENIAN:
|
|
|
|
|
return "50";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
case LANGUAGE_HUNGARIAN:
|
|
|
|
|
return "36";
|
|
|
|
|
case LANGUAGE_RUSSIAN:
|
|
|
|
|
return "07";
|
|
|
|
|
case LANGUAGE_SLOVAK:
|
2002-09-20 06:50:25 +00:00
|
|
|
|
return "43";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
case LANGUAGE_GREEK:
|
|
|
|
|
return "30";
|
|
|
|
|
case LANGUAGE_TURKISH:
|
|
|
|
|
return "90";
|
|
|
|
|
|
|
|
|
|
case LANGUAGE_CHINESE_SIMPLIFIED:
|
|
|
|
|
return "86";
|
|
|
|
|
case LANGUAGE_CHINESE_TRADITIONAL:
|
|
|
|
|
return "88";
|
|
|
|
|
case LANGUAGE_JAPANESE:
|
|
|
|
|
return "81";
|
|
|
|
|
case LANGUAGE_KOREAN:
|
|
|
|
|
case LANGUAGE_KOREAN_JOHAB:
|
|
|
|
|
return "82";
|
2002-05-31 11:08:35 +00:00
|
|
|
|
case LANGUAGE_THAI:
|
2002-11-28 10:07:04 +00:00
|
|
|
|
return "66";
|
2002-11-28 10:38:49 +00:00
|
|
|
|
case LANGUAGE_HINDI:
|
|
|
|
|
return "91";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2009-01-06 12:54:16 +00:00
|
|
|
|
case LANGUAGE_ARABIC_PRIMARY_ONLY:
|
2000-09-18 16:07:07 +00:00
|
|
|
|
case LANGUAGE_ARABIC_IRAQ:
|
|
|
|
|
case LANGUAGE_ARABIC_EGYPT:
|
|
|
|
|
case LANGUAGE_ARABIC_LIBYA:
|
|
|
|
|
case LANGUAGE_ARABIC_ALGERIA:
|
|
|
|
|
case LANGUAGE_ARABIC_MOROCCO:
|
|
|
|
|
case LANGUAGE_ARABIC_TUNISIA:
|
|
|
|
|
case LANGUAGE_ARABIC_OMAN:
|
|
|
|
|
case LANGUAGE_ARABIC_YEMEN:
|
|
|
|
|
case LANGUAGE_ARABIC_SYRIA:
|
|
|
|
|
case LANGUAGE_ARABIC_JORDAN:
|
|
|
|
|
case LANGUAGE_ARABIC_LEBANON:
|
|
|
|
|
case LANGUAGE_ARABIC_KUWAIT:
|
|
|
|
|
case LANGUAGE_ARABIC_UAE:
|
|
|
|
|
case LANGUAGE_ARABIC_BAHRAIN:
|
|
|
|
|
case LANGUAGE_ARABIC_QATAR:
|
|
|
|
|
return "96";
|
|
|
|
|
|
2004-03-30 12:48:48 +00:00
|
|
|
|
case LANGUAGE_HEBREW:
|
|
|
|
|
return "97";
|
|
|
|
|
|
2001-04-05 08:01:31 +00:00
|
|
|
|
case LANGUAGE_CATALAN:
|
|
|
|
|
return "37";
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
default:
|
2001-05-18 09:35:38 +00:00
|
|
|
|
return "99";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ( nPrio == 1 )
|
|
|
|
|
{
|
|
|
|
|
switch ( nType )
|
|
|
|
|
{
|
|
|
|
|
case LANGUAGE_FRENCH_CANADIAN:
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "33";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
case LANGUAGE_PORTUGUESE_BRAZILIAN:
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "03";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if ( nPrio == 2 )
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "01";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
else if ( nPrio == 3 )
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "44";
|
2001-05-18 09:35:38 +00:00
|
|
|
|
else if ( nPrio == 4 )
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return "49";
|
2001-05-18 09:35:38 +00:00
|
|
|
|
else
|
|
|
|
|
return "99";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResMgr* ResMgr::CreateResMgr( const sal_Char* pPrefixName,
|
2005-01-03 16:14:02 +00:00
|
|
|
|
com::sun::star::lang::Locale aLocale )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
OUString aPrefix( pPrefixName, strlen( pPrefixName ), osl_getThreadTextEncoding() );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if( ! aLocale.Language.getLength() )
|
|
|
|
|
aLocale = ResMgrContainer::get().getDefLocale();
|
2004-06-25 14:04:28 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
InternalResMgr* pImp = ResMgrContainer::get().getResMgr( aPrefix, aLocale );
|
|
|
|
|
return pImp ? new ResMgr( pImp ) : NULL;
|
2000-11-16 13:21:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResMgr* ResMgr::SearchCreateResMgr(
|
|
|
|
|
const sal_Char* pPrefixName,
|
2005-01-03 16:14:02 +00:00
|
|
|
|
com::sun::star::lang::Locale& rLocale )
|
2000-11-16 13:21:17 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
2004-06-25 14:04:28 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
OUString aPrefix( pPrefixName, strlen( pPrefixName ), osl_getThreadTextEncoding() );
|
2004-06-25 14:04:28 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
if( ! rLocale.Language.getLength() )
|
|
|
|
|
rLocale = ResMgrContainer::get().getDefLocale();
|
2004-06-25 14:04:28 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
InternalResMgr* pImp = ResMgrContainer::get().getResMgr( aPrefix, rLocale );
|
|
|
|
|
return pImp ? new ResMgr( pImp ) : NULL;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
INT16 ResMgr::ReadShort()
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
return pFallbackResMgr->ReadShort();
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
INT16 n = GetShort( GetClass() );
|
|
|
|
|
Increment( sizeof( INT16 ) );
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
INT32 ResMgr::ReadLong()
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
return pFallbackResMgr->ReadLong();
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
INT32 n = GetLong( GetClass() );
|
|
|
|
|
Increment( sizeof( INT32 ) );
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
UniString ResMgr::ReadStringWithoutHook()
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
return pFallbackResMgr->ReadStringWithoutHook();
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
UniString aRet;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
const ImpRCStack& rTop = aStack[nCurStack];
|
|
|
|
|
if( (rTop.Flags & RC_NOTFOUND) )
|
|
|
|
|
{
|
|
|
|
|
#if OSL_DEBUG_LEVEL > 0
|
|
|
|
|
aRet = OUString( RTL_CONSTASCII_USTRINGPARAM( "<resource not found>" ) );
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
Increment( GetStringWithoutHook( aRet, (const BYTE*)GetClass() ) );
|
|
|
|
|
|
|
|
|
|
return aRet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
UniString ResMgr::ReadString()
|
|
|
|
|
{
|
|
|
|
|
UniString aRet = ReadStringWithoutHook();
|
|
|
|
|
if ( pImplResHookProc )
|
|
|
|
|
pImplResHookProc( aRet );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
return aRet;
|
|
|
|
|
}
|
|
|
|
|
|
2000-12-05 18:23:20 +00:00
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
ULONG ResMgr::GetAutoHelpId()
|
|
|
|
|
{
|
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
|
|
|
|
|
if( pFallbackResMgr )
|
|
|
|
|
return pFallbackResMgr->GetAutoHelpId();
|
|
|
|
|
|
|
|
|
|
DBG_ASSERT( nCurStack, "resource stack empty in Auto help id generation" );
|
|
|
|
|
if( nCurStack < 1 || nCurStack > 2 )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
const ImpRCStack *pRC = StackTop( nCurStack==1 ? 0 : 1 );
|
|
|
|
|
|
|
|
|
|
DBG_ASSERT( pRC->pResource, "MM hat gesagt, dass der immer einen hat" );
|
|
|
|
|
ULONG nGID = pRC->pResource->GetId();
|
|
|
|
|
|
|
|
|
|
if( !nGID || nGID > 32767 )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ULONG nHID = 0;
|
|
|
|
|
|
|
|
|
|
// GGGg gggg::gggg gggg::ggLL LLLl::llll llll
|
|
|
|
|
switch( pRC->pResource->GetRT() ) { // maximal 7
|
|
|
|
|
case RSC_DOCKINGWINDOW:
|
|
|
|
|
nHID += 0x20000000L;
|
|
|
|
|
case RSC_WORKWIN:
|
|
|
|
|
nHID += 0x20000000L;
|
|
|
|
|
case RSC_MODELESSDIALOG:
|
|
|
|
|
nHID += 0x20000000L;
|
|
|
|
|
case RSC_FLOATINGWINDOW:
|
|
|
|
|
nHID += 0x20000000L;
|
|
|
|
|
case RSC_MODALDIALOG:
|
|
|
|
|
nHID += 0x20000000L;
|
|
|
|
|
case RSC_TABPAGE:
|
|
|
|
|
nHID += 0x20000000L;
|
|
|
|
|
|
|
|
|
|
if( nCurStack == 2 ) {
|
|
|
|
|
pRC = StackTop();
|
|
|
|
|
ULONG nLID = pRC->pResource->GetId();
|
|
|
|
|
|
|
|
|
|
if( !nLID || nLID > 511 )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
switch( pRC->pResource->GetRT() ) { // maximal 32
|
|
|
|
|
case RSC_TABCONTROL: nHID |= 0x0000; break;
|
|
|
|
|
case RSC_RADIOBUTTON: nHID |= 0x0200; break;
|
|
|
|
|
case RSC_CHECKBOX: nHID |= 0x0400; break;
|
|
|
|
|
case RSC_TRISTATEBOX: nHID |= 0x0600; break;
|
|
|
|
|
case RSC_EDIT: nHID |= 0x0800; break;
|
|
|
|
|
case RSC_MULTILINEEDIT: nHID |= 0x0A00; break;
|
|
|
|
|
case RSC_MULTILISTBOX: nHID |= 0x0C00; break;
|
|
|
|
|
case RSC_LISTBOX: nHID |= 0x0E00; break;
|
|
|
|
|
case RSC_COMBOBOX: nHID |= 0x1000; break;
|
|
|
|
|
case RSC_PUSHBUTTON: nHID |= 0x1200; break;
|
|
|
|
|
case RSC_SPINFIELD: nHID |= 0x1400; break;
|
|
|
|
|
case RSC_PATTERNFIELD: nHID |= 0x1600; break;
|
|
|
|
|
case RSC_NUMERICFIELD: nHID |= 0x1800; break;
|
|
|
|
|
case RSC_METRICFIELD: nHID |= 0x1A00; break;
|
|
|
|
|
case RSC_CURRENCYFIELD: nHID |= 0x1C00; break;
|
|
|
|
|
case RSC_DATEFIELD: nHID |= 0x1E00; break;
|
|
|
|
|
case RSC_TIMEFIELD: nHID |= 0x2000; break;
|
|
|
|
|
case RSC_IMAGERADIOBUTTON: nHID |= 0x2200; break;
|
|
|
|
|
case RSC_NUMERICBOX: nHID |= 0x2400; break;
|
|
|
|
|
case RSC_METRICBOX: nHID |= 0x2600; break;
|
|
|
|
|
case RSC_CURRENCYBOX: nHID |= 0x2800; break;
|
|
|
|
|
case RSC_DATEBOX: nHID |= 0x2A00; break;
|
|
|
|
|
case RSC_TIMEBOX: nHID |= 0x2C00; break;
|
|
|
|
|
case RSC_IMAGEBUTTON: nHID |= 0x2E00; break;
|
|
|
|
|
case RSC_MENUBUTTON: nHID |= 0x3000; break;
|
|
|
|
|
case RSC_MOREBUTTON: nHID |= 0x3200; break;
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
} // of switch
|
|
|
|
|
nHID |= nLID;
|
|
|
|
|
} // of if
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
} // of switch
|
|
|
|
|
nHID |= nGID << 14;
|
|
|
|
|
|
|
|
|
|
return nHID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2000-12-05 18:23:20 +00:00
|
|
|
|
void ResMgr::SetReadStringHook( ResHookProc pProc )
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
2000-12-05 18:23:20 +00:00
|
|
|
|
pImplResHookProc = pProc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResHookProc ResMgr::GetReadStringHook()
|
|
|
|
|
{
|
|
|
|
|
return pImplResHookProc;
|
|
|
|
|
}
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void ResMgr::SetDefaultLocale( const com::sun::star::lang::Locale& rLocale )
|
|
|
|
|
{
|
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
ResMgrContainer::get().setDefLocale( rLocale );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const OUString& ResMgr::GetFileName() const
|
|
|
|
|
{
|
|
|
|
|
return pImpRes->aFileName;
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
|
|
SimpleResMgr::SimpleResMgr( const sal_Char* pPrefixName,
|
2005-01-03 16:14:02 +00:00
|
|
|
|
const ::com::sun::star::lang::Locale& rLocale )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
OUString aPrefix( pPrefixName, strlen( pPrefixName ), osl_getThreadTextEncoding() );
|
|
|
|
|
com::sun::star::lang::Locale aLocale( rLocale );
|
2004-06-25 14:04:28 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
if( ! aLocale.Language.getLength() )
|
|
|
|
|
aLocale = ResMgrContainer::get().getDefLocale();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
m_pResImpl = ResMgrContainer::get().getResMgr( aPrefix, aLocale, true );
|
|
|
|
|
DBG_ASSERT( m_pResImpl, "SimpleResMgr::SimpleResMgr : have no impl class !" );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-03-29 11:43:16 +00:00
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
SimpleResMgr::SimpleResMgr( const ::rtl::OUString& _rPrefixName, ::com::sun::star::lang::Locale& _inout_Locale )
|
|
|
|
|
{
|
|
|
|
|
osl::Guard<osl::Mutex> aGuard( getResMgrMutex() );
|
|
|
|
|
m_pResImpl = ResMgrContainer::get().getResMgr( _rPrefixName, _inout_Locale, true );
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
SimpleResMgr::~SimpleResMgr()
|
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
delete m_pResImpl;
|
|
|
|
|
}
|
|
|
|
|
|
2006-03-29 11:43:16 +00:00
|
|
|
|
// -----------------------------------------------------------------------
|
2005-01-03 16:14:02 +00:00
|
|
|
|
SimpleResMgr* SimpleResMgr::Create( const sal_Char* pPrefixName, com::sun::star::lang::Locale aLocale )
|
|
|
|
|
{
|
|
|
|
|
return new SimpleResMgr( pPrefixName, aLocale );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
2006-03-29 11:43:16 +00:00
|
|
|
|
bool SimpleResMgr::IsAvailable( RESOURCE_TYPE _resourceType, sal_uInt32 _resourceId )
|
|
|
|
|
{
|
2010-10-16 03:20:00 -05:00
|
|
|
|
osl::MutexGuard aGuard(m_aAccessSafety);
|
2006-03-29 11:43:16 +00:00
|
|
|
|
|
|
|
|
|
if ( ( RSC_STRING != _resourceType ) && ( RSC_RESOURCE != _resourceType ) )
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
DBG_ASSERT( m_pResImpl, "SimpleResMgr::IsAvailable: have no impl class !" );
|
|
|
|
|
return m_pResImpl->IsGlobalAvailable( _resourceType, _resourceId );
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2006-03-29 11:43:16 +00:00
|
|
|
|
// -----------------------------------------------------------------------
|
2005-01-03 16:14:02 +00:00
|
|
|
|
UniString SimpleResMgr::ReadString( sal_uInt32 nId )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2010-10-16 03:20:00 -05:00
|
|
|
|
osl::MutexGuard aGuard(m_aAccessSafety);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
DBG_ASSERT( m_pResImpl, "SimpleResMgr::ReadString : have no impl class !" );
|
|
|
|
|
// perhaps constructed with an invalid filename ?
|
|
|
|
|
|
|
|
|
|
UniString sReturn;
|
|
|
|
|
if ( !m_pResImpl )
|
|
|
|
|
return sReturn;
|
|
|
|
|
|
|
|
|
|
void* pResHandle = NULL;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
InternalResMgr* pFallback = m_pResImpl;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
RSHEADER_TYPE* pResHeader = (RSHEADER_TYPE*)m_pResImpl->LoadGlobalRes( RSC_STRING, nId, &pResHandle );
|
|
|
|
|
if ( !pResHeader )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
{
|
2006-06-19 12:48:55 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
// try fallback
|
|
|
|
|
while( ! pResHandle && pFallback )
|
|
|
|
|
{
|
|
|
|
|
InternalResMgr* pOldFallback = pFallback;
|
|
|
|
|
pFallback = ResMgrContainer::get().getNextFallback( pFallback );
|
|
|
|
|
if( pOldFallback != m_pResImpl )
|
|
|
|
|
ResMgrContainer::get().freeResMgr( pOldFallback );
|
|
|
|
|
if( pFallback )
|
|
|
|
|
{
|
|
|
|
|
// handle possible recursion
|
|
|
|
|
if( pFallback->aLocale.Language != m_pResImpl->aLocale.Language ||
|
|
|
|
|
pFallback->aLocale.Country != m_pResImpl->aLocale.Country ||
|
|
|
|
|
pFallback->aLocale.Variant != m_pResImpl->aLocale.Variant )
|
|
|
|
|
{
|
|
|
|
|
pResHeader = (RSHEADER_TYPE*)pFallback->LoadGlobalRes( RSC_STRING, nId, &pResHandle );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ResMgrContainer::get().freeResMgr( pFallback );
|
|
|
|
|
pFallback = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if( ! pResHandle )
|
|
|
|
|
// no such resource
|
|
|
|
|
return sReturn;
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// ULONG nLen = pResHeader->GetLocalOff() - sizeof(RSHEADER_TYPE);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
ResMgr::GetString( sReturn, (const BYTE*)(pResHeader+1) );
|
|
|
|
|
|
|
|
|
|
// not neccessary with te current implementation which holds the string table permanently, but to be sure ....
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// note: pFallback cannot be NULL here and is either the fallback or m_pResImpl
|
|
|
|
|
pFallback->FreeGlobalRes( pResHeader, pResHandle );
|
|
|
|
|
if( m_pResImpl != pFallback )
|
|
|
|
|
{
|
2006-06-19 12:48:55 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
ResMgrContainer::get().freeResMgr( pFallback );
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
return sReturn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2006-03-29 11:43:16 +00:00
|
|
|
|
const ::com::sun::star::lang::Locale& SimpleResMgr::GetLocale() const
|
|
|
|
|
{
|
|
|
|
|
DBG_ASSERT( IsValid(), "SimpleResMgr::ReadBlob: invalid, this will crash!" );
|
|
|
|
|
return m_pResImpl->aLocale;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt32 SimpleResMgr::ReadBlob( sal_uInt32 nId, void** pBuffer )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2010-10-16 03:20:00 -05:00
|
|
|
|
osl::MutexGuard aGuard(m_aAccessSafety);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
DBG_ASSERT( m_pResImpl, "SimpleResMgr::ReadBlob : have no impl class !" );
|
|
|
|
|
|
|
|
|
|
// perhaps constructed with an invalid filename ?
|
|
|
|
|
DBG_ASSERT( pBuffer, "SimpleResMgr::ReadBlob : invalid argument !" );
|
|
|
|
|
*pBuffer = NULL;
|
|
|
|
|
|
|
|
|
|
void* pResHandle = NULL;
|
2005-01-03 16:14:02 +00:00
|
|
|
|
InternalResMgr* pFallback = m_pResImpl;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
RSHEADER_TYPE* pResHeader = (RSHEADER_TYPE*)m_pResImpl->LoadGlobalRes( RSC_RESOURCE, nId, &pResHandle );
|
|
|
|
|
DBG_ASSERT( pResHeader, "SimpleResMgr::ReadBlob : couldn't find the resource with the given id !" );
|
|
|
|
|
|
|
|
|
|
if ( !pResHeader )
|
2005-01-03 16:14:02 +00:00
|
|
|
|
{
|
2006-06-19 12:48:55 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
// try fallback
|
|
|
|
|
while( ! pResHandle && pFallback )
|
|
|
|
|
{
|
|
|
|
|
InternalResMgr* pOldFallback = pFallback;
|
|
|
|
|
pFallback = ResMgrContainer::get().getNextFallback( pFallback );
|
|
|
|
|
if( pOldFallback != m_pResImpl )
|
|
|
|
|
ResMgrContainer::get().freeResMgr( pOldFallback );
|
|
|
|
|
if( pFallback )
|
2008-11-10 15:06:12 +00:00
|
|
|
|
{
|
2005-01-03 16:14:02 +00:00
|
|
|
|
// handle possible recursion
|
|
|
|
|
if( pFallback->aLocale.Language != m_pResImpl->aLocale.Language ||
|
|
|
|
|
pFallback->aLocale.Country != m_pResImpl->aLocale.Country ||
|
|
|
|
|
pFallback->aLocale.Variant != m_pResImpl->aLocale.Variant )
|
|
|
|
|
{
|
|
|
|
|
pResHeader = (RSHEADER_TYPE*)pFallback->LoadGlobalRes( RSC_RESOURCE, nId, &pResHandle );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ResMgrContainer::get().freeResMgr( pFallback );
|
|
|
|
|
pFallback = NULL;
|
|
|
|
|
}
|
2008-11-10 15:06:12 +00:00
|
|
|
|
}
|
2005-01-03 16:14:02 +00:00
|
|
|
|
}
|
|
|
|
|
if( ! pResHandle )
|
|
|
|
|
// no exception handling, this would require the locking of the solar mutex which isn't allowed within this class
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
DBG_ASSERT( pResHandle == NULL, "SimpleResMgr::ReadBlob : behaviour of LoadGlobalRes changed !" );
|
|
|
|
|
// if pResHandle is not NULL the FreeBlob wouldn't have to delete the pointer given as pBuffer, but
|
|
|
|
|
// FreeBlob doesn't know that so it would probably crash ....
|
|
|
|
|
|
2005-01-03 16:14:02 +00:00
|
|
|
|
sal_uInt32 nRemaining = pResHeader->GetLocalOff() - sizeof(RSHEADER_TYPE);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*pBuffer = (void*)(((BYTE*)pResHeader) + sizeof(RSHEADER_TYPE));
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
// free an eventual fallback InternalResMgr
|
|
|
|
|
if( m_pResImpl != pFallback )
|
|
|
|
|
{
|
2006-06-19 12:48:55 +00:00
|
|
|
|
osl::Guard<osl::Mutex> aGuard2( getResMgrMutex() );
|
2005-01-03 16:14:02 +00:00
|
|
|
|
|
|
|
|
|
ResMgrContainer::get().freeResMgr( pFallback );
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
return nRemaining;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void SimpleResMgr::FreeBlob( void* pBuffer )
|
|
|
|
|
{
|
|
|
|
|
void* pCompleteBuffer = (void*)(((BYTE*)pBuffer) - sizeof(RSHEADER_TYPE));
|
2005-01-03 16:14:02 +00:00
|
|
|
|
rtl_freeMemory(pCompleteBuffer);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
2010-10-14 08:27:31 +02:00
|
|
|
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|