Kaydet (Commit) a5afd981 authored tarafından Caolán McNamara's avatar Caolán McNamara

don't leak PPDParsers

üst 06bd3364
...@@ -125,6 +125,7 @@ class PPDParser ...@@ -125,6 +125,7 @@ class PPDParser
{ {
friend class PPDContext; friend class PPDContext;
friend class CUPSManager; friend class CUPSManager;
friend class PPDCache;
typedef ::std::hash_map< ::rtl::OUString, PPDKey*, ::rtl::OUStringHash > hash_type; typedef ::std::hash_map< ::rtl::OUString, PPDKey*, ::rtl::OUStringHash > hash_type;
typedef ::std::vector< PPDKey* > value_type; typedef ::std::vector< PPDKey* > value_type;
...@@ -141,11 +142,6 @@ public: ...@@ -141,11 +142,6 @@ public:
PPDConstraint() : m_pKey1( NULL ), m_pOption1( NULL ), m_pKey2( NULL ), m_pOption2( NULL ) {} PPDConstraint() : m_pKey1( NULL ), m_pOption1( NULL ), m_pKey2( NULL ), m_pOption2( NULL ) {}
}; };
private: private:
static ::std::list< PPDParser* > aAllParsers;
static ::std::hash_map< rtl::OUString, rtl::OUString, rtl::OUStringHash >*
pAllPPDFiles;
hash_type m_aKeys; hash_type m_aKeys;
value_type m_aOrderedKeys; value_type m_aOrderedKeys;
::std::list< PPDConstraint > m_aConstraints; ::std::list< PPDConstraint > m_aConstraints;
......
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include "osl/thread.h" #include "osl/thread.h"
#include "rtl/strbuf.hxx" #include "rtl/strbuf.hxx"
#include "rtl/ustrbuf.hxx" #include "rtl/ustrbuf.hxx"
#include "rtl/instance.hxx"
#include <sal/macros.h> #include <sal/macros.h>
#include "com/sun/star/lang/Locale.hpp" #include "com/sun/star/lang/Locale.hpp"
...@@ -245,6 +246,26 @@ namespace psp ...@@ -245,6 +246,26 @@ namespace psp
} }
return aResult; return aResult;
} }
class PPDCache
{
public:
std::list< PPDParser* > aAllParsers;
std::hash_map< rtl::OUString, rtl::OUString, rtl::OUStringHash >* pAllPPDFiles;
PPDCache()
: pAllPPDFiles(NULL)
{}
~PPDCache()
{
while( aAllParsers.begin() != aAllParsers.end() )
{
delete aAllParsers.front();
aAllParsers.pop_front();
}
delete pAllPPDFiles;
pAllPPDFiles = NULL;
}
};
} }
using namespace psp; using namespace psp;
...@@ -258,8 +279,10 @@ using namespace rtl; ...@@ -258,8 +279,10 @@ using namespace rtl;
#define DBG_ASSERT( x, y ) #define DBG_ASSERT( x, y )
#endif #endif
std::list< PPDParser* > PPDParser::aAllParsers; namespace
std::hash_map< OUString, OUString, OUStringHash >* PPDParser::pAllPPDFiles = NULL; {
struct thePPDCache : public rtl::Static<PPDCache, thePPDCache> {};
}
class PPDDecompressStream class PPDDecompressStream
{ {
...@@ -406,6 +429,8 @@ void PPDParser::scanPPDDir( const String& rDir ) ...@@ -406,6 +429,8 @@ void PPDParser::scanPPDDir( const String& rDir )
const int nSuffixes = SAL_N_ELEMENTS(pSuffixes); const int nSuffixes = SAL_N_ELEMENTS(pSuffixes);
PPDCache &rPPDCache = thePPDCache::get();
osl::Directory aDir( rDir ); osl::Directory aDir( rDir );
aDir.open(); aDir.open();
osl::DirectoryItem aItem; osl::DirectoryItem aItem;
...@@ -438,7 +463,7 @@ void PPDParser::scanPPDDir( const String& rDir ) ...@@ -438,7 +463,7 @@ void PPDParser::scanPPDDir( const String& rDir )
{ {
if( aFileName.endsWithIgnoreAsciiCaseAsciiL( pSuffixes[nSuffix].pSuffix, pSuffixes[nSuffix].nSuffixLen ) ) if( aFileName.endsWithIgnoreAsciiCaseAsciiL( pSuffixes[nSuffix].pSuffix, pSuffixes[nSuffix].nSuffixLen ) )
{ {
(*pAllPPDFiles)[ aFileName.copy( 0, aFileName.getLength() - pSuffixes[nSuffix].nSuffixLen ) ] = aPPDFile.PathToFileName(); (*rPPDCache.pAllPPDFiles)[ aFileName.copy( 0, aFileName.getLength() - pSuffixes[nSuffix].nSuffixLen ) ] = aPPDFile.PathToFileName();
break; break;
} }
} }
...@@ -456,10 +481,11 @@ void PPDParser::scanPPDDir( const String& rDir ) ...@@ -456,10 +481,11 @@ void PPDParser::scanPPDDir( const String& rDir )
void PPDParser::initPPDFiles() void PPDParser::initPPDFiles()
{ {
if( pAllPPDFiles ) PPDCache &rPPDCache = thePPDCache::get();
if( rPPDCache.pAllPPDFiles )
return; return;
pAllPPDFiles = new std::hash_map< OUString, OUString, OUStringHash >(); rPPDCache.pAllPPDFiles = new std::hash_map< OUString, OUString, OUStringHash >();
// check installation directories // check installation directories
std::list< OUString > aPathList; std::list< OUString > aPathList;
...@@ -469,7 +495,7 @@ void PPDParser::initPPDFiles() ...@@ -469,7 +495,7 @@ void PPDParser::initPPDFiles()
INetURLObject aPPDDir( *ppd_it, INET_PROT_FILE, INetURLObject::ENCODE_ALL ); INetURLObject aPPDDir( *ppd_it, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
scanPPDDir( aPPDDir.GetMainURL( INetURLObject::NO_DECODE ) ); scanPPDDir( aPPDDir.GetMainURL( INetURLObject::NO_DECODE ) );
} }
if( pAllPPDFiles->find( OUString( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) ) == pAllPPDFiles->end() ) if( rPPDCache.pAllPPDFiles->find( OUString( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) ) == rPPDCache.pAllPPDFiles->end() )
{ {
// last try: search in directory of executable (mainly for setup) // last try: search in directory of executable (mainly for setup)
OUString aExe; OUString aExe;
...@@ -482,7 +508,7 @@ void PPDParser::initPPDFiles() ...@@ -482,7 +508,7 @@ void PPDParser::initPPDFiles()
#endif #endif
scanPPDDir( aDir.GetMainURL( INetURLObject::NO_DECODE ) ); scanPPDDir( aDir.GetMainURL( INetURLObject::NO_DECODE ) );
#ifdef DEBUG #ifdef DEBUG
fprintf( stderr, "SGENPRT %s\n", pAllPPDFiles->find( OUString( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) ) == pAllPPDFiles->end() ? "not found" : "found" ); fprintf( stderr, "SGENPRT %s\n", rPPDCache.pAllPPDFiles->find( OUString( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) ) == rPPDCache.pAllPPDFiles->end() ? "not found" : "found" );
#endif #endif
} }
} }
...@@ -490,17 +516,19 @@ void PPDParser::initPPDFiles() ...@@ -490,17 +516,19 @@ void PPDParser::initPPDFiles()
void PPDParser::getKnownPPDDrivers( std::list< rtl::OUString >& o_rDrivers, bool bRefresh ) void PPDParser::getKnownPPDDrivers( std::list< rtl::OUString >& o_rDrivers, bool bRefresh )
{ {
PPDCache &rPPDCache = thePPDCache::get();
if( bRefresh ) if( bRefresh )
{ {
delete pAllPPDFiles; delete rPPDCache.pAllPPDFiles;
pAllPPDFiles = NULL; rPPDCache.pAllPPDFiles = NULL;
} }
initPPDFiles(); initPPDFiles();
o_rDrivers.clear(); o_rDrivers.clear();
std::hash_map< OUString, OUString, OUStringHash >::const_iterator it; std::hash_map< OUString, OUString, OUStringHash >::const_iterator it;
for( it = pAllPPDFiles->begin(); it != pAllPPDFiles->end(); ++it ) for( it = rPPDCache.pAllPPDFiles->begin(); it != rPPDCache.pAllPPDFiles->end(); ++it )
o_rDrivers.push_back( it->first ); o_rDrivers.push_back( it->first );
} }
...@@ -512,6 +540,7 @@ String PPDParser::getPPDFile( const String& rFile ) ...@@ -512,6 +540,7 @@ String PPDParser::getPPDFile( const String& rFile )
if( ! aStream.IsOpen() ) if( ! aStream.IsOpen() )
{ {
std::hash_map< OUString, OUString, OUStringHash >::const_iterator it; std::hash_map< OUString, OUString, OUStringHash >::const_iterator it;
PPDCache &rPPDCache = thePPDCache::get();
bool bRetry = true; bool bRetry = true;
do do
...@@ -525,23 +554,23 @@ String PPDParser::getPPDFile( const String& rFile ) ...@@ -525,23 +554,23 @@ String PPDParser::getPPDFile( const String& rFile )
aBase = aBase.copy( nLastIndex+1 ); aBase = aBase.copy( nLastIndex+1 );
do do
{ {
it = pAllPPDFiles->find( aBase ); it = rPPDCache.pAllPPDFiles->find( aBase );
nLastIndex = aBase.lastIndexOf( sal_Unicode( '.' ) ); nLastIndex = aBase.lastIndexOf( sal_Unicode( '.' ) );
if( nLastIndex > 0 ) if( nLastIndex > 0 )
aBase = aBase.copy( 0, nLastIndex ); aBase = aBase.copy( 0, nLastIndex );
} while( it == pAllPPDFiles->end() && nLastIndex > 0 ); } while( it == rPPDCache.pAllPPDFiles->end() && nLastIndex > 0 );
if( it == pAllPPDFiles->end() && bRetry ) if( it == rPPDCache.pAllPPDFiles->end() && bRetry )
{ {
// a new file ? rehash // a new file ? rehash
delete pAllPPDFiles; pAllPPDFiles = NULL; delete rPPDCache.pAllPPDFiles; rPPDCache.pAllPPDFiles = NULL;
bRetry = false; bRetry = false;
// note this is optimized for office start where // note this is optimized for office start where
// no new files occur and initPPDFiles is called only once // no new files occur and initPPDFiles is called only once
} }
} while( ! pAllPPDFiles ); } while( ! rPPDCache.pAllPPDFiles );
if( it != pAllPPDFiles->end() ) if( it != rPPDCache.pAllPPDFiles->end() )
aStream.Open( it->second ); aStream.Open( it->second );
} }
...@@ -625,7 +654,8 @@ const PPDParser* PPDParser::getParser( const String& rFile ) ...@@ -625,7 +654,8 @@ const PPDParser* PPDParser::getParser( const String& rFile )
return NULL; return NULL;
} }
for( ::std::list< PPDParser* >::const_iterator it = aAllParsers.begin(); it != aAllParsers.end(); ++it ) PPDCache &rPPDCache = thePPDCache::get();
for( ::std::list< PPDParser* >::const_iterator it = rPPDCache.aAllParsers.begin(); it != rPPDCache.aAllParsers.end(); ++it )
if( (*it)->m_aFile == aFile ) if( (*it)->m_aFile == aFile )
return *it; return *it;
...@@ -644,24 +674,13 @@ const PPDParser* PPDParser::getParser( const String& rFile ) ...@@ -644,24 +674,13 @@ const PPDParser* PPDParser::getParser( const String& rFile )
{ {
// this may actually be the SGENPRT parser, // this may actually be the SGENPRT parser,
// so ensure uniquness here // so ensure uniquness here
aAllParsers.remove( pNewParser ); rPPDCache.aAllParsers.remove( pNewParser );
// insert new parser to list // insert new parser to list
aAllParsers.push_front( pNewParser ); rPPDCache.aAllParsers.push_front( pNewParser );
} }
return pNewParser; return pNewParser;
} }
void PPDParser::freeAll()
{
while( aAllParsers.begin() != aAllParsers.end() )
{
delete aAllParsers.front();
aAllParsers.pop_front();
}
delete pAllPPDFiles;
pAllPPDFiles = NULL;
}
PPDParser::PPDParser( const String& rFile ) : PPDParser::PPDParser( const String& rFile ) :
m_aFile( rFile ), m_aFile( rFile ),
m_bType42Capable( false ), m_bType42Capable( false ),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment