2000-09-18 16:07:07 +00:00
|
|
|
|
/*************************************************************************
|
|
|
|
|
*
|
|
|
|
|
* $RCSfile: resmgr.cxx,v $
|
|
|
|
|
*
|
2002-11-28 10:07:04 +00:00
|
|
|
|
* $Revision: 1.20 $
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*
|
2002-11-28 10:07:04 +00:00
|
|
|
|
* last change: $Author: dv $ $Date: 2002-11-28 11:07:04 $
|
2000-09-18 16:07:07 +00:00
|
|
|
|
*
|
|
|
|
|
* The Contents of this file are made available subject to the terms of
|
|
|
|
|
* either of the following licenses
|
|
|
|
|
*
|
|
|
|
|
* - GNU Lesser General Public License Version 2.1
|
|
|
|
|
* - Sun Industry Standards Source License Version 1.1
|
|
|
|
|
*
|
|
|
|
|
* Sun Microsystems Inc., October, 2000
|
|
|
|
|
*
|
|
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
|
* =============================================
|
|
|
|
|
* Copyright 2000 by Sun Microsystems, Inc.
|
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
|
|
|
*
|
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
|
|
|
*
|
|
|
|
|
* This library 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 for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
* Sun Industry Standards Source License Version 1.1
|
|
|
|
|
* =================================================
|
|
|
|
|
* The contents of this file are subject to the Sun Industry Standards
|
|
|
|
|
* Source License Version 1.1 (the "License"); You may not use this file
|
|
|
|
|
* except in compliance with the License. You may obtain a copy of the
|
|
|
|
|
* License at http://www.openoffice.org/license.html.
|
|
|
|
|
*
|
|
|
|
|
* Software provided under this License is provided on an "AS IS" basis,
|
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
|
|
|
|
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
|
|
|
|
|
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
|
|
|
|
|
* See the License for the specific provisions governing your rights and
|
|
|
|
|
* obligations concerning the Software.
|
|
|
|
|
*
|
|
|
|
|
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
|
|
|
|
|
*
|
|
|
|
|
* Copyright: 2000 by Sun Microsystems, Inc.
|
|
|
|
|
*
|
|
|
|
|
* All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): _______________________________________
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
#ifndef _VOS_SIGNAL_HXX_
|
|
|
|
|
#include <vos/signal.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef _NEW_HXX
|
|
|
|
|
#include <new.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _DEBUG_HXX
|
|
|
|
|
#include <debug.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _TABLE_HXX
|
|
|
|
|
#include <table.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _FSYS_HXX
|
|
|
|
|
#include <fsys.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _STREAM_HXX
|
|
|
|
|
#include <stream.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _INTN_HXX
|
|
|
|
|
#include <intn.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _TOOLS_RESMGR_HXX
|
|
|
|
|
#include <resmgr.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _TOOLS_RC_HXX
|
|
|
|
|
#include <rc.hxx>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _TOOLS_RCID_H
|
|
|
|
|
#include <rcid.h>
|
|
|
|
|
#endif
|
2000-11-16 13:21:17 +00:00
|
|
|
|
#ifndef _OSL_PROCESS_H_
|
|
|
|
|
#include <osl/process.h>
|
|
|
|
|
#endif
|
|
|
|
|
#ifndef _OSL_FILE_HXX_
|
|
|
|
|
#include <osl/file.hxx>
|
|
|
|
|
#endif
|
2001-07-05 09:58:16 +00:00
|
|
|
|
#ifndef _URLOBJ_HXX
|
|
|
|
|
#include <urlobj.hxx>
|
|
|
|
|
#endif
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
#ifndef _TOOLS_SIMPLERESMGR_HXX_
|
|
|
|
|
#include "simplerm.hxx"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#pragma hdrstop
|
|
|
|
|
|
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 ) )
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
|
|
extern ImplSVResourceData aResData;
|
|
|
|
|
inline ImplSVResourceData* GetResData()
|
|
|
|
|
{
|
|
|
|
|
return &aResData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static List & GetResMgrList()
|
|
|
|
|
{
|
|
|
|
|
ImplSVResourceData * pRD = GetResData();
|
|
|
|
|
if ( !pRD->pInternalResMgrList )
|
|
|
|
|
pRD->pInternalResMgrList = new List();
|
|
|
|
|
return *pRD->pInternalResMgrList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct ImpContent
|
|
|
|
|
{
|
|
|
|
|
ULONG nTypeAndId;
|
|
|
|
|
ULONG nOffset;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if defined( OS2 ) && defined( ICC )
|
|
|
|
|
static int _Optlink Compare( const void * pFirst, const void * pSecond )
|
|
|
|
|
#elif S390
|
|
|
|
|
extern "C" { int Compare( const void * pFirst, const void * pSecond )
|
|
|
|
|
#else
|
|
|
|
|
static int __LOADONCALLAPI Compare( const void * pFirst, const void * pSecond )
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
if( ((ImpContent *)pFirst)->nTypeAndId > ((ImpContent *)pSecond)->nTypeAndId )
|
|
|
|
|
return( 1 );
|
|
|
|
|
else if( ((ImpContent *)pFirst)->nTypeAndId < ((ImpContent *)pSecond)->nTypeAndId )
|
|
|
|
|
return( -1 );
|
|
|
|
|
else
|
|
|
|
|
return( 0 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef S390
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if defined( OS2 ) && defined( ICC )
|
|
|
|
|
static int _Optlink Search( const void * nTypeAndId, const void * pSecond )
|
|
|
|
|
#elif S390
|
|
|
|
|
extern "C" { int Search( const void * nTypeAndId, const void * pSecond )
|
|
|
|
|
#else
|
|
|
|
|
static int __LOADONCALLAPI Search( const void * nTypeAndId, const void * pSecond )
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
if( (ULONG)nTypeAndId > (((ImpContent *)pSecond)->nTypeAndId) )
|
|
|
|
|
return( 1 );
|
|
|
|
|
else if( (ULONG)nTypeAndId < (((ImpContent *)pSecond)->nTypeAndId) )
|
|
|
|
|
return( -1 );
|
|
|
|
|
else
|
|
|
|
|
return( 0 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef S390
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
2000-12-05 18:23:20 +00:00
|
|
|
|
static ResHookProc pImplResHookProc = 0;
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
SvStream * InternalResMgr::GetBitmapStream( USHORT nId )
|
|
|
|
|
{
|
|
|
|
|
// Anfang der Strings suchen
|
|
|
|
|
ImpContent * pFind = (ImpContent *)
|
|
|
|
|
bsearch( (void *)((ULONG(RT_SYS_BITMAP) << 16) | nId), pContent, nEntries,
|
|
|
|
|
sizeof( ImpContent ), Search );
|
|
|
|
|
|
|
|
|
|
if ( pFind )
|
|
|
|
|
{
|
|
|
|
|
pStm->Seek( pFind->nOffset );
|
|
|
|
|
return pStm;
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void InternalResMgr::GetResMgrPath( InternalResMgr* pThis,
|
|
|
|
|
const UniString& rFileName,
|
|
|
|
|
const UniString* pAppFileName,
|
|
|
|
|
const UniString* pResourcePath )
|
|
|
|
|
{
|
2001-07-05 09:58:16 +00:00
|
|
|
|
String aResFile;
|
|
|
|
|
String aFileName( rFileName );
|
|
|
|
|
::rtl::OUString aResPath( rFileName.Len() && pResourcePath ? *pResourcePath : String() );
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
if ( rFileName.Len() )
|
|
|
|
|
{
|
|
|
|
|
if ( pAppFileName )
|
|
|
|
|
{
|
2001-07-16 14:35:36 +00:00
|
|
|
|
INetURLObject aAppDir( *pAppFileName, INET_PROT_FILE );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aAppDir.CutName();
|
2001-07-05 09:58:16 +00:00
|
|
|
|
UniString aAppPath = aAppDir.PathToFileName();
|
|
|
|
|
aAppDir.Append( String( RTL_CONSTASCII_USTRINGPARAM( "resource" ) ) );
|
|
|
|
|
UniString aAppResPath = aAppDir.PathToFileName();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
// Default resource path is bin\resource
|
2001-07-05 09:58:16 +00:00
|
|
|
|
if ( aResPath.getLength() )
|
|
|
|
|
aResPath += SEARCH_PATH_DELIMITER_STRING;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aResPath += aAppResPath;
|
|
|
|
|
|
|
|
|
|
// we a search also in the bin path
|
2001-07-05 09:58:16 +00:00
|
|
|
|
aResPath += SEARCH_PATH_DELIMITER_STRING;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
aResPath += aAppPath;
|
|
|
|
|
}
|
|
|
|
|
const sal_Char* pEnv = getenv( "STAR_RESOURCEPATH" );
|
|
|
|
|
if( pEnv )
|
|
|
|
|
{
|
2001-07-05 09:58:16 +00:00
|
|
|
|
if ( aResPath.getLength() )
|
|
|
|
|
aResPath += SEARCH_PATH_DELIMITER_STRING;
|
|
|
|
|
aResPath += ::rtl::OStringToOUString( pEnv, osl_getThreadTextEncoding() );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else if ( pAppFileName )
|
|
|
|
|
{
|
2001-07-16 14:35:36 +00:00
|
|
|
|
INetURLObject aPath( *pAppFileName, INET_PROT_FILE );
|
2001-07-05 09:58:16 +00:00
|
|
|
|
aFileName = aPath.GetName();
|
|
|
|
|
aPath.CutName();
|
|
|
|
|
aResPath = aPath.PathToFileName();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
#if defined( OS2 ) || defined( WIN ) || defined( WNT )
|
2001-07-05 09:58:16 +00:00
|
|
|
|
aFileName.Erase( aResFile.Len() - 4 );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
#endif
|
2001-07-05 09:58:16 +00:00
|
|
|
|
aFileName.AppendAscii( ".res" );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-07-05 09:58:16 +00:00
|
|
|
|
sal_Int32 nIndex = 0;
|
|
|
|
|
while( nIndex != -1 )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2001-07-05 09:58:16 +00:00
|
|
|
|
::rtl::OUString aPath( aResPath.getToken( 0, SEARCH_PATH_DELIMITER, nIndex ) );
|
|
|
|
|
if( aPath.getLength() )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
2001-07-05 09:58:16 +00:00
|
|
|
|
::rtl::OUString aUrl;
|
|
|
|
|
::osl::File::getFileURLFromSystemPath( aPath, aUrl );
|
2001-07-13 07:11:33 +00:00
|
|
|
|
if( aUrl.lastIndexOf( '/' ) != aUrl.getLength()-1 )
|
|
|
|
|
aUrl += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) );
|
2001-07-05 09:58:16 +00:00
|
|
|
|
aUrl += aFileName;
|
|
|
|
|
::osl::FileStatus aStatus( FileStatusMask_Type | FileStatusMask_LinkTargetURL );
|
|
|
|
|
::osl::DirectoryItem aItem;
|
|
|
|
|
if( ::osl::DirectoryItem::get( aUrl, aItem ) == ::osl::FileBase::E_None
|
|
|
|
|
&& aItem.getFileStatus( aStatus ) == ::osl::FileBase::E_None
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
::osl::FileStatus::Type eType = aStatus.getFileType();
|
|
|
|
|
if( eType == ::osl::FileStatus::Link )
|
|
|
|
|
{
|
|
|
|
|
aUrl = aStatus.getLinkTargetURL();
|
|
|
|
|
::osl::FileStatus aRealStatus( FileStatusMask_Type );
|
|
|
|
|
|
|
|
|
|
if( ::osl::DirectoryItem::get( aUrl, aItem ) != ::osl::FileBase::E_None
|
|
|
|
|
|| aItem.getFileStatus( aRealStatus ) != ::osl::FileBase::E_None
|
|
|
|
|
)
|
|
|
|
|
continue;
|
|
|
|
|
eType = aRealStatus.getFileType();
|
|
|
|
|
}
|
|
|
|
|
if( eType == ::osl::FileStatus::Regular )
|
|
|
|
|
{
|
|
|
|
|
::rtl::OUString aSysPath;
|
|
|
|
|
::osl::FileBase::getSystemPathFromFileURL( aUrl, aSysPath );
|
|
|
|
|
aResFile = aSysPath;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-07-05 09:58:16 +00:00
|
|
|
|
|
|
|
|
|
if( aResFile.Len() )
|
|
|
|
|
{
|
2001-07-16 14:35:36 +00:00
|
|
|
|
INetURLObject aPath( aResFile, INET_PROT_FILE );
|
2001-07-05 09:58:16 +00:00
|
|
|
|
pThis->aFileName = aPath.PathToFileName();
|
|
|
|
|
pThis->aShortFileName = aPath.GetName();
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
InternalResMgr::InternalResMgr()
|
|
|
|
|
: pContent( NULL )
|
|
|
|
|
, pStringBlock( NULL )
|
|
|
|
|
, pStm( NULL )
|
|
|
|
|
, bEqual2Content( TRUE )
|
|
|
|
|
, nEntries( 0 )
|
|
|
|
|
, pResUseDump( 0 )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
InternalResMgr::~InternalResMgr()
|
|
|
|
|
{
|
|
|
|
|
SvMemFree(pContent);
|
|
|
|
|
SvMemFree(pStringBlock);
|
|
|
|
|
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: " );
|
|
|
|
|
aLine.Append( ByteString( aFileName, RTL_TEXTENCODING_UTF8 ) );
|
|
|
|
|
aStm.WriteLine( aLine );
|
|
|
|
|
|
|
|
|
|
for( ULONG i = 0; i < pResUseDump->Count(); i++ )
|
|
|
|
|
{
|
|
|
|
|
ULONG nKeyId = pResUseDump->GetObjectKey( i );
|
|
|
|
|
aLine.Assign( "Type/Id: " );
|
|
|
|
|
aLine.Append( ByteString::CreateFromInt32( (nKeyId >> 16) & 0xFFFF ) );
|
|
|
|
|
aLine.Append( '/' );
|
|
|
|
|
aLine.Append( ByteString::CreateFromInt32( nKeyId & 0xFFFF ) );
|
|
|
|
|
aStm.WriteLine( aLine );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
delete pResUseDump;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
InternalResMgr* InternalResMgr::Create( const UniString& rName,
|
|
|
|
|
const UniString* pAppName,
|
|
|
|
|
const UniString* pResPath )
|
|
|
|
|
{
|
|
|
|
|
InternalResMgr* pThis = new InternalResMgr();
|
|
|
|
|
|
|
|
|
|
GetResMgrPath( pThis, rName, pAppName, pResPath );
|
|
|
|
|
|
|
|
|
|
if ( pThis->aFileName.Len() && pThis->Create() )
|
|
|
|
|
return pThis;
|
|
|
|
|
|
|
|
|
|
delete pThis;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
BOOL InternalResMgr::Create()
|
|
|
|
|
{
|
|
|
|
|
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 );
|
|
|
|
|
pContent = (ImpContent *)SvMemAlloc( lContLen );
|
|
|
|
|
pStm->Read( pContent, lContLen );
|
|
|
|
|
// Auf die Anzahl der ImpContent k<>rzen
|
|
|
|
|
nEntries = (UINT32)lContLen / sizeof( ImpContent );
|
|
|
|
|
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 )
|
|
|
|
|
{
|
|
|
|
|
pResUseDump = new Table();
|
|
|
|
|
for( ULONG i = 0; i < nEntries; i++ )
|
|
|
|
|
pResUseDump->Insert( pContent[i].nTypeAndId, NULL );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
// swap the content to the right endian
|
|
|
|
|
pContent[0].nTypeAndId = ResMgr::GetLong( &pContent[0].nTypeAndId );
|
|
|
|
|
pContent[0].nOffset = ResMgr::GetLong( &pContent[0].nOffset );
|
|
|
|
|
for( ULONG i = 0; i < nEntries -1; i++ )
|
|
|
|
|
{
|
|
|
|
|
// swap the content to the right endian
|
|
|
|
|
pContent[i+1].nTypeAndId = ResMgr::GetLong( &pContent[i+1].nTypeAndId );
|
|
|
|
|
pContent[i+1].nOffset = ResMgr::GetLong( &pContent[i+1].nOffset );
|
|
|
|
|
if( pContent[i].nTypeAndId >= pContent[i +1].nTypeAndId )
|
|
|
|
|
bSorted = FALSE;
|
|
|
|
|
if( (pContent[i].nTypeAndId & 0xFFFF0000) == (pContent[i +1].nTypeAndId & 0xFFFF0000)
|
|
|
|
|
&& pContent[i].nOffset >= pContent[i +1].nOffset )
|
|
|
|
|
bEqual2Content = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
DBG_ASSERT( bSorted, "content not sorted" )
|
|
|
|
|
DBG_ASSERT( bEqual2Content, "resource structure wrong" )
|
|
|
|
|
if( !bSorted )
|
|
|
|
|
qsort( pContent, nEntries, sizeof( ImpContent ), Compare );
|
|
|
|
|
|
|
|
|
|
bDone = TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return bDone;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
InternalResMgr* InternalResMgr::GetInternalResMgr( const UniString& rFileName,
|
|
|
|
|
const UniString* pAppName,
|
|
|
|
|
const UniString* pResPath )
|
|
|
|
|
{
|
|
|
|
|
// Nur InternalResMgr's mit FileNamen stehen in der Liste
|
|
|
|
|
if ( rFileName.Len() )
|
|
|
|
|
{
|
|
|
|
|
List& rMgrList = GetResMgrList();
|
|
|
|
|
|
|
|
|
|
InternalResMgr* pEle = (InternalResMgr*)rMgrList.First();
|
|
|
|
|
while( pEle )
|
|
|
|
|
{
|
|
|
|
|
if ( rFileName.EqualsIgnoreCaseAscii( pEle->aFileName ) ||
|
|
|
|
|
rFileName.EqualsIgnoreCaseAscii( pEle->aShortFileName ) )
|
|
|
|
|
{
|
|
|
|
|
pEle->AddRef();
|
|
|
|
|
return pEle;
|
|
|
|
|
}
|
|
|
|
|
pEle = (InternalResMgr*)rMgrList.Next();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
ByteString aTraceStr( "Search/Load-RESDLL:" );
|
|
|
|
|
aTraceStr += ByteString( rFileName, RTL_TEXTENCODING_UTF8 );
|
|
|
|
|
DBG_TRACE( aTraceStr.GetBuffer() );
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
pEle = Create( rFileName, pAppName, pResPath );
|
|
|
|
|
|
|
|
|
|
if ( pEle )
|
|
|
|
|
{
|
|
|
|
|
pEle->AddRef();
|
|
|
|
|
rMgrList.Insert( pEle );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return pEle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void InternalResMgr::FreeInternalResMgr( InternalResMgr* pFreeInternalResMgr )
|
|
|
|
|
{
|
|
|
|
|
// Nur InternalResMgr's mit FileNamen stehen in der Liste und werden vor dem
|
|
|
|
|
// Programmende freigegeben
|
|
|
|
|
if( pFreeInternalResMgr->aFileName.Len() )
|
|
|
|
|
{
|
|
|
|
|
if( pFreeInternalResMgr->ReleaseRef() == 0 )
|
|
|
|
|
GetResMgrList().Remove( pFreeInternalResMgr );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
BOOL InternalResMgr::IsGlobalAvailable( RESOURCE_TYPE nRT, USHORT nId ) const
|
|
|
|
|
{
|
|
|
|
|
// Anfang der Strings suchen
|
|
|
|
|
ImpContent * pFind = (ImpContent *)
|
|
|
|
|
bsearch( (void *)((ULONG(nRT) << 16) | nId), pContent, nEntries,
|
|
|
|
|
sizeof( ImpContent ), Search );
|
|
|
|
|
return pFind != NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void* InternalResMgr::LoadGlobalRes( RESOURCE_TYPE nRT, USHORT nId,
|
|
|
|
|
void **pResHandle )
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
if( pResUseDump )
|
|
|
|
|
pResUseDump->Remove( (ULONG(nRT) << 16) | nId );
|
|
|
|
|
#endif
|
|
|
|
|
// Anfang der Strings suchen
|
|
|
|
|
ImpContent * pFind = (ImpContent *)
|
|
|
|
|
bsearch( (void *)((ULONG(nRT) << 16) | nId), pContent, nEntries,
|
|
|
|
|
sizeof( ImpContent ), Search );
|
|
|
|
|
if( nRT == RSC_STRING && bEqual2Content && pFind )
|
|
|
|
|
{
|
|
|
|
|
// String Optimierung
|
|
|
|
|
if( !pStringBlock )
|
|
|
|
|
{
|
|
|
|
|
// Anfang der Strings suchen
|
|
|
|
|
ImpContent * pFirst = pFind;
|
|
|
|
|
ImpContent * pLast = pFirst;
|
|
|
|
|
while( pFirst > pContent && ((pFirst -1)->nTypeAndId >> 16) == RSC_STRING )
|
|
|
|
|
pFirst--;
|
|
|
|
|
while( pLast < (pContent + nEntries) && (pLast->nTypeAndId >> 16) == RSC_STRING )
|
|
|
|
|
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;
|
|
|
|
|
pStringBlock = (BYTE*)SvMemAlloc( nSize );
|
|
|
|
|
pStm->Seek( pFirst->nOffset );
|
|
|
|
|
pStm->Read( pStringBlock, nSize );
|
|
|
|
|
}
|
|
|
|
|
*pResHandle = pStringBlock;
|
|
|
|
|
return (BYTE*)pStringBlock + pFind->nOffset - nOffCorrection;
|
|
|
|
|
}
|
|
|
|
|
*pResHandle = 0;
|
|
|
|
|
if( pFind )
|
|
|
|
|
{
|
|
|
|
|
RSHEADER_TYPE aHeader;
|
|
|
|
|
pStm->Seek( pFind->nOffset );
|
|
|
|
|
pStm->Read( &aHeader, sizeof( RSHEADER_TYPE ) );
|
2002-05-22 13:44:52 +00:00
|
|
|
|
void * pRes = ::operator new( aHeader.GetGlobOff() );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
memcpy( pRes, &aHeader, sizeof( RSHEADER_TYPE ) );
|
|
|
|
|
pStm->Read( (BYTE*)pRes + sizeof( RSHEADER_TYPE ),
|
|
|
|
|
aHeader.GetGlobOff() - sizeof( RSHEADER_TYPE ) );
|
|
|
|
|
return pRes;
|
|
|
|
|
}
|
|
|
|
|
//Resource holen
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void InternalResMgr::FreeGlobalRes( void * pResHandle, void * pResource )
|
|
|
|
|
{
|
|
|
|
|
if ( !pResHandle )
|
|
|
|
|
// REsource wurde extra allokiert
|
2002-05-22 13:44:52 +00:00
|
|
|
|
::operator delete (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;
|
2000-09-18 16:07:07 +00:00
|
|
|
|
UniString aTypStr( rTypeId.GetId() );
|
|
|
|
|
|
|
|
|
|
if ( !bInUse )
|
|
|
|
|
{
|
|
|
|
|
bInUse = TRUE;
|
|
|
|
|
|
|
|
|
|
ResId aResId( RSCVERSION_ID );
|
|
|
|
|
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
|
|
|
|
|
Resource::GetResManager()->Increment( sizeof( RSHEADER_TYPE ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
bInUse = FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return aTypStr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
static void RscError_Impl( const sal_Char* pMessage, ResMgr* pResMgr,
|
|
|
|
|
RESOURCE_TYPE nRT, USHORT nId,
|
|
|
|
|
ImpRCStack* pResStack, short nStackTop )
|
|
|
|
|
{
|
|
|
|
|
// neuen ResourceMgr erzeugen
|
|
|
|
|
ResMgr* pNewResMgr = new ResMgr( pResMgr->GetFileName() );
|
|
|
|
|
|
|
|
|
|
ByteString aStr = ByteString( pResMgr->GetFileName(), RTL_TEXTENCODING_UTF8 );
|
|
|
|
|
if ( aStr.Len() )
|
|
|
|
|
aStr += '\n';
|
|
|
|
|
|
|
|
|
|
aStr.Append( "Class: " );
|
|
|
|
|
aStr.Append( ByteString( GetTypeRes_Impl( ResId( nRT, pNewResMgr ) ), RTL_TEXTENCODING_UTF8 ) );
|
|
|
|
|
aStr.Append( ", Id: " );
|
|
|
|
|
aStr.Append( ByteString::CreateFromInt32( (long)nId ) );
|
|
|
|
|
aStr.Append( ". " );
|
|
|
|
|
aStr.Append( pMessage );
|
|
|
|
|
|
|
|
|
|
aStr.Append( "\nResource Stack\n" );
|
|
|
|
|
while( nStackTop > 0 )
|
|
|
|
|
{
|
|
|
|
|
aStr.Append( "Class: " );
|
|
|
|
|
aStr.Append( ByteString( GetTypeRes_Impl( ResId( (pResStack + nStackTop)->pResource->GetRT(), pNewResMgr ) ), RTL_TEXTENCODING_UTF8 ) );
|
|
|
|
|
aStr.Append( ", Id: " );
|
|
|
|
|
aStr.Append( ByteString::CreateFromInt32( (long)(pResStack + nStackTop)->pResource->GetId() ) );
|
|
|
|
|
nStackTop--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete pNewResMgr;
|
|
|
|
|
|
|
|
|
|
DBG_ERROR( aStr.GetBuffer() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
|
|
static void RscException_Impl()
|
|
|
|
|
{
|
|
|
|
|
switch ( NAMESPACE_VOS(OSignalHandler)::raise( OSL_SIGNAL_USER_RESOURCEFAILURE, (void*)"" ) )
|
|
|
|
|
{
|
|
|
|
|
case NAMESPACE_VOS(OSignalHandler)::TAction_CallNextHandler:
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NAMESPACE_VOS(OSignalHandler)::TAction_Ignore:
|
|
|
|
|
return;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NAMESPACE_VOS(OSignalHandler)::TAction_AbortApplication:
|
|
|
|
|
abort();
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NAMESPACE_VOS(OSignalHandler)::TAction_KillApplication:
|
|
|
|
|
exit(-1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
|
|
void ImpRCStack::Init( ResMgr* pMgr, const Resource* pObj, USHORT Id )
|
|
|
|
|
{
|
|
|
|
|
pResource = NULL;
|
|
|
|
|
pClassRes = NULL;
|
|
|
|
|
Flags = RC_NOTYPE;
|
|
|
|
|
aResHandle = NULL;
|
|
|
|
|
pResObj = pObj;
|
|
|
|
|
nId = Id & ~RSC_DONTRELEASE; //TLX: Besser Init aendern
|
|
|
|
|
pResMgr = pMgr;
|
|
|
|
|
if ( !(Id & RSC_DONTRELEASE) )
|
|
|
|
|
Flags |= RC_AUTORELEASE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void ImpRCStack::Clear()
|
|
|
|
|
{
|
|
|
|
|
pResource = NULL;
|
|
|
|
|
pClassRes = NULL;
|
|
|
|
|
Flags = RC_NOTYPE;
|
|
|
|
|
aResHandle = NULL;
|
|
|
|
|
pResObj = NULL;
|
|
|
|
|
nId = 0;
|
|
|
|
|
pResMgr = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
static RSHEADER_TYPE* LocalResource( const ImpRCStack* pStack,
|
|
|
|
|
RESOURCE_TYPE nRTType,
|
|
|
|
|
USHORT nId )
|
|
|
|
|
{
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
|
|
void ResMgr::DestroyAllResMgr()
|
|
|
|
|
{
|
|
|
|
|
ImplSVResourceData* pSVInData = GetResData();
|
|
|
|
|
|
|
|
|
|
// Da auch von Abort gerufen werden kann, geben wir alle
|
|
|
|
|
// ResMgr's und alle InternalResMgr's hier frei
|
|
|
|
|
List* pMgrList = pSVInData->pInternalResMgrList;
|
|
|
|
|
if ( pMgrList )
|
|
|
|
|
{
|
|
|
|
|
InternalResMgr* pEle = (InternalResMgr*)pMgrList->First();
|
|
|
|
|
while ( pEle )
|
|
|
|
|
{
|
|
|
|
|
DBG_WARNING1( "ResMgr's not destroyed: %s",
|
|
|
|
|
ByteString( pEle->aFileName, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
|
|
|
|
|
pEle->ReleaseReference();
|
|
|
|
|
pEle = (InternalResMgr*)pMgrList->Next();
|
|
|
|
|
}
|
|
|
|
|
delete pMgrList;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void ResMgr::Init( const UniString& rFileName )
|
|
|
|
|
{
|
|
|
|
|
if ( !pImpRes )
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
ByteString aStr( "Resourcefile not found:\n" );
|
|
|
|
|
aStr += ByteString( rFileName, RTL_TEXTENCODING_UTF8 );
|
|
|
|
|
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" );
|
|
|
|
|
aStr += ByteString( pImpRes->aFileName, RTL_TEXTENCODING_UTF8 );
|
|
|
|
|
DbgError( aStr.GetBuffer() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
nTopRes = 0;
|
|
|
|
|
aStack[0].Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResMgr::ResMgr( const UniString& rFileName,
|
|
|
|
|
const UniString* pAppName,
|
|
|
|
|
const UniString* pResPath )
|
|
|
|
|
{
|
|
|
|
|
pImpRes = InternalResMgr::GetInternalResMgr( rFileName, pAppName, pResPath );
|
|
|
|
|
Init( pImpRes ? (const UniString&)pImpRes->aFileName : rFileName );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResMgr::ResMgr( InternalResMgr * pImpMgr )
|
|
|
|
|
{
|
|
|
|
|
pImpRes = pImpMgr;
|
|
|
|
|
Init( pImpMgr->aFileName );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResMgr::~ResMgr()
|
|
|
|
|
{
|
|
|
|
|
InternalResMgr::FreeInternalResMgr( pImpRes );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
|
|
|
|
|
void ResMgr::TestStack( const Resource* pResObj )
|
|
|
|
|
{
|
|
|
|
|
if ( DbgIsResource() )
|
|
|
|
|
{
|
|
|
|
|
for( short i = 1; i <= nTopRes; i++ )
|
|
|
|
|
{
|
|
|
|
|
if ( aStack[i].pResObj == pResObj )
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
RscError_Impl( "Resource not freed! ", this,
|
|
|
|
|
aStack[i].pResource->GetRT(),
|
|
|
|
|
aStack[i].pResource->GetId(),
|
|
|
|
|
aStack, i -1 );
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
void ResMgr::TestStack( const Resource* )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
BOOL ResMgr::IsAvailable( const ResId& rId, const Resource* pResObj ) const
|
|
|
|
|
{
|
|
|
|
|
BOOL bAvailable = FALSE;
|
|
|
|
|
RSHEADER_TYPE* pClassRes = rId.GetpResource();
|
|
|
|
|
RESOURCE_TYPE nRT = rId.GetRT2();
|
|
|
|
|
USHORT nId = rId.GetId();
|
|
|
|
|
const ResMgr* pMgr = rId.GetResMgr();
|
|
|
|
|
|
|
|
|
|
if ( !pMgr )
|
|
|
|
|
pMgr = this;
|
|
|
|
|
|
|
|
|
|
if ( !pResObj || pResObj == pMgr->aStack[pMgr->nTopRes].pResObj )
|
|
|
|
|
{
|
|
|
|
|
if ( !pClassRes )
|
|
|
|
|
pClassRes = LocalResource( &pMgr->aStack[pMgr->nTopRes], nRT, nId );
|
|
|
|
|
if ( pClassRes )
|
|
|
|
|
{
|
|
|
|
|
if ( pClassRes->GetRT() == nRT )
|
|
|
|
|
bAvailable = TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// vieleicht globale Resource
|
|
|
|
|
if ( !pClassRes )
|
|
|
|
|
bAvailable = pMgr->pImpRes->IsGlobalAvailable( nRT, nId );
|
|
|
|
|
|
|
|
|
|
return bAvailable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
inline ResMgr* GetActualResMgr()
|
|
|
|
|
{
|
|
|
|
|
return GetResData()->pAppResMgr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
BOOL ResMgr::GetResource( const ResId& rId, const Resource* pResObj )
|
|
|
|
|
{
|
|
|
|
|
DBG_TESTSOLARMUTEX();
|
|
|
|
|
|
|
|
|
|
ResMgr* pMgr = rId.GetResMgr();
|
|
|
|
|
if ( pMgr && (this != pMgr) )
|
|
|
|
|
return pMgr->GetResource( rId, pResObj );
|
|
|
|
|
|
|
|
|
|
RSHEADER_TYPE* pClassRes = rId.GetpResource();
|
|
|
|
|
RESOURCE_TYPE nRT = rId.GetRT2();
|
|
|
|
|
USHORT nId = rId.GetId();
|
|
|
|
|
|
|
|
|
|
ResMgr* pLastMgr = GetActualResMgr();
|
|
|
|
|
if ( pLastMgr != this )
|
|
|
|
|
Resource::SetResManager( this );
|
|
|
|
|
|
|
|
|
|
nTopRes++; // Stackzeiger erhoehen
|
|
|
|
|
ImpRCStack* pTop = &aStack[nTopRes];
|
|
|
|
|
pTop->Init( pLastMgr, pResObj, nId |
|
|
|
|
|
(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!",
|
|
|
|
|
this, nRT, nId, aStack, nTopRes -1 );
|
|
|
|
|
#endif
|
|
|
|
|
RscException_Impl();
|
|
|
|
|
nTopRes--;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
pTop->pClassRes = LocalResource( pTop -1, nRT, nId );
|
|
|
|
|
|
|
|
|
|
if ( pTop->pClassRes )
|
|
|
|
|
// lokale Resource, nicht system Resource
|
|
|
|
|
pTop->pResource = (RSHEADER_TYPE *)pTop->pClassRes;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pTop->Flags |= RC_GLOBAL;
|
|
|
|
|
pTop->pClassRes = pImpRes->LoadGlobalRes( nRT, nId, &pTop->aResHandle );
|
|
|
|
|
if ( pTop->pClassRes )
|
|
|
|
|
pTop->pResource = (RSHEADER_TYPE *)pTop->pClassRes;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
RscError_Impl( "Cannot load resource! ",
|
|
|
|
|
this, nRT, nId, aStack, nTopRes -1 );
|
|
|
|
|
#endif
|
|
|
|
|
RscException_Impl();
|
|
|
|
|
nTopRes--;
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void * ResMgr::GetResourceSkipHeader( const ResId& rResId, ResMgr ** ppResMgr )
|
|
|
|
|
{
|
|
|
|
|
if ( rResId.GetResMgr() )
|
|
|
|
|
*ppResMgr = rResId.GetResMgr();
|
|
|
|
|
else
|
|
|
|
|
*ppResMgr = Resource::GetResManager();
|
|
|
|
|
(*ppResMgr)->GetResource( rResId );
|
|
|
|
|
(*ppResMgr)->Increment( sizeof( RSHEADER_TYPE ) );
|
|
|
|
|
return (*ppResMgr)->GetClass();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
void ResMgr::PopContext( const Resource* pResObj )
|
|
|
|
|
#else
|
|
|
|
|
void ResMgr::PopContext( const Resource* )
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
if ( DbgIsResource() )
|
|
|
|
|
{
|
|
|
|
|
if ( (aStack[nTopRes].pResObj != pResObj) || !nTopRes )
|
|
|
|
|
{
|
|
|
|
|
RscError_Impl( "Cannot free resource! ", this,
|
|
|
|
|
RSC_NOTYPE, 0, aStack, nTopRes );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if ( nTopRes )
|
|
|
|
|
{
|
|
|
|
|
ImpRCStack* pTop = &aStack[nTopRes];
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
|
if ( DbgIsResource() )
|
|
|
|
|
{
|
|
|
|
|
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(),
|
|
|
|
|
aStack, nTopRes -1 );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Resource freigeben
|
|
|
|
|
if ( pTop->Flags & RC_GLOBAL )
|
|
|
|
|
// kann auch Fremd-Ressource sein
|
|
|
|
|
pImpRes->FreeGlobalRes( pTop->aResHandle, pTop->pResource );
|
|
|
|
|
if ( pTop->pResMgr != this )
|
|
|
|
|
// wurde durch ResId gesetzt, automatisch zuruecksetzen
|
|
|
|
|
Resource::SetResManager( pTop->pResMgr );
|
|
|
|
|
nTopRes--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
RSHEADER_TYPE* ResMgr::CreateBlock( const ResId& rId )
|
|
|
|
|
{
|
|
|
|
|
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.
|
2002-05-22 13:44:52 +00:00
|
|
|
|
pHeader = (RSHEADER_TYPE*)::operator new( 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 )
|
|
|
|
|
{
|
|
|
|
|
#ifdef __BIGENDIAN
|
|
|
|
|
return *(UINT16*)pShort;
|
|
|
|
|
#else
|
|
|
|
|
return SWAPSHORT( *(UINT16*)pShort );
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
INT32 ResMgr::GetLong( void * pLong )
|
|
|
|
|
{
|
|
|
|
|
#ifdef __BIGENDIAN
|
|
|
|
|
return (long)(((INT32)(*(UINT16*)pLong) << 16) | *(((UINT16*)pLong) + 1));
|
|
|
|
|
#else
|
|
|
|
|
return ((INT32)(*(BYTE*)pLong) << 24)
|
|
|
|
|
| ((INT32)(*((BYTE*)pLong +1)) << 16)
|
|
|
|
|
| ((INT32)(*((BYTE*)pLong +2)) << 8)
|
|
|
|
|
| (INT32)(*((BYTE*)pLong +3));
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
USHORT ResMgr::GetString( UniString& rStr, const BYTE* pStr )
|
|
|
|
|
{
|
|
|
|
|
UniString aString( (sal_Char*)pStr, RTL_TEXTENCODING_UTF8,
|
|
|
|
|
RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_MAPTOPRIVATE |
|
|
|
|
|
RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_DEFAULT |
|
|
|
|
|
RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT );
|
2000-12-05 18:23:20 +00:00
|
|
|
|
if ( pImplResHookProc )
|
|
|
|
|
pImplResHookProc( aString );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
rStr = aString;
|
|
|
|
|
return GetStringSize( pStr );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
USHORT ResMgr::GetStringSize( const BYTE* pStr )
|
|
|
|
|
{
|
|
|
|
|
return GetStringSize( strlen( (const char*)pStr ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
USHORT ResMgr::GetRemainSize()
|
|
|
|
|
{
|
|
|
|
|
return (USHORT)((long)(BYTE *)aStack[nTopRes].pResource +
|
|
|
|
|
aStack[nTopRes].pResource->GetLocalOff() -
|
|
|
|
|
(long)(BYTE *)aStack[nTopRes].pClassRes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void* ResMgr::Increment( USHORT nSize )
|
|
|
|
|
{
|
|
|
|
|
BYTE* pClassRes = (BYTE*)aStack[nTopRes].pClassRes + nSize;
|
|
|
|
|
|
|
|
|
|
aStack[nTopRes].pClassRes = pClassRes;
|
|
|
|
|
|
|
|
|
|
RSHEADER_TYPE* pRes = aStack[nTopRes].pResource;
|
|
|
|
|
|
|
|
|
|
if ( (pRes->GetGlobOff() == pRes->GetLocalOff()) &&
|
|
|
|
|
(((char*)pRes + pRes->GetLocalOff()) == aStack[nTopRes].pClassRes) &&
|
|
|
|
|
(aStack[nTopRes].Flags & RC_AUTORELEASE))
|
|
|
|
|
{
|
|
|
|
|
PopContext( aStack[nTopRes].pResObj );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return pClassRes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const char* ResMgr::GetLang( LanguageType& nType, USHORT nPrio )
|
|
|
|
|
{
|
|
|
|
|
if ( nType == LANGUAGE_SYSTEM || nType == LANGUAGE_DONTKNOW )
|
|
|
|
|
nType = ::GetSystemLanguage();
|
|
|
|
|
|
|
|
|
|
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";
|
|
|
|
|
|
|
|
|
|
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";
|
|
|
|
|
|
|
|
|
|
case LANGUAGE_SPANISH:
|
|
|
|
|
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";
|
|
|
|
|
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-18 10:42:35 +00:00
|
|
|
|
return "91";
|
2002-11-28 10:07:04 +00:00
|
|
|
|
case LANGUAGE_HINDI:
|
|
|
|
|
return "66";
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
case LANGUAGE_ARABIC:
|
|
|
|
|
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";
|
|
|
|
|
|
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,
|
|
|
|
|
LanguageType nType,
|
|
|
|
|
const UniString* pAppName,
|
|
|
|
|
const UniString* pResPath )
|
|
|
|
|
{
|
|
|
|
|
// Suchreihenfolge festlegen
|
2001-05-28 11:07:45 +00:00
|
|
|
|
const sal_Char* pLang[6];
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
// Resourcefile suchen
|
|
|
|
|
UniString aName;
|
|
|
|
|
InternalResMgr* pInternalResMgr = NULL;
|
2000-11-16 13:21:17 +00:00
|
|
|
|
int i;
|
2001-05-18 09:35:38 +00:00
|
|
|
|
for ( i = 0; i < 6; i++ )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
pLang[i] = GetLang( nType, i );
|
|
|
|
|
|
|
|
|
|
if ( pLang[i] && (i == 0 || pLang[i] != pLang[0]) )
|
|
|
|
|
{
|
|
|
|
|
aName.AssignAscii( pPrefixName );
|
|
|
|
|
aName.AppendAscii( pLang[i] );
|
|
|
|
|
aName.AppendAscii( ".res" );
|
|
|
|
|
pInternalResMgr = InternalResMgr::GetInternalResMgr( aName, pAppName, pResPath );
|
|
|
|
|
if ( pInternalResMgr )
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return new ResMgr( pInternalResMgr );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-11-16 13:21:17 +00:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResMgr* ResMgr::SearchCreateResMgr(
|
|
|
|
|
const sal_Char* pPrefixName,
|
|
|
|
|
LanguageType& nType )
|
|
|
|
|
{
|
|
|
|
|
if( nType == LANGUAGE_DONTKNOW )
|
|
|
|
|
nType = GetSystemLanguage();
|
|
|
|
|
|
|
|
|
|
::rtl::OUString aRtlUniAppFileName;
|
|
|
|
|
osl_getExecutableFile( &aRtlUniAppFileName.pData );
|
|
|
|
|
::rtl::OUString aRtlAppFileName;
|
2001-05-10 09:30:58 +00:00
|
|
|
|
::osl::FileBase::getSystemPathFromFileURL( aRtlUniAppFileName, aRtlAppFileName );
|
2000-11-16 13:21:17 +00:00
|
|
|
|
String aAppFileName( aRtlAppFileName );
|
|
|
|
|
|
|
|
|
|
const sal_Char* pLang = GetLang( nType, 0 );
|
|
|
|
|
String aBaseName( String::CreateFromAscii( pPrefixName ) );
|
|
|
|
|
String aName( aBaseName );
|
|
|
|
|
aName.AppendAscii( pLang ? pLang : "" );
|
|
|
|
|
aName.AppendAscii( ".res" );
|
|
|
|
|
|
|
|
|
|
InternalResMgr* pInternalResMgr = InternalResMgr::GetInternalResMgr( aName, &aAppFileName, NULL );
|
2000-09-18 16:07:07 +00:00
|
|
|
|
if ( pInternalResMgr )
|
|
|
|
|
return new ResMgr( pInternalResMgr );
|
|
|
|
|
|
2000-11-16 13:21:17 +00:00
|
|
|
|
static const LanguageType aLanguages[] =
|
|
|
|
|
{
|
|
|
|
|
LANGUAGE_ENGLISH_US,
|
2000-12-01 13:51:30 +00:00
|
|
|
|
LANGUAGE_GERMAN,
|
2000-11-16 13:21:17 +00:00
|
|
|
|
LANGUAGE_FRENCH,
|
|
|
|
|
LANGUAGE_ITALIAN,
|
|
|
|
|
LANGUAGE_SPANISH,
|
|
|
|
|
LANGUAGE_DUTCH,
|
|
|
|
|
LANGUAGE_SWEDISH,
|
|
|
|
|
LANGUAGE_TURKISH,
|
|
|
|
|
LANGUAGE_SWEDISH_FINLAND,
|
|
|
|
|
LANGUAGE_PORTUGUESE_BRAZILIAN,
|
|
|
|
|
LANGUAGE_PORTUGUESE,
|
|
|
|
|
LANGUAGE_POLISH,
|
|
|
|
|
LANGUAGE_NORWEGIAN,
|
|
|
|
|
LANGUAGE_NORWEGIAN_NYNORSK,
|
|
|
|
|
LANGUAGE_NORWEGIAN_BOKMAL,
|
|
|
|
|
LANGUAGE_FINNISH,
|
|
|
|
|
LANGUAGE_DUTCH_BELGIAN,
|
|
|
|
|
LANGUAGE_DANISH,
|
|
|
|
|
LANGUAGE_CATALAN,
|
|
|
|
|
LANGUAGE_CHINESE_SIMPLIFIED,
|
|
|
|
|
LANGUAGE_CHINESE_TRADITIONAL,
|
|
|
|
|
LANGUAGE_JAPANESE,
|
|
|
|
|
LANGUAGE_HUNGARIAN,
|
|
|
|
|
LANGUAGE_CZECH,
|
|
|
|
|
LANGUAGE_RUSSIAN,
|
|
|
|
|
LANGUAGE_ARABIC,
|
|
|
|
|
LANGUAGE_GREEK,
|
|
|
|
|
LANGUAGE_KOREAN,
|
2002-05-31 11:08:35 +00:00
|
|
|
|
LANGUAGE_KOREAN_JOHAB,
|
2002-11-28 10:07:04 +00:00
|
|
|
|
LANGUAGE_THAI,
|
|
|
|
|
LANGUAGE_HINDI
|
2000-11-16 13:21:17 +00:00
|
|
|
|
};
|
|
|
|
|
|
2002-05-22 13:44:52 +00:00
|
|
|
|
for( size_t i = 0; i < sizeof( aLanguages )/sizeof( aLanguages[0] ); i++ )
|
2000-11-16 13:21:17 +00:00
|
|
|
|
{
|
|
|
|
|
nType = aLanguages[i];
|
|
|
|
|
aName = aBaseName;
|
|
|
|
|
aName.AppendAscii( GetLang( nType, 0 ) );
|
|
|
|
|
aName.AppendAscii( ".res" );
|
|
|
|
|
pInternalResMgr = InternalResMgr::GetInternalResMgr( aName, &aAppFileName, NULL );
|
|
|
|
|
if ( pInternalResMgr )
|
|
|
|
|
return new ResMgr( pInternalResMgr );
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
INT16 ResMgr::ReadShort()
|
|
|
|
|
{
|
|
|
|
|
INT16 n = GetShort( GetClass() );
|
|
|
|
|
Increment( sizeof( INT16 ) );
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
INT32 ResMgr::ReadLong()
|
|
|
|
|
{
|
|
|
|
|
INT32 n = GetLong( GetClass() );
|
|
|
|
|
Increment( sizeof( INT32 ) );
|
|
|
|
|
return n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
UniString ResMgr::ReadString()
|
|
|
|
|
{
|
|
|
|
|
UniString aRet;
|
|
|
|
|
Increment( GetString( aRet, (const BYTE*)GetClass() ) );
|
|
|
|
|
return aRet;
|
|
|
|
|
}
|
|
|
|
|
|
2000-12-05 18:23:20 +00:00
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void ResMgr::SetReadStringHook( ResHookProc pProc )
|
|
|
|
|
{
|
|
|
|
|
pImplResHookProc = pProc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
ResHookProc ResMgr::GetReadStringHook()
|
|
|
|
|
{
|
|
|
|
|
return pImplResHookProc;
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-18 16:07:07 +00:00
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
|
|
SimpleResMgr::SimpleResMgr( const sal_Char* pPrefixName,
|
|
|
|
|
LanguageType nType,
|
|
|
|
|
const UniString* pAppName,
|
|
|
|
|
const UniString* pResPath )
|
|
|
|
|
{
|
|
|
|
|
// Suchreihenfolge festlegen
|
2001-05-28 11:07:45 +00:00
|
|
|
|
const sal_Char* pLang[6];
|
2000-09-18 16:07:07 +00:00
|
|
|
|
|
|
|
|
|
// Resourcefile suchen
|
|
|
|
|
UniString aName;
|
2001-05-28 11:07:45 +00:00
|
|
|
|
for ( int i = 0; i < 6; i++ )
|
2000-09-18 16:07:07 +00:00
|
|
|
|
{
|
|
|
|
|
pLang[i] = ResMgr::GetLang( nType, i );
|
|
|
|
|
|
|
|
|
|
if ( pLang[i] && (i == 0 || pLang[i] != pLang[0]) )
|
|
|
|
|
{
|
|
|
|
|
aName.AssignAscii( pPrefixName );
|
|
|
|
|
aName.AppendAscii( pLang[i] );
|
|
|
|
|
aName.AppendAscii( ".res" );
|
|
|
|
|
m_pResImpl = InternalResMgr::Create( aName, pAppName, pResPath );
|
|
|
|
|
if ( m_pResImpl )
|
2000-11-06 07:17:58 +00:00
|
|
|
|
{
|
|
|
|
|
m_pResImpl->AddRef();
|
2000-09-18 16:07:07 +00:00
|
|
|
|
break;
|
2000-11-06 07:17:58 +00:00
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
SimpleResMgr::~SimpleResMgr()
|
|
|
|
|
{
|
2000-12-15 09:01:38 +00:00
|
|
|
|
if(m_pResImpl)
|
|
|
|
|
{
|
2000-11-06 07:17:58 +00:00
|
|
|
|
#ifdef DBG_UTIL
|
2000-12-15 09:01:38 +00:00
|
|
|
|
sal_Int32 nRefCount =
|
2000-11-06 07:17:58 +00:00
|
|
|
|
#endif
|
2000-12-15 09:01:38 +00:00
|
|
|
|
m_pResImpl->ReleaseRef();
|
|
|
|
|
DBG_ASSERT(0 == nRefCount, "SimpleResMgr::~SimpleResMgr: invalid impl ref count!");
|
|
|
|
|
// our impl class is not expected to be shared, and only we ourself should have added a ref
|
|
|
|
|
}
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
UniString SimpleResMgr::ReadString( USHORT nId )
|
|
|
|
|
{
|
|
|
|
|
NAMESPACE_VOS(OGuard) aGuard(m_aAccessSafety);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
RSHEADER_TYPE* pResHeader = (RSHEADER_TYPE*)m_pResImpl->LoadGlobalRes( RSC_STRING, nId, &pResHandle );
|
|
|
|
|
if ( !pResHeader )
|
|
|
|
|
// no such resource
|
|
|
|
|
return sReturn;
|
|
|
|
|
|
2002-05-22 13:44:52 +00:00
|
|
|
|
// USHORT 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 ....
|
|
|
|
|
m_pResImpl->FreeGlobalRes( pResHeader, pResHandle );
|
|
|
|
|
return sReturn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
USHORT SimpleResMgr::ReadBlob( USHORT nId, void** pBuffer )
|
|
|
|
|
{
|
|
|
|
|
NAMESPACE_VOS(OGuard) aGuard(m_aAccessSafety);
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
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 !" );
|
|
|
|
|
|
|
|
|
|
// no exception handling, this would require the locking of the solar mutex which isn't allowed within this class
|
|
|
|
|
if ( !pResHeader )
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
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 ....
|
|
|
|
|
|
|
|
|
|
USHORT nRemaining = pResHeader->GetLocalOff() - sizeof(RSHEADER_TYPE);
|
|
|
|
|
*pBuffer = (void*)(((BYTE*)pResHeader) + sizeof(RSHEADER_TYPE));
|
|
|
|
|
return nRemaining;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void SimpleResMgr::FreeBlob( void* pBuffer )
|
|
|
|
|
{
|
|
|
|
|
void* pCompleteBuffer = (void*)(((BYTE*)pBuffer) - sizeof(RSHEADER_TYPE));
|
2002-05-22 13:44:52 +00:00
|
|
|
|
::operator delete (pCompleteBuffer);
|
2000-09-18 16:07:07 +00:00
|
|
|
|
}
|