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