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