summaryrefslogtreecommitdiff
path: root/psprint
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2008-06-25 13:21:43 +0000
committerKurt Zenker <kz@openoffice.org>2008-06-25 13:21:43 +0000
commit9ede065284db3439e1edc8dfb7281be73f881ada (patch)
treee1de80f5403c68f162965c1c837a4f035fd26259 /psprint
parentf0c837c9b44f6c3b873fec7df73082f21500e259 (diff)
INTEGRATION: CWS vcl89 (1.25.8); FILE MERGED
2008/05/07 19:47:59 pl 1.25.8.3: #i72327# add getKnownPPDDrivers 2008/05/07 19:06:47 pl 1.25.8.2: #i72327# support for system cups dir 2008/05/07 17:41:51 pl 1.25.8.1: #i72327# support for gzipped PPD files
Diffstat (limited to 'psprint')
-rw-r--r--psprint/source/helper/ppdparser.cxx277
1 files changed, 229 insertions, 48 deletions
diff --git a/psprint/source/helper/ppdparser.cxx b/psprint/source/helper/ppdparser.cxx
index 493bf78c86f3..f2ab3b210a5e 100644
--- a/psprint/source/helper/ppdparser.cxx
+++ b/psprint/source/helper/ppdparser.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: ppdparser.cxx,v $
- * $Revision: 1.25 $
+ * $Revision: 1.26 $
*
* This file is part of OpenOffice.org.
*
@@ -35,21 +35,20 @@
#include <hash_map>
-#include <psprint/ppdparser.hxx>
-#include <tools/debug.hxx>
-#include <psprint/strhelper.hxx>
-#include <psprint/helper.hxx>
-#include <cupsmgr.hxx>
-#include <tools/urlobj.hxx>
-#include <tools/stream.hxx>
-#include <osl/mutex.hxx>
-#include <osl/file.hxx>
-#include <osl/process.h>
-#include <osl/thread.h>
-#include <rtl/strbuf.hxx>
-#include <rtl/ustrbuf.hxx>
-
-#define PRINTER_PPDDIR "driver"
+#include "psprint/ppdparser.hxx"
+#include "tools/debug.hxx"
+#include "psprint/strhelper.hxx"
+#include "psprint/helper.hxx"
+#include "cupsmgr.hxx"
+#include "tools/urlobj.hxx"
+#include "tools/stream.hxx"
+#include "tools/zcodec.hxx"
+#include "osl/mutex.hxx"
+#include "osl/file.hxx"
+#include "osl/process.h"
+#include "osl/thread.h"
+#include "rtl/strbuf.hxx"
+#include "rtl/ustrbuf.hxx"
using namespace psp;
using namespace rtl;
@@ -66,9 +65,149 @@ std::list< PPDParser* > PPDParser::aAllParsers;
std::hash_map< OUString, OUString, OUStringHash >* PPDParser::pAllPPDFiles = NULL;
static String aEmptyString;
+class PPDDecompressStream
+{
+ SvFileStream* mpFileStream;
+ SvMemoryStream* mpMemStream;
+ rtl::OUString maFileName;
+
+ // forbid copying
+ PPDDecompressStream( const PPDDecompressStream& );
+ PPDDecompressStream& operator=(const PPDDecompressStream& );
+
+ public:
+ PPDDecompressStream( const rtl::OUString& rFile );
+ ~PPDDecompressStream();
+
+ bool IsOpen() const;
+ bool IsEof() const;
+ void ReadLine( ByteString& o_rLine);
+ void Open( const rtl::OUString& i_rFile );
+ void Close();
+ const rtl::OUString& GetFileName() const { return maFileName; }
+};
+
+PPDDecompressStream::PPDDecompressStream( const rtl::OUString& i_rFile ) :
+ mpFileStream( NULL ),
+ mpMemStream( NULL )
+{
+ Open( i_rFile );
+}
+
+PPDDecompressStream::~PPDDecompressStream()
+{
+ Close();
+}
+
+void PPDDecompressStream::Open( const rtl::OUString& i_rFile )
+{
+ Close();
+
+ mpFileStream = new SvFileStream( i_rFile, STREAM_READ );
+ maFileName = mpFileStream->GetFileName();
+
+ if( ! mpFileStream->IsOpen() )
+ {
+ Close();
+ return;
+ }
+
+ ByteString aLine;
+ mpFileStream->ReadLine( aLine );
+ mpFileStream->Seek( 0 );
+
+ // check for compress'ed or gzip'ed file
+ ULONG nCompressMethod = 0;
+ if( aLine.Len() > 1 && static_cast<unsigned char>(aLine.GetChar( 0 )) == 0x1f )
+ {
+ if( static_cast<unsigned char>(aLine.GetChar( 1 )) == 0x8b ) // check for gzip
+ nCompressMethod = ZCODEC_DEFAULT | ZCODEC_GZ_LIB;
+ }
+
+ if( nCompressMethod != 0 )
+ {
+ // so let's try to decompress the stream
+ mpMemStream = new SvMemoryStream( 4096, 4096 );
+ ZCodec aCodec;
+ aCodec.BeginCompression( nCompressMethod );
+ long nComp = aCodec.Decompress( *mpFileStream, *mpMemStream );
+ aCodec.EndCompression();
+ if( nComp < 0 )
+ {
+ // decompression failed, must be an uncompressed stream after all
+ delete mpMemStream, mpMemStream = NULL;
+ mpFileStream->Seek( 0 );
+ }
+ else
+ {
+ // compression successfull, can get rid of file stream
+ delete mpFileStream, mpFileStream = NULL;
+ mpMemStream->Seek( 0 );
+ }
+ }
+}
+
+void PPDDecompressStream::Close()
+{
+ delete mpMemStream, mpMemStream = NULL;
+ delete mpFileStream, mpFileStream = NULL;
+}
+
+bool PPDDecompressStream::IsOpen() const
+{
+ return (mpMemStream || (mpFileStream && mpFileStream->IsOpen()));
+}
+
+bool PPDDecompressStream::IsEof() const
+{
+ return ( mpMemStream ? mpMemStream->IsEof() : ( mpFileStream ? mpFileStream->IsEof() : true ) );
+}
+
+void PPDDecompressStream::ReadLine( ByteString& o_rLine )
+{
+ if( mpMemStream )
+ mpMemStream->ReadLine( o_rLine );
+ else if( mpFileStream )
+ mpFileStream->ReadLine( o_rLine );
+}
+
+static osl::FileBase::RC resolveLink( const rtl::OUString& i_rURL, rtl::OUString& o_rResolvedURL, rtl::OUString& o_rBaseName, osl::FileStatus::Type& o_rType, int nLinkLevel = 10 )
+{
+ osl::DirectoryItem aLinkItem;
+ osl::FileBase::RC aRet = osl::FileBase::E_None;
+
+ if( ( aRet = osl::DirectoryItem::get( i_rURL, aLinkItem ) ) == osl::FileBase::E_None )
+ {
+ osl::FileStatus aStatus( FileStatusMask_FileName | FileStatusMask_Type | FileStatusMask_LinkTargetURL );
+ if( ( aRet = aLinkItem.getFileStatus( aStatus ) ) == osl::FileBase::E_None )
+ {
+ if( aStatus.getFileType() == osl::FileStatus::Link )
+ {
+ if( nLinkLevel > 0 )
+ aRet = resolveLink( aStatus.getLinkTargetURL(), o_rResolvedURL, o_rBaseName, o_rType, nLinkLevel-1 );
+ else
+ aRet = osl::FileBase::E_MULTIHOP;
+ }
+ else
+ {
+ o_rResolvedURL = i_rURL;
+ o_rBaseName = aStatus.getFileName();
+ o_rType = aStatus.getFileType();
+ }
+ }
+ }
+ return aRet;
+}
+
void PPDParser::scanPPDDir( const String& rDir )
{
- static const sal_Char* pSuffixes[] = { "PS", "PPD" };
+ static struct suffix_t
+ {
+ const sal_Char* pSuffix;
+ const sal_Int32 nSuffixLen;
+ } const pSuffixes[] =
+ { { ".PS", 3 }, { ".PPD", 4 }, { ".PS.GZ", 6 }, { ".PPD.GZ", 7 } };
+
const int nSuffixes = sizeof(pSuffixes)/sizeof(pSuffixes[0]);
osl::Directory aDir( rDir );
@@ -81,16 +220,37 @@ void PPDParser::scanPPDDir( const String& rDir )
osl::FileStatus aStatus( FileStatusMask_FileName );
if( aItem.getFileStatus( aStatus ) == osl::FileBase::E_None )
{
- INetURLObject aPPDFile = aPPDDir;
- aPPDFile.Append( aStatus.getFileName() );
- String aExt = aPPDFile.getExtension();
- // match extension
- for( int nSuffix = 0; nSuffix < nSuffixes; nSuffix++ )
+ rtl::OUStringBuffer aURLBuf( rDir.Len() + 64 );
+ aURLBuf.append( rDir );
+ aURLBuf.append( sal_Unicode( '/' ) );
+ aURLBuf.append( aStatus.getFileName() );
+
+ rtl::OUString aFileURL, aFileName;
+ osl::FileStatus::Type eType = osl::FileStatus::Unknown;
+
+ if( resolveLink( aURLBuf.makeStringAndClear(), aFileURL, aFileName, eType ) == osl::FileBase::E_None )
{
- if( aExt.EqualsIgnoreCaseAscii( pSuffixes[nSuffix] ) )
+ if( eType == osl::FileStatus::Regular )
{
- (*pAllPPDFiles)[ aPPDFile.getBase() ] = aPPDFile.PathToFileName();
- break;
+ INetURLObject aPPDFile = aPPDDir;
+ aPPDFile.Append( aFileName );
+
+ // match extension
+ for( int nSuffix = 0; nSuffix < nSuffixes; nSuffix++ )
+ {
+ if( aFileName.getLength() > pSuffixes[nSuffix].nSuffixLen )
+ {
+ if( aFileName.endsWithIgnoreAsciiCaseAsciiL( pSuffixes[nSuffix].pSuffix, pSuffixes[nSuffix].nSuffixLen ) )
+ {
+ (*pAllPPDFiles)[ aFileName.copy( 0, aFileName.getLength() - pSuffixes[nSuffix].nSuffixLen ) ] = aPPDFile.PathToFileName();
+ break;
+ }
+ }
+ }
+ }
+ else if( eType == osl::FileStatus::Directory )
+ {
+ scanPPDDir( aFileURL );
}
}
}
@@ -132,34 +292,55 @@ void PPDParser::initPPDFiles()
}
}
+void PPDParser::getKnownPPDDrivers( std::list< rtl::OUString >& o_rDrivers )
+{
+ initPPDFiles();
+ o_rDrivers.clear();
+
+ std::hash_map< OUString, OUString, OUStringHash >::const_iterator it;
+ for( it = pAllPPDFiles->begin(); it != pAllPPDFiles->end(); ++it )
+ o_rDrivers.push_back( it->first );
+}
+
String PPDParser::getPPDFile( const String& rFile )
{
INetURLObject aPPD( rFile, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
// someone might enter a full qualified name here
- SvFileStream aStream( aPPD.PathToFileName(), STREAM_READ );
+ PPDDecompressStream aStream( aPPD.PathToFileName() );
if( ! aStream.IsOpen() )
{
- initPPDFiles();
- // some PPD files contain dots beside the extension, so try name first,
- // base after that
- std::hash_map< OUString, OUString, OUStringHash >::const_iterator it =
- pAllPPDFiles->find( aPPD.getName() );
- if( it == pAllPPDFiles->end() )
- it = pAllPPDFiles->find( aPPD.getBase() );
- if( it == pAllPPDFiles->end() )
+ std::hash_map< OUString, OUString, OUStringHash >::const_iterator it;
+
+ bool bRetry = true;
+ do
{
- // a new file ? rehash
- delete pAllPPDFiles; pAllPPDFiles = NULL;
initPPDFiles();
- // aPPD is already the file name minus the extension
- it = pAllPPDFiles->find( aPPD.getName() );
- if( it == pAllPPDFiles->end() )
- it = pAllPPDFiles->find( aPPD.getBase() );
- // note this is optimized for office start where
- // no new files occur and initPPDFiles is called only once
- }
+ // some PPD files contain dots beside the extension, so try name first
+ // and cut of points after that
+ rtl::OUString aBase( rFile );
+ sal_Int32 nLastIndex = aBase.lastIndexOf( sal_Unicode( '/' ) );
+ if( nLastIndex >= 0 )
+ aBase = aBase.copy( nLastIndex+1 );
+ do
+ {
+ it = pAllPPDFiles->find( aBase );
+ nLastIndex = aBase.lastIndexOf( sal_Unicode( '.' ) );
+ if( nLastIndex > 0 )
+ aBase = aBase.copy( 0, nLastIndex );
+ } while( it == pAllPPDFiles->end() && nLastIndex > 0 );
+
+ if( it == pAllPPDFiles->end() && bRetry )
+ {
+ // a new file ? rehash
+ delete pAllPPDFiles; pAllPPDFiles = NULL;
+ bRetry = false;
+ // note this is optimized for office start where
+ // no new files occur and initPPDFiles is called only once
+ }
+ } while( ! pAllPPDFiles );
+
if( it != pAllPPDFiles->end() )
- aStream.Open( it->second, STREAM_READ );
+ aStream.Open( it->second );
}
String aRet;
@@ -190,7 +371,7 @@ String PPDParser::getPPDPrinterName( const String& rFile )
String aName;
// read in the file
- SvFileStream aStream( aPath, STREAM_READ );
+ PPDDecompressStream aStream( aPath );
if( aStream.IsOpen() )
{
String aCurLine;
@@ -211,7 +392,7 @@ String PPDParser::getPPDPrinterName( const String& rFile )
aCurLine.EraseLeadingChars( '"' );
aCurLine.EraseTrailingChars( '"' );
aStream.Close();
- aStream.Open( getPPDFile( aCurLine ), STREAM_READ );
+ aStream.Open( getPPDFile( aCurLine ) );
continue;
}
if( aCurLine.CompareToAscii( "*ModelName:", 11 ) == COMPARE_EQUAL )
@@ -297,7 +478,7 @@ PPDParser::PPDParser( const String& rFile ) :
{
// read in the file
std::list< ByteString > aLines;
- SvFileStream aStream( m_aFile, STREAM_READ );
+ PPDDecompressStream aStream( m_aFile );
bool bLanguageEncoding = false;
if( aStream.IsOpen() )
{
@@ -319,7 +500,7 @@ PPDParser::PPDParser( const String& rFile ) :
aCurLine.EraseLeadingChars( '"' );
aCurLine.EraseTrailingChars( '"' );
aStream.Close();
- aStream.Open( getPPDFile( String( aCurLine, m_aFileEncoding ) ), STREAM_READ );
+ aStream.Open( getPPDFile( String( aCurLine, m_aFileEncoding ) ) );
continue;
}
else if( ! bLanguageEncoding &&