LCOV - code coverage report
Current view: top level - tools/source/rc - resmgr.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 501 775 64.6 %
Date: 2012-08-25 Functions: 60 69 87.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 443 1233 35.9 %

           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: */

Generated by: LCOV version 1.10