LCOV - code coverage report
Current view: top level - vcl/unx/generic/printer - ppdparser.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 658 996 66.1 %
Date: 2012-08-25 Functions: 54 72 75.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 767 2045 37.5 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <stdlib.h>
      31                 :            : #include <stdio.h>
      32                 :            : 
      33                 :            : #include <boost/unordered_map.hpp>
      34                 :            : 
      35                 :            : #include <comphelper/string.hxx>
      36                 :            : #include "vcl/ppdparser.hxx"
      37                 :            : #include "vcl/strhelper.hxx"
      38                 :            : #include "vcl/helper.hxx"
      39                 :            : #include "vcl/svapp.hxx"
      40                 :            : #include "cupsmgr.hxx"
      41                 :            : #include "tools/urlobj.hxx"
      42                 :            : #include "tools/stream.hxx"
      43                 :            : #include "tools/zcodec.hxx"
      44                 :            : #include "osl/mutex.hxx"
      45                 :            : #include "osl/file.hxx"
      46                 :            : #include "osl/process.h"
      47                 :            : #include "osl/thread.h"
      48                 :            : #include "rtl/strbuf.hxx"
      49                 :            : #include "rtl/ustrbuf.hxx"
      50                 :            : #include "rtl/instance.hxx"
      51                 :            : #include <sal/macros.h>
      52                 :            : #include <salhelper/linkhelper.hxx>
      53                 :            : 
      54                 :            : #include "com/sun/star/lang/Locale.hpp"
      55                 :            : 
      56                 :            : namespace psp
      57                 :            : {
      58                 :            :     class PPDTranslator
      59                 :            :     {
      60                 :            :         struct LocaleEqual
      61                 :            :         {
      62                 :          0 :             bool operator()(const com::sun::star::lang::Locale& i_rLeft,
      63                 :            :                             const com::sun::star::lang::Locale& i_rRight) const
      64                 :            :             {
      65                 :          0 :                 return i_rLeft.Language.equals( i_rRight.Language ) &&
      66                 :          0 :                 i_rLeft.Country.equals( i_rRight.Country ) &&
      67         [ #  # ]:          0 :                 i_rLeft.Variant.equals( i_rRight.Variant );
           [ #  #  #  # ]
      68                 :            :             }
      69                 :            :         };
      70                 :            : 
      71                 :            :         struct LocaleHash
      72                 :            :         {
      73                 :       8040 :             size_t operator()(const com::sun::star::lang::Locale& rLocale) const
      74                 :            :             { return
      75                 :       8040 :                   (size_t)rLocale.Language.hashCode()
      76                 :       8040 :                 ^ (size_t)rLocale.Country.hashCode()
      77                 :       8040 :                 ^ (size_t)rLocale.Variant.hashCode()
      78                 :            :                 ;
      79                 :            :             }
      80                 :            :         };
      81                 :            : 
      82                 :            :         typedef boost::unordered_map< com::sun::star::lang::Locale, rtl::OUString, LocaleHash, LocaleEqual > translation_map;
      83                 :            :         typedef boost::unordered_map< rtl::OUString, translation_map, rtl::OUStringHash > key_translation_map;
      84                 :            : 
      85                 :            :         key_translation_map     m_aTranslations;
      86                 :            :         public:
      87         [ +  - ]:         60 :         PPDTranslator() {}
      88                 :         60 :         ~PPDTranslator() {}
      89                 :            : 
      90                 :            : 
      91                 :            :         void insertValue(
      92                 :            :             const rtl::OUString& i_rKey,
      93                 :            :             const rtl::OUString& i_rOption,
      94                 :            :             const rtl::OUString& i_rValue,
      95                 :            :             const rtl::OUString& i_rTranslation,
      96                 :            :             const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale()
      97                 :            :             );
      98                 :            : 
      99                 :       7860 :         void insertOption( const rtl::OUString& i_rKey,
     100                 :            :                            const rtl::OUString& i_rOption,
     101                 :            :                            const rtl::OUString& i_rTranslation,
     102                 :            :                            const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() )
     103                 :            :         {
     104         [ +  - ]:       7860 :             insertValue( i_rKey, i_rOption, rtl::OUString(), i_rTranslation, i_rLocale );
     105                 :       7860 :         }
     106                 :            : 
     107                 :        240 :         void insertKey( const rtl::OUString& i_rKey,
     108                 :            :                         const rtl::OUString& i_rTranslation,
     109                 :            :                         const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() )
     110                 :            :         {
     111         [ +  - ]:        240 :             insertValue( i_rKey, rtl::OUString(), rtl::OUString(), i_rTranslation, i_rLocale );
     112                 :        240 :         }
     113                 :            : 
     114                 :            :         rtl::OUString translateValue(
     115                 :            :             const rtl::OUString& i_rKey,
     116                 :            :             const rtl::OUString& i_rOption,
     117                 :            :             const rtl::OUString& i_rValue,
     118                 :            :             const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale()
     119                 :            :             ) const;
     120                 :            : 
     121                 :          0 :         rtl::OUString translateOption( const rtl::OUString& i_rKey,
     122                 :            :                                        const rtl::OUString& i_rOption,
     123                 :            :                                        const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() ) const
     124                 :            :         {
     125         [ #  # ]:          0 :             return translateValue( i_rKey, i_rOption, rtl::OUString(), i_rLocale );
     126                 :            :         }
     127                 :            : 
     128                 :          0 :         rtl::OUString translateKey( const rtl::OUString& i_rKey,
     129                 :            :                                     const com::sun::star::lang::Locale& i_rLocale = com::sun::star::lang::Locale() ) const
     130                 :            :         {
     131         [ #  # ]:          0 :             return translateValue( i_rKey, rtl::OUString(), rtl::OUString(), i_rLocale );
     132                 :            :         }
     133                 :            :     };
     134                 :            : 
     135                 :          0 :     static com::sun::star::lang::Locale normalizeInputLocale(
     136                 :            :         const com::sun::star::lang::Locale& i_rLocale,
     137                 :            :         bool bInsertDefault = false
     138                 :            :         )
     139                 :            :     {
     140                 :          0 :         com::sun::star::lang::Locale aLoc( i_rLocale );
     141 [ #  # ][ #  # ]:          0 :         if( bInsertDefault && aLoc.Language.isEmpty() )
                 [ #  # ]
     142                 :            :         {
     143                 :            :             // empty locale requested, fill in application UI locale
     144 [ #  # ][ #  # ]:          0 :             aLoc = Application::GetSettings().GetUILocale();
     145                 :            : 
     146                 :            :             #if OSL_DEBUG_LEVEL > 1
     147                 :            :             static const char* pEnvLocale = getenv( "SAL_PPDPARSER_LOCALE" );
     148                 :            :             if( pEnvLocale && *pEnvLocale )
     149                 :            :             {
     150                 :            :                 rtl::OString aStr( pEnvLocale );
     151                 :            :                 sal_Int32 nLen = aStr.getLength();
     152                 :            :                 aLoc.Language = rtl::OStringToOUString( aStr.copy( 0, nLen > 2 ? 2 : nLen ), RTL_TEXTENCODING_MS_1252 );
     153                 :            :                 if( nLen >=5 && aStr.getStr()[2] == '_' )
     154                 :            :                     aLoc.Country = rtl::OStringToOUString( aStr.copy( 3, 2 ), RTL_TEXTENCODING_MS_1252 );
     155                 :            :                 else
     156                 :            :                     aLoc.Country = rtl::OUString();
     157                 :            :                 aLoc.Variant = rtl::OUString();
     158                 :            :             }
     159                 :            :             #endif
     160                 :            :         }
     161                 :          0 :         aLoc.Language = aLoc.Language.toAsciiLowerCase();
     162                 :          0 :         aLoc.Country  = aLoc.Country.toAsciiUpperCase();
     163                 :          0 :         aLoc.Variant  = aLoc.Variant.toAsciiUpperCase();
     164                 :            : 
     165                 :          0 :         return aLoc;
     166                 :            :     }
     167                 :            : 
     168                 :       8160 :     void PPDTranslator::insertValue(
     169                 :            :         const rtl::OUString& i_rKey,
     170                 :            :         const rtl::OUString& i_rOption,
     171                 :            :         const rtl::OUString& i_rValue,
     172                 :            :         const rtl::OUString& i_rTranslation,
     173                 :            :         const com::sun::star::lang::Locale& i_rLocale
     174                 :            :         )
     175                 :            :     {
     176                 :       8160 :         rtl::OUStringBuffer aKey( i_rKey.getLength() + i_rOption.getLength() + i_rValue.getLength() + 2 );
     177         [ +  - ]:       8160 :         aKey.append( i_rKey );
     178 [ +  + ][ +  + ]:       8160 :         if( !i_rOption.isEmpty() || !i_rValue.isEmpty() )
                 [ +  + ]
     179                 :            :         {
     180         [ +  - ]:       7920 :             aKey.append( sal_Unicode( ':' ) );
     181         [ +  - ]:       7920 :             aKey.append( i_rOption );
     182                 :            :         }
     183         [ +  + ]:       8160 :         if( !i_rValue.isEmpty() )
     184                 :            :         {
     185         [ +  - ]:         60 :             aKey.append( sal_Unicode( ':' ) );
     186         [ +  - ]:         60 :             aKey.append( i_rValue );
     187                 :            :         }
     188 [ +  - ][ +  + ]:       8160 :         if( aKey.getLength() && !i_rTranslation.isEmpty() )
                 [ +  + ]
     189                 :            :         {
     190         [ +  - ]:       8040 :             rtl::OUString aK( aKey.makeStringAndClear() );
     191                 :       8040 :             com::sun::star::lang::Locale aLoc;
     192                 :       8040 :             aLoc.Language = i_rLocale.Language.toAsciiLowerCase();
     193                 :       8040 :             aLoc.Country  = i_rLocale.Country.toAsciiUpperCase();
     194                 :       8040 :             aLoc.Variant  = i_rLocale.Variant.toAsciiUpperCase();
     195 [ +  - ][ +  - ]:       8040 :             m_aTranslations[ aK ][ aLoc ] = i_rTranslation;
     196                 :       8160 :         }
     197                 :       8160 :     }
     198                 :            : 
     199                 :          0 :     rtl::OUString PPDTranslator::translateValue(
     200                 :            :         const rtl::OUString& i_rKey,
     201                 :            :         const rtl::OUString& i_rOption,
     202                 :            :         const rtl::OUString& i_rValue,
     203                 :            :         const com::sun::star::lang::Locale& i_rLocale
     204                 :            :         ) const
     205                 :            :     {
     206                 :          0 :         rtl::OUString aResult;
     207                 :            : 
     208                 :          0 :         rtl::OUStringBuffer aKey( i_rKey.getLength() + i_rOption.getLength() + i_rValue.getLength() + 2 );
     209         [ #  # ]:          0 :         aKey.append( i_rKey );
     210 [ #  # ][ #  # ]:          0 :         if( !i_rOption.isEmpty() || !i_rValue.isEmpty() )
                 [ #  # ]
     211                 :            :         {
     212         [ #  # ]:          0 :             aKey.append( sal_Unicode( ':' ) );
     213         [ #  # ]:          0 :             aKey.append( i_rOption );
     214                 :            :         }
     215         [ #  # ]:          0 :         if( !i_rValue.isEmpty() )
     216                 :            :         {
     217         [ #  # ]:          0 :             aKey.append( sal_Unicode( ':' ) );
     218         [ #  # ]:          0 :             aKey.append( i_rValue );
     219                 :            :         }
     220         [ #  # ]:          0 :         if( aKey.getLength() )
     221                 :            :         {
     222         [ #  # ]:          0 :             rtl::OUString aK( aKey.makeStringAndClear() );
     223         [ #  # ]:          0 :             key_translation_map::const_iterator it = m_aTranslations.find( aK );
     224 [ #  # ][ #  # ]:          0 :             if( it != m_aTranslations.end() )
     225                 :            :             {
     226         [ #  # ]:          0 :                 const translation_map& rMap( it->second );
     227                 :            : 
     228         [ #  # ]:          0 :                 com::sun::star::lang::Locale aLoc( normalizeInputLocale( i_rLocale, true ) );
     229         [ #  # ]:          0 :                 for( int nTry = 0; nTry < 4; nTry++ )
     230                 :            :                 {
     231         [ #  # ]:          0 :                     translation_map::const_iterator tr = rMap.find( aLoc );
     232 [ #  # ][ #  # ]:          0 :                     if( tr != rMap.end() )
     233                 :            :                     {
     234         [ #  # ]:          0 :                         aResult = tr->second;
     235                 :            :                         break;
     236                 :            :                     }
     237   [ #  #  #  # ]:          0 :                     switch( nTry )
     238                 :            :                     {
     239                 :          0 :                     case 0: aLoc.Variant  = rtl::OUString();break;
     240                 :          0 :                     case 1: aLoc.Country  = rtl::OUString();break;
     241                 :          0 :                     case 2: aLoc.Language = rtl::OUString();break;
     242                 :            :                     }
     243                 :          0 :                 }
     244                 :          0 :             }
     245                 :            :         }
     246                 :          0 :         return aResult;
     247                 :            :     }
     248                 :            : 
     249                 :            :     class PPDCache
     250                 :            :     {
     251                 :            :     public:
     252                 :            :         std::list< PPDParser* > aAllParsers;
     253                 :            :         boost::unordered_map< rtl::OUString, rtl::OUString, rtl::OUStringHash >* pAllPPDFiles;
     254                 :         80 :         PPDCache()
     255                 :         80 :             : pAllPPDFiles(NULL)
     256                 :         80 :         {}
     257                 :         80 :         ~PPDCache()
     258                 :         80 :         {
     259 [ +  - ][ +  + ]:        140 :             while( aAllParsers.begin() != aAllParsers.end() )
     260                 :            :             {
     261 [ +  - ][ +  - ]:         60 :                 delete aAllParsers.front();
                 [ +  - ]
     262         [ +  - ]:         60 :                 aAllParsers.pop_front();
     263                 :            :             }
     264 [ +  - ][ +  - ]:         80 :             delete pAllPPDFiles;
     265                 :         80 :             pAllPPDFiles = NULL;
     266                 :         80 :         }
     267                 :            :     };
     268                 :            : }
     269                 :            : 
     270                 :            : using namespace psp;
     271                 :            : 
     272                 :            : using ::rtl::OUString;
     273                 :            : using ::rtl::OStringBuffer;
     274                 :            : using ::rtl::OUStringHash;
     275                 :            : 
     276                 :            : #define BSTRING(x) rtl::OUStringToOString( x, osl_getThreadTextEncoding() )
     277                 :            : 
     278                 :            : namespace
     279                 :            : {
     280                 :            :     struct thePPDCache : public rtl::Static<PPDCache, thePPDCache> {};
     281                 :            : }
     282                 :            : 
     283                 :            : class PPDDecompressStream
     284                 :            : {
     285                 :            :     SvFileStream*       mpFileStream;
     286                 :            :     SvMemoryStream*     mpMemStream;
     287                 :            :     rtl::OUString       maFileName;
     288                 :            : 
     289                 :            :     // forbid copying
     290                 :            :     PPDDecompressStream( const PPDDecompressStream& );
     291                 :            :     PPDDecompressStream& operator=(const PPDDecompressStream& );
     292                 :            : 
     293                 :            :     public:
     294                 :            :     PPDDecompressStream( const rtl::OUString& rFile );
     295                 :            :     ~PPDDecompressStream();
     296                 :            : 
     297                 :            :     bool IsOpen() const;
     298                 :            :     bool IsEof() const;
     299                 :            :     rtl::OString ReadLine();
     300                 :            :     void Open( const rtl::OUString& i_rFile );
     301                 :            :     void Close();
     302                 :        259 :     const rtl::OUString& GetFileName() const { return maFileName; }
     303                 :            : };
     304                 :            : 
     305                 :        359 : PPDDecompressStream::PPDDecompressStream( const rtl::OUString& i_rFile ) :
     306                 :            :     mpFileStream( NULL ),
     307                 :        359 :     mpMemStream( NULL )
     308                 :            : {
     309         [ +  - ]:        359 :     Open( i_rFile );
     310                 :        359 : }
     311                 :            : 
     312                 :        359 : PPDDecompressStream::~PPDDecompressStream()
     313                 :            : {
     314         [ +  - ]:        359 :     Close();
     315                 :        359 : }
     316                 :            : 
     317                 :        618 : void PPDDecompressStream::Open( const rtl::OUString& i_rFile )
     318                 :            : {
     319         [ +  - ]:        618 :     Close();
     320                 :            : 
     321 [ +  - ][ +  - ]:        618 :     mpFileStream = new SvFileStream( i_rFile, STREAM_READ );
         [ +  - ][ +  - ]
     322         [ +  - ]:        618 :     maFileName = mpFileStream->GetFileName();
     323                 :            : 
     324         [ +  + ]:        618 :     if( ! mpFileStream->IsOpen() )
     325                 :            :     {
     326         [ +  - ]:        299 :         Close();
     327                 :        618 :         return;
     328                 :            :     }
     329                 :            : 
     330                 :        319 :     rtl::OString aLine;
     331         [ +  - ]:        319 :     mpFileStream->ReadLine( aLine );
     332         [ +  - ]:        319 :     mpFileStream->Seek( 0 );
     333                 :            : 
     334                 :            :     // check for compress'ed or gzip'ed file
     335                 :        319 :     sal_uLong nCompressMethod = 0;
     336 [ +  - ][ -  + ]:        319 :     if( aLine.getLength() > 1 && static_cast<unsigned char>(aLine[0]) == 0x1f )
                 [ -  + ]
     337                 :            :     {
     338         [ #  # ]:          0 :         if( static_cast<unsigned char>(aLine[1]) == 0x8b ) // check for gzip
     339                 :          0 :             nCompressMethod = ZCODEC_DEFAULT | ZCODEC_GZ_LIB;
     340                 :            :     }
     341                 :            : 
     342         [ -  + ]:        319 :     if( nCompressMethod != 0 )
     343                 :            :     {
     344                 :            :         // so let's try to decompress the stream
     345 [ #  # ][ #  # ]:          0 :         mpMemStream = new SvMemoryStream( 4096, 4096 );
     346         [ #  # ]:          0 :         ZCodec aCodec;
     347         [ #  # ]:          0 :         aCodec.BeginCompression( nCompressMethod );
     348         [ #  # ]:          0 :         long nComp = aCodec.Decompress( *mpFileStream, *mpMemStream );
     349         [ #  # ]:          0 :         aCodec.EndCompression();
     350         [ #  # ]:          0 :         if( nComp < 0 )
     351                 :            :         {
     352                 :            :             // decompression failed, must be an uncompressed stream after all
     353 [ #  # ][ #  # ]:          0 :             delete mpMemStream, mpMemStream = NULL;
     354         [ #  # ]:          0 :             mpFileStream->Seek( 0 );
     355                 :            :         }
     356                 :            :         else
     357                 :            :         {
     358                 :            :             // compression successfull, can get rid of file stream
     359 [ #  # ][ #  # ]:          0 :             delete mpFileStream, mpFileStream = NULL;
     360         [ #  # ]:          0 :             mpMemStream->Seek( 0 );
     361         [ #  # ]:          0 :         }
     362                 :        618 :     }
     363                 :            : }
     364                 :            : 
     365                 :       1336 : void PPDDecompressStream::Close()
     366                 :            : {
     367         [ -  + ]:       1336 :     delete mpMemStream, mpMemStream = NULL;
     368         [ +  + ]:       1336 :     delete mpFileStream, mpFileStream = NULL;
     369                 :       1336 : }
     370                 :            : 
     371                 :        658 : bool PPDDecompressStream::IsOpen() const
     372                 :            : {
     373 [ +  - ][ +  + ]:        658 :     return (mpMemStream || (mpFileStream && mpFileStream->IsOpen()));
                 [ +  - ]
     374                 :            : }
     375                 :            : 
     376                 :      34980 : bool PPDDecompressStream::IsEof() const
     377                 :            : {
     378 [ -  + ][ +  - ]:      34980 :     return ( mpMemStream ? mpMemStream->IsEof() : ( mpFileStream ? mpFileStream->IsEof() : true ) );
                 [ +  + ]
     379                 :            : }
     380                 :            : 
     381                 :      35179 : rtl::OString PPDDecompressStream::ReadLine()
     382                 :            : {
     383                 :      35179 :     rtl::OString o_rLine;
     384         [ -  + ]:      35179 :     if( mpMemStream )
     385         [ #  # ]:          0 :         mpMemStream->ReadLine( o_rLine );
     386         [ +  - ]:      35179 :     else if( mpFileStream )
     387         [ +  - ]:      35179 :         mpFileStream->ReadLine( o_rLine );
     388                 :      35179 :     return o_rLine;
     389                 :            : }
     390                 :            : 
     391                 :        240 : 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 )
     392                 :            : {
     393                 :            :     salhelper::LinkResolver aResolver(osl_FileStatus_Mask_FileName |
     394                 :            :                                       osl_FileStatus_Mask_Type |
     395                 :        240 :                                       osl_FileStatus_Mask_FileURL);
     396                 :            : 
     397         [ +  - ]:        240 :     osl::FileBase::RC aRet = aResolver.fetchFileStatus(i_rURL, nLinkLevel);
     398                 :            : 
     399         [ +  - ]:        240 :     if (aRet  == osl::FileBase::E_None)
     400                 :            :     {
     401         [ +  - ]:        240 :         o_rResolvedURL = aResolver.m_aStatus.getFileURL();
     402         [ +  - ]:        240 :         o_rBaseName = aResolver.m_aStatus.getFileName();
     403         [ +  - ]:        240 :         o_rType = aResolver.m_aStatus.getFileType();
     404                 :            :     }
     405                 :            : 
     406                 :        240 :     return aRet;
     407                 :            : }
     408                 :            : 
     409                 :        240 : void PPDParser::scanPPDDir( const String& rDir )
     410                 :            : {
     411                 :            :     static struct suffix_t
     412                 :            :     {
     413                 :            :         const sal_Char* pSuffix;
     414                 :            :         const sal_Int32 nSuffixLen;
     415                 :            :     } const pSuffixes[] =
     416                 :            :     { { ".PS", 3 },  { ".PPD", 4 }, { ".PS.GZ", 6 }, { ".PPD.GZ", 7 } };
     417                 :            : 
     418                 :        240 :     const int nSuffixes = SAL_N_ELEMENTS(pSuffixes);
     419                 :            : 
     420         [ +  - ]:        240 :     PPDCache &rPPDCache = thePPDCache::get();
     421                 :            : 
     422         [ +  - ]:        240 :     osl::Directory aDir( rDir );
     423 [ +  - ][ +  - ]:        240 :     if ( aDir.open() == osl::FileBase::E_None )
     424                 :            :     {
     425                 :        240 :         osl::DirectoryItem aItem;
     426                 :            : 
     427 [ +  - ][ +  - ]:        240 :         INetURLObject aPPDDir(rDir);
     428 [ +  - ][ +  + ]:        480 :         while( aDir.getNextItem( aItem ) == osl::FileBase::E_None )
     429                 :            :         {
     430                 :        240 :             osl::FileStatus aStatus( osl_FileStatus_Mask_FileName );
     431 [ +  - ][ +  - ]:        240 :             if( aItem.getFileStatus( aStatus ) == osl::FileBase::E_None )
     432                 :            :             {
     433                 :        240 :                 rtl::OUStringBuffer aURLBuf( rDir.Len() + 64 );
     434 [ +  - ][ +  - ]:        240 :                 aURLBuf.append( rDir );
     435         [ +  - ]:        240 :                 aURLBuf.append( sal_Unicode( '/' ) );
     436 [ +  - ][ +  - ]:        240 :                 aURLBuf.append( aStatus.getFileName() );
     437                 :            : 
     438                 :        240 :                 rtl::OUString aFileURL, aFileName;
     439                 :        240 :                 osl::FileStatus::Type eType = osl::FileStatus::Unknown;
     440                 :            : 
     441 [ +  - ][ +  - ]:        240 :                 if( resolveLink( aURLBuf.makeStringAndClear(), aFileURL, aFileName, eType ) == osl::FileBase::E_None )
                 [ +  - ]
     442                 :            :                 {
     443         [ +  - ]:        240 :                     if( eType == osl::FileStatus::Regular )
     444                 :            :                     {
     445         [ +  - ]:        240 :                         INetURLObject aPPDFile = aPPDDir;
     446         [ +  - ]:        240 :                         aPPDFile.Append( aFileName );
     447                 :            : 
     448                 :            :                         // match extension
     449         [ +  + ]:        720 :                         for( int nSuffix = 0; nSuffix < nSuffixes; nSuffix++ )
     450                 :            :                         {
     451         [ +  - ]:        600 :                             if( aFileName.getLength() > pSuffixes[nSuffix].nSuffixLen )
     452                 :            :                             {
     453         [ +  + ]:        600 :                                 if( aFileName.endsWithIgnoreAsciiCaseAsciiL( pSuffixes[nSuffix].pSuffix, pSuffixes[nSuffix].nSuffixLen ) )
     454                 :            :                                 {
     455 [ +  - ][ +  - ]:        120 :                                 (*rPPDCache.pAllPPDFiles)[ aFileName.copy( 0, aFileName.getLength() - pSuffixes[nSuffix].nSuffixLen ) ] = aPPDFile.PathToFileName();
     456                 :        120 :                                     break;
     457                 :            :                                 }
     458                 :            :                             }
     459         [ +  - ]:        240 :                         }
     460                 :            :                     }
     461         [ #  # ]:          0 :                     else if( eType == osl::FileStatus::Directory )
     462                 :            :                     {
     463 [ #  # ][ #  # ]:          0 :                         scanPPDDir( aFileURL );
                 [ #  # ]
     464                 :            :                     }
     465                 :        240 :                 }
     466                 :            :             }
     467                 :        240 :         }
     468 [ +  - ][ +  - ]:        240 :         aDir.close();
                 [ +  - ]
     469         [ +  - ]:        240 :     }
     470                 :        240 : }
     471                 :            : 
     472                 :        339 : void PPDParser::initPPDFiles()
     473                 :            : {
     474         [ +  - ]:        339 :     PPDCache &rPPDCache = thePPDCache::get();
     475         [ +  + ]:        339 :     if( rPPDCache.pAllPPDFiles )
     476                 :        339 :         return;
     477                 :            : 
     478 [ +  - ][ +  - ]:        120 :     rPPDCache.pAllPPDFiles = new boost::unordered_map< OUString, OUString, OUStringHash >();
     479                 :            : 
     480                 :            :     // check installation directories
     481         [ +  - ]:        120 :     std::list< OUString > aPathList;
     482         [ +  - ]:        120 :     psp::getPrinterPathList( aPathList, PRINTER_PPDDIR );
     483         [ +  + ]:        300 :     for( std::list< OUString >::const_iterator ppd_it = aPathList.begin(); ppd_it != aPathList.end(); ++ppd_it )
     484                 :            :     {
     485         [ +  - ]:        180 :         INetURLObject aPPDDir( *ppd_it, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
     486 [ +  - ][ +  - ]:        180 :         scanPPDDir( aPPDDir.GetMainURL( INetURLObject::NO_DECODE ) );
         [ +  - ][ +  - ]
     487         [ +  - ]:        180 :     }
     488 [ +  - ][ +  - ]:        120 :     if( rPPDCache.pAllPPDFiles->find( OUString( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) ) == rPPDCache.pAllPPDFiles->end() )
         [ +  - ][ +  + ]
     489                 :            :     {
     490                 :            :         // last try: search in directory of executable (mainly for setup)
     491                 :         60 :         OUString aExe;
     492 [ +  - ][ +  - ]:         60 :         if( osl_getExecutableFile( &aExe.pData ) == osl_Process_E_None )
     493                 :            :         {
     494         [ +  - ]:         60 :             INetURLObject aDir( aExe );
     495         [ +  - ]:         60 :             aDir.removeSegment();
     496                 :            : #ifdef DEBUG
     497                 :            :             fprintf( stderr, "scanning last chance dir: %s\n", rtl::OUStringToOString( aDir.GetMainURL( INetURLObject::NO_DECODE ), osl_getThreadTextEncoding() ).getStr() );
     498                 :            : #endif
     499 [ +  - ][ +  - ]:         60 :             scanPPDDir( aDir.GetMainURL( INetURLObject::NO_DECODE ) );
         [ +  - ][ +  - ]
                 [ +  - ]
     500                 :            : #ifdef DEBUG
     501                 :            :             fprintf( stderr, "SGENPRT %s\n", rPPDCache.pAllPPDFiles->find( OUString( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) ) == rPPDCache.pAllPPDFiles->end() ? "not found" : "found" );
     502                 :            : #endif
     503                 :         60 :         }
     504                 :        339 :     }
     505                 :            : }
     506                 :            : 
     507                 :          0 : void PPDParser::getKnownPPDDrivers( std::list< rtl::OUString >& o_rDrivers, bool bRefresh )
     508                 :            : {
     509         [ #  # ]:          0 :     PPDCache &rPPDCache = thePPDCache::get();
     510                 :            : 
     511         [ #  # ]:          0 :     if( bRefresh )
     512                 :            :     {
     513 [ #  # ][ #  # ]:          0 :         delete rPPDCache.pAllPPDFiles;
     514                 :          0 :         rPPDCache.pAllPPDFiles = NULL;
     515                 :            :     }
     516                 :            : 
     517         [ #  # ]:          0 :     initPPDFiles();
     518                 :          0 :     o_rDrivers.clear();
     519                 :            : 
     520                 :          0 :     boost::unordered_map< OUString, OUString, OUStringHash >::const_iterator it;
     521 [ #  # ][ #  # ]:          0 :     for( it = rPPDCache.pAllPPDFiles->begin(); it != rPPDCache.pAllPPDFiles->end(); ++it )
                 [ #  # ]
     522 [ #  # ][ #  # ]:          0 :         o_rDrivers.push_back( it->first );
     523                 :          0 : }
     524                 :            : 
     525                 :        299 : String PPDParser::getPPDFile( const String& rFile )
     526                 :            : {
     527 [ +  - ][ +  - ]:        299 :     INetURLObject aPPD( rFile, INET_PROT_FILE, INetURLObject::ENCODE_ALL );
     528                 :            :     // someone might enter a full qualified name here
     529 [ +  - ][ +  - ]:        299 :     PPDDecompressStream aStream( aPPD.PathToFileName() );
     530         [ +  - ]:        299 :     if( ! aStream.IsOpen() )
     531                 :            :     {
     532                 :        299 :         boost::unordered_map< OUString, OUString, OUStringHash >::const_iterator it;
     533         [ +  - ]:        299 :         PPDCache &rPPDCache = thePPDCache::get();
     534                 :            : 
     535                 :        299 :         bool bRetry = true;
     536         [ +  + ]:        339 :         do
     537                 :            :         {
     538         [ +  - ]:        339 :             initPPDFiles();
     539                 :            :             // some PPD files contain dots beside the extension, so try name first
     540                 :            :             // and cut of points after that
     541         [ +  - ]:        339 :             rtl::OUString aBase( rFile );
     542                 :        339 :             sal_Int32 nLastIndex = aBase.lastIndexOf( sal_Unicode( '/' ) );
     543         [ -  + ]:        339 :             if( nLastIndex >= 0 )
     544                 :          0 :                 aBase = aBase.copy( nLastIndex+1 );
     545 [ -  + ][ -  + ]:        678 :             do
                 [ +  + ]
     546                 :            :             {
     547         [ +  - ]:        339 :                 it = rPPDCache.pAllPPDFiles->find( aBase );
     548                 :        339 :                 nLastIndex = aBase.lastIndexOf( sal_Unicode( '.' ) );
     549         [ -  + ]:        339 :                 if( nLastIndex > 0 )
     550                 :          0 :                     aBase = aBase.copy( 0, nLastIndex );
     551 [ +  - ][ +  - ]:        678 :             } while( it == rPPDCache.pAllPPDFiles->end() && nLastIndex > 0 );
                 [ +  - ]
           [ #  #  #  # ]
     552                 :            : 
     553 [ +  - ][ +  + ]:        339 :             if( it == rPPDCache.pAllPPDFiles->end() && bRetry )
         [ +  + ][ +  - ]
         [ +  - ][ +  +  
             #  #  #  # ]
     554                 :            :             {
     555                 :            :                 // a new file ? rehash
     556 [ +  - ][ +  - ]:         40 :                 delete rPPDCache.pAllPPDFiles; rPPDCache.pAllPPDFiles = NULL;
     557                 :         40 :                 bRetry = false;
     558                 :            :                 // note this is optimized for office start where
     559                 :            :                 // no new files occur and initPPDFiles is called only once
     560                 :        339 :             }
     561                 :        339 :         } while( ! rPPDCache.pAllPPDFiles );
     562                 :            : 
     563 [ +  - ][ +  + ]:        299 :         if( it != rPPDCache.pAllPPDFiles->end() )
     564 [ +  - ][ +  - ]:        299 :             aStream.Open( it->second );
     565                 :            :     }
     566                 :            : 
     567         [ +  - ]:        299 :     String aRet;
     568         [ +  + ]:        299 :     if( aStream.IsOpen() )
     569                 :            :     {
     570         [ +  - ]:        259 :         rtl::OString aLine = aStream.ReadLine();
     571         [ +  - ]:        259 :         if (aLine.indexOfL(RTL_CONSTASCII_STRINGPARAM("*PPD-Adobe")) == 0)
     572         [ +  - ]:        259 :             aRet = aStream.GetFileName();
     573                 :            :         else
     574                 :            :         {
     575                 :            :             // our *Include hack does usually not begin
     576                 :            :             // with *PPD-Adobe, so try some lines for *Include
     577                 :          0 :             int nLines = 10;
     578 [ #  # ][ #  # ]:          0 :             while (aLine.indexOfL(RTL_CONSTASCII_STRINGPARAM("*Include")) != 0 && --nLines)
                 [ #  # ]
     579         [ #  # ]:          0 :                 aLine = aStream.ReadLine();
     580         [ #  # ]:          0 :             if( nLines )
     581         [ #  # ]:          0 :                 aRet = aStream.GetFileName();
     582                 :        259 :         }
     583                 :            :     }
     584                 :            : 
     585 [ +  - ][ +  - ]:        299 :     return aRet;
     586                 :            : }
     587                 :            : 
     588                 :          0 : String PPDParser::getPPDPrinterName( const String& rFile )
     589                 :            : {
     590         [ #  # ]:          0 :     String aPath = getPPDFile( rFile );
     591         [ #  # ]:          0 :     String aName;
     592                 :            : 
     593                 :            :     // read in the file
     594 [ #  # ][ #  # ]:          0 :     PPDDecompressStream aStream( aPath );
     595         [ #  # ]:          0 :     if( aStream.IsOpen() )
     596                 :            :     {
     597         [ #  # ]:          0 :         String aCurLine;
     598 [ #  # ][ #  # ]:          0 :         while( ! aStream.IsEof() && aStream.IsOpen() )
                 [ #  # ]
     599                 :            :         {
     600         [ #  # ]:          0 :             rtl::OString aByteLine = aStream.ReadLine();
     601 [ #  # ][ #  # ]:          0 :             aCurLine = rtl::OStringToOUString(aByteLine, RTL_TEXTENCODING_MS_1252);
     602 [ #  # ][ #  # ]:          0 :             if( aCurLine.CompareIgnoreCaseToAscii( "*include:", 9 ) == COMPARE_EQUAL )
     603                 :            :             {
     604         [ #  # ]:          0 :                 aCurLine.Erase( 0, 9 );
     605 [ #  # ][ #  # ]:          0 :                 aCurLine = comphelper::string::stripStart(aCurLine, ' ');
                 [ #  # ]
     606 [ #  # ][ #  # ]:          0 :                 aCurLine = comphelper::string::stripEnd(aCurLine, ' ');
                 [ #  # ]
     607 [ #  # ][ #  # ]:          0 :                 aCurLine = comphelper::string::stripStart(aCurLine, '\t');
                 [ #  # ]
     608 [ #  # ][ #  # ]:          0 :                 aCurLine = comphelper::string::stripEnd(aCurLine, '\t');
                 [ #  # ]
     609 [ #  # ][ #  # ]:          0 :                 aCurLine = comphelper::string::stripEnd(aCurLine, '\r');
                 [ #  # ]
     610 [ #  # ][ #  # ]:          0 :                 aCurLine = comphelper::string::stripEnd(aCurLine, '\n');
                 [ #  # ]
     611 [ #  # ][ #  # ]:          0 :                 aCurLine = comphelper::string::stripStart(aCurLine, '"');
                 [ #  # ]
     612 [ #  # ][ #  # ]:          0 :                 aCurLine = comphelper::string::stripEnd(aCurLine, '"');
                 [ #  # ]
     613         [ #  # ]:          0 :                 aStream.Close();
     614 [ #  # ][ #  # ]:          0 :                 aStream.Open( getPPDFile( aCurLine ) );
         [ #  # ][ #  # ]
     615                 :          0 :                 continue;
     616                 :            :             }
     617 [ #  # ][ #  # ]:          0 :             if( aCurLine.CompareToAscii( "*ModelName:", 11 ) == COMPARE_EQUAL )
     618                 :            :             {
     619 [ #  # ][ #  # ]:          0 :                 aName = aCurLine.GetToken( 1, '"' );
                 [ #  # ]
     620                 :            :                 break;
     621                 :            :             }
     622 [ #  # ][ #  # ]:          0 :             else if( aCurLine.CompareToAscii( "*NickName:", 10 ) == COMPARE_EQUAL )
     623 [ #  # ][ #  # ]:          0 :                 aName = aCurLine.GetToken( 1, '"' );
                 [ #  # ]
     624      [ #  #  # ]:          0 :         }
                 [ #  # ]
     625                 :            :     }
     626 [ #  # ][ #  # ]:          0 :     return aName;
     627                 :            : }
     628                 :            : 
     629                 :        299 : const PPDParser* PPDParser::getParser( const String& rFile )
     630                 :            : {
     631 [ +  + ][ +  - ]:        299 :     static ::osl::Mutex aMutex;
         [ +  - ][ #  # ]
     632         [ +  - ]:        299 :     ::osl::Guard< ::osl::Mutex > aGuard( aMutex );
     633                 :            : 
     634         [ +  - ]:        299 :     String aFile = rFile;
     635 [ +  - ][ +  - ]:        299 :     if( rFile.CompareToAscii( "CUPS:", 5 ) != COMPARE_EQUAL )
     636 [ +  - ][ +  - ]:        299 :         aFile = getPPDFile( rFile );
                 [ +  - ]
     637         [ +  + ]:        299 :     if( ! aFile.Len() )
     638                 :            :     {
     639                 :            : #if OSL_DEBUG_LEVEL > 1
     640                 :            :         fprintf( stderr, "Could not get printer PPD file \"%s\" !\n", ::rtl::OUStringToOString( rFile, osl_getThreadTextEncoding() ).getStr() );
     641                 :            : #endif
     642                 :         40 :         return NULL;
     643                 :            :     }
     644                 :            : 
     645         [ +  - ]:        259 :     PPDCache &rPPDCache = thePPDCache::get();
     646 [ +  - ][ #  # ]:        259 :     for( ::std::list< PPDParser* >::const_iterator it = rPPDCache.aAllParsers.begin(); it != rPPDCache.aAllParsers.end(); ++it )
         [ +  - ][ +  - ]
                 [ +  + ]
     647 [ +  - ][ +  - ]:        199 :         if( (*it)->m_aFile == aFile )
                 [ +  - ]
     648         [ +  - ]:        199 :             return *it;
     649                 :            : 
     650                 :         60 :     PPDParser* pNewParser = NULL;
     651 [ +  - ][ +  - ]:         60 :     if( aFile.CompareToAscii( "CUPS:", 5 ) != COMPARE_EQUAL )
     652 [ +  - ][ +  - ]:         60 :         pNewParser = new PPDParser( aFile );
     653                 :            :     else
     654                 :            :     {
     655         [ #  # ]:          0 :         PrinterInfoManager& rMgr = PrinterInfoManager::get();
     656         [ #  # ]:          0 :         if( rMgr.getType() == PrinterInfoManager::CUPS )
     657                 :            :         {
     658                 :            : #ifdef ENABLE_CUPS
     659 [ #  # ][ #  # ]:          0 :             pNewParser = const_cast<PPDParser*>(static_cast<CUPSManager&>(rMgr).createCUPSParser( aFile ));
     660                 :            : #endif
     661                 :            :         }
     662                 :            :     }
     663         [ +  - ]:         60 :     if( pNewParser )
     664                 :            :     {
     665                 :            :         // this may actually be the SGENPRT parser,
     666                 :            :         // so ensure uniquness here
     667         [ +  - ]:         60 :         rPPDCache.aAllParsers.remove( pNewParser );
     668                 :            :         // insert new parser to list
     669         [ +  - ]:         60 :         rPPDCache.aAllParsers.push_front( pNewParser );
     670                 :            :     }
     671 [ +  - ][ +  - ]:        299 :     return pNewParser;
     672                 :            : }
     673                 :            : 
     674                 :         60 : PPDParser::PPDParser( const String& rFile ) :
     675                 :            :         m_aFile( rFile ),
     676                 :            :         m_bType42Capable( false ),
     677                 :            :         m_aFileEncoding( RTL_TEXTENCODING_MS_1252 ),
     678                 :            :         m_pDefaultImageableArea( NULL ),
     679                 :            :         m_pImageableAreas( NULL ),
     680                 :            :         m_pDefaultPaperDimension( NULL ),
     681                 :            :         m_pPaperDimensions( NULL ),
     682                 :            :         m_pDefaultInputSlot( NULL ),
     683                 :            :         m_pInputSlots( NULL ),
     684                 :            :         m_pDefaultResolution( NULL ),
     685                 :            :         m_pResolutions( NULL ),
     686                 :            :         m_pDefaultDuplexType( NULL ),
     687                 :            :         m_pDuplexTypes( NULL ),
     688                 :            :         m_pFontList( NULL ),
     689 [ +  - ][ +  - ]:         60 :         m_pTranslator( new PPDTranslator() )
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     690                 :            : {
     691                 :            :     // read in the file
     692         [ +  - ]:         60 :     std::list< rtl::OString > aLines;
     693 [ +  - ][ +  - ]:         60 :     PPDDecompressStream aStream( m_aFile );
     694                 :         60 :     bool bLanguageEncoding = false;
     695         [ +  - ]:         60 :     if( aStream.IsOpen() )
     696                 :            :     {
     697         [ +  + ]:      34980 :         while( ! aStream.IsEof() )
     698                 :            :         {
     699         [ +  - ]:      34920 :             rtl::OString aCurLine = aStream.ReadLine();
     700         [ +  + ]:      34920 :             if( aCurLine[0] == '*' )
     701                 :            :             {
     702         [ -  + ]:      25560 :                 if (aCurLine.matchIgnoreAsciiCase(rtl::OString("*include:")))
     703                 :            :                 {
     704                 :          0 :                     aCurLine = aCurLine.copy(9);
     705         [ #  # ]:          0 :                     aCurLine = comphelper::string::stripStart(aCurLine, ' ');
     706         [ #  # ]:          0 :                     aCurLine = comphelper::string::stripEnd(aCurLine, ' ');
     707         [ #  # ]:          0 :                     aCurLine = comphelper::string::stripStart(aCurLine, '\t');
     708         [ #  # ]:          0 :                     aCurLine = comphelper::string::stripEnd(aCurLine, '\t');
     709         [ #  # ]:          0 :                     aCurLine = comphelper::string::stripEnd(aCurLine, '\r');
     710         [ #  # ]:          0 :                     aCurLine = comphelper::string::stripEnd(aCurLine, '\n');
     711         [ #  # ]:          0 :                     aCurLine = comphelper::string::stripStart(aCurLine, '"');
     712         [ #  # ]:          0 :                     aCurLine = comphelper::string::stripEnd(aCurLine, '"');
     713         [ #  # ]:          0 :                     aStream.Close();
     714 [ #  # ][ #  # ]:          0 :                     aStream.Open(getPPDFile(rtl::OStringToOUString(aCurLine, m_aFileEncoding)));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     715                 :          0 :                     continue;
     716                 :            :                 }
     717   [ +  +  +  + ]:      52800 :                 else if( ! bLanguageEncoding &&
                 [ +  + ]
     718 [ +  + ][ +  + ]:      27240 :                          aCurLine.matchIgnoreAsciiCase(rtl::OString("*languageencoding")) )
     719                 :            :                 {
     720                 :         60 :                     bLanguageEncoding = true; // generally only the first one counts
     721                 :         60 :                     rtl::OString aLower = aCurLine.toAsciiLowerCase();
     722         [ +  - ]:         60 :                     if( aLower.indexOfL(RTL_CONSTASCII_STRINGPARAM("isolatin1"), 17 ) != -1 ||
           [ -  +  #  # ]
     723                 :          0 :                         aLower.indexOfL(RTL_CONSTASCII_STRINGPARAM("windowsansi"), 17 ) != -1 )
     724                 :         60 :                         m_aFileEncoding = RTL_TEXTENCODING_MS_1252;
     725         [ #  # ]:          0 :                     else if( aLower.indexOfL(RTL_CONSTASCII_STRINGPARAM("isolatin2"), 17 ) != -1 )
     726                 :          0 :                         m_aFileEncoding = RTL_TEXTENCODING_ISO_8859_2;
     727         [ #  # ]:          0 :                     else if( aLower.indexOfL(RTL_CONSTASCII_STRINGPARAM("isolatin5"), 17 ) != -1 )
     728                 :          0 :                         m_aFileEncoding = RTL_TEXTENCODING_ISO_8859_5;
     729         [ #  # ]:          0 :                     else if( aLower.indexOfL(RTL_CONSTASCII_STRINGPARAM("jis83-rksj"), 17 ) != -1 )
     730                 :          0 :                         m_aFileEncoding = RTL_TEXTENCODING_SHIFT_JIS;
     731         [ #  # ]:          0 :                     else if( aLower.indexOfL(RTL_CONSTASCII_STRINGPARAM("macstandard"), 17 ) != -1 )
     732                 :          0 :                         m_aFileEncoding = RTL_TEXTENCODING_APPLE_ROMAN;
     733         [ #  # ]:          0 :                     else if( aLower.indexOfL(RTL_CONSTASCII_STRINGPARAM("utf-8"), 17 ) != -1 )
     734                 :         60 :                         m_aFileEncoding = RTL_TEXTENCODING_UTF8;
     735                 :            :                 }
     736                 :            :             }
     737 [ +  - ][ +  - ]:      69840 :             aLines.push_back( aCurLine );
     738                 :      34920 :         }
     739                 :            :     }
     740         [ +  - ]:         60 :     aStream.Close();
     741                 :            : 
     742                 :            :     // now get the Values
     743         [ +  - ]:         60 :     parse( aLines );
     744                 :            : #if OSL_DEBUG_LEVEL > 2
     745                 :            :     fprintf( stderr, "acquired %d Keys from PPD %s:\n", m_aKeys.size(), BSTRING( m_aFile ).getStr() );
     746                 :            :     for( PPDParser::hash_type::const_iterator it = m_aKeys.begin(); it != m_aKeys.end(); ++it )
     747                 :            :     {
     748                 :            :         const PPDKey* pKey = it->second;
     749                 :            :         char* pSetupType = "<unknown>";
     750                 :            :         switch( pKey->m_eSetupType )
     751                 :            :         {
     752                 :            :             case PPDKey::ExitServer:        pSetupType = "ExitServer";break;
     753                 :            :             case PPDKey::Prolog:            pSetupType = "Prolog";break;
     754                 :            :             case PPDKey::DocumentSetup: pSetupType = "DocumentSetup";break;
     755                 :            :             case PPDKey::PageSetup:     pSetupType = "PageSetup";break;
     756                 :            :             case PPDKey::JCLSetup:          pSetupType = "JCLSetup";break;
     757                 :            :             case PPDKey::AnySetup:          pSetupType = "AnySetup";break;
     758                 :            :             default: break;
     759                 :            :         };
     760                 :            :         fprintf( stderr, "\t\"%s\" (%d values) OrderDependency: %d %s\n",
     761                 :            :                  BSTRING( pKey->getKey() ).getStr(),
     762                 :            :                  pKey->countValues(),
     763                 :            :                  pKey->m_nOrderDependency,
     764                 :            :                  pSetupType );
     765                 :            :         for( int j = 0; j < pKey->countValues(); j++ )
     766                 :            :         {
     767                 :            :             fprintf( stderr, "\t\t" );
     768                 :            :             const PPDValue* pValue = pKey->getValue( j );
     769                 :            :             if( pValue == pKey->m_pDefaultValue )
     770                 :            :                 fprintf( stderr, "(Default:) " );
     771                 :            :             char* pVType = "<unknown>";
     772                 :            :             switch( pValue->m_eType )
     773                 :            :             {
     774                 :            :                 case eInvocation:       pVType = "invocation";break;
     775                 :            :                 case eQuoted:           pVType = "quoted";break;
     776                 :            :                 case eString:           pVType = "string";break;
     777                 :            :                 case eSymbol:           pVType = "symbol";break;
     778                 :            :                 case eNo:               pVType = "no";break;
     779                 :            :                 default: break;
     780                 :            :             };
     781                 :            :             fprintf( stderr, "option: \"%s\", value: type %s \"%s\"\n",
     782                 :            :                      BSTRING( pValue->m_aOption ).getStr(),
     783                 :            :                      pVType,
     784                 :            :                      BSTRING( pValue->m_aValue ).getStr() );
     785                 :            :         }
     786                 :            :     }
     787                 :            :     fprintf( stderr, "constraints: (%d found)\n", m_aConstraints.size() );
     788                 :            :     for( std::list< PPDConstraint >::const_iterator cit = m_aConstraints.begin(); cit != m_aConstraints.end(); ++cit )
     789                 :            :     {
     790                 :            :         fprintf( stderr, "*\"%s\" \"%s\" *\"%s\" \"%s\"\n",
     791                 :            :                  BSTRING( cit->m_pKey1->getKey() ).getStr(),
     792                 :            :                  cit->m_pOption1 ? BSTRING( cit->m_pOption1->m_aOption ).getStr() : "<nil>",
     793                 :            :                  BSTRING( cit->m_pKey2->getKey() ).getStr(),
     794                 :            :                  cit->m_pOption2 ? BSTRING( cit->m_pOption2->m_aOption ).getStr() : "<nil>"
     795                 :            :                  );
     796                 :            :     }
     797                 :            : #endif
     798                 :            : 
     799                 :            :     // fill in shortcuts
     800                 :            :     const PPDKey* pKey;
     801                 :            : 
     802 [ +  - ][ +  - ]:         60 :     m_pImageableAreas = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "ImageableArea" ) ) );
                 [ +  - ]
     803         [ +  - ]:         60 :     if( m_pImageableAreas )
     804                 :         60 :         m_pDefaultImageableArea = m_pImageableAreas->getDefaultValue();
     805                 :         60 :     if (m_pImageableAreas == 0) {
     806                 :            :         OSL_TRACE(
     807                 :            :             OSL_LOG_PREFIX "Warning: no ImageableArea in %s\n",
     808                 :            :             rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr());
     809                 :            :     }
     810                 :         60 :     if (m_pDefaultImageableArea == 0) {
     811                 :            :         OSL_TRACE(
     812                 :            :             OSL_LOG_PREFIX "Warning: no DefaultImageableArea in %s\n",
     813                 :            :             rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr());
     814                 :            :     }
     815                 :            : 
     816 [ +  - ][ +  - ]:         60 :     m_pPaperDimensions = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PaperDimension" ) ) );
                 [ +  - ]
     817         [ +  - ]:         60 :     if( m_pPaperDimensions )
     818                 :         60 :         m_pDefaultPaperDimension = m_pPaperDimensions->getDefaultValue();
     819                 :         60 :     if (m_pPaperDimensions == 0) {
     820                 :            :         OSL_TRACE(
     821                 :            :             OSL_LOG_PREFIX "Warning: no PaperDimensions in %s\n",
     822                 :            :             rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr());
     823                 :            :     }
     824                 :         60 :     if (m_pDefaultPaperDimension == 0) {
     825                 :            :         OSL_TRACE(
     826                 :            :             OSL_LOG_PREFIX "Warning: no DefaultPaperDimensions in %s\n",
     827                 :            :             rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr());
     828                 :            :     }
     829                 :            : 
     830 [ +  - ][ +  - ]:         60 :     m_pResolutions = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ) );
                 [ +  - ]
     831         [ +  - ]:         60 :     if( m_pResolutions )
     832                 :         60 :         m_pDefaultResolution = m_pResolutions->getDefaultValue();
     833                 :         60 :     if (m_pResolutions == 0) {
     834                 :            :         OSL_TRACE(
     835                 :            :             OSL_LOG_PREFIX "Warning: no Resolution in %s\n",
     836                 :            :             rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr());
     837                 :            :     }
     838                 :         60 :     if (m_pDefaultResolution == 0) {
     839                 :            :         OSL_TRACE(
     840                 :            :             OSL_LOG_PREFIX "Warning: no DefaultResolution in %s\n",
     841                 :            :             rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr());
     842                 :            :     }
     843                 :            : 
     844 [ +  - ][ +  - ]:         60 :     m_pInputSlots = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) );
                 [ +  - ]
     845         [ -  + ]:         60 :     if( m_pInputSlots )
     846                 :          0 :         m_pDefaultInputSlot = m_pInputSlots->getDefaultValue();
     847                 :         60 :     if (m_pInputSlots == 0) {
     848                 :            :         OSL_TRACE(
     849                 :            :             OSL_LOG_PREFIX "Warning: no InputSlot in %s\n",
     850                 :            :             rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr());
     851                 :            :     }
     852                 :         60 :     if (m_pDefaultInputSlot == 0) {
     853                 :            :         OSL_TRACE(
     854                 :            :             OSL_LOG_PREFIX "Warning: no DefaultInputSlot in %s\n",
     855                 :            :             rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr());
     856                 :            :     }
     857                 :            : 
     858 [ +  - ][ +  - ]:         60 :     m_pDuplexTypes = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Duplex" ) ) );
                 [ +  - ]
     859         [ +  - ]:         60 :     if( m_pDuplexTypes )
     860                 :         60 :         m_pDefaultDuplexType = m_pDuplexTypes->getDefaultValue();
     861                 :            : 
     862 [ +  - ][ +  - ]:         60 :     m_pFontList = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Font" ) ) );
                 [ +  - ]
     863                 :         60 :     if (m_pFontList == 0) {
     864                 :            :         OSL_TRACE(
     865                 :            :             OSL_LOG_PREFIX "Warning: no Font in %s\n",
     866                 :            :             rtl::OUStringToOString(m_aFile, RTL_TEXTENCODING_UTF8).getStr());
     867                 :            :     }
     868                 :            : 
     869                 :            :     // fill in direct values
     870 [ +  - ][ +  - ]:         60 :     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "ModelName" ) ) )) )
         [ +  - ][ +  - ]
     871 [ +  - ][ +  - ]:         60 :         m_aPrinterName = pKey->getValue( 0 )->m_aValue;
     872 [ +  - ][ +  - ]:         60 :     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "NickName" ) ) )) )
         [ +  - ][ +  - ]
     873 [ +  - ][ +  - ]:         60 :         m_aNickName = pKey->getValue( 0 )->m_aValue;
     874 [ +  - ][ +  - ]:         60 :     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "ColorDevice" ) ) )) )
         [ +  - ][ +  - ]
     875 [ +  - ][ +  - ]:         60 :         m_bColorDevice = pKey->getValue( 0 )->m_aValue.CompareIgnoreCaseToAscii( "true", 4 ) == COMPARE_EQUAL ? true : false;
     876                 :            : 
     877 [ +  - ][ +  - ]:         60 :     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "LanguageLevel" ) ) )) )
         [ +  - ][ +  - ]
     878 [ +  - ][ +  - ]:         60 :         m_nLanguageLevel = pKey->getValue( 0 )->m_aValue.ToInt32();
     879 [ +  - ][ +  - ]:         60 :     if( (pKey = getKey( String( RTL_CONSTASCII_USTRINGPARAM( "TTRasterizer" ) ) )) )
         [ +  - ][ -  + ]
     880 [ #  # ][ #  # ]:         60 :         m_bType42Capable = pKey->getValue( 0 )->m_aValue.EqualsIgnoreCaseAscii( "Type42" ) ? true : false;
                 [ +  - ]
     881                 :         60 : }
     882                 :            : 
     883 [ +  - ][ +  - ]:         60 : PPDParser::~PPDParser()
                 [ +  - ]
     884                 :            : {
     885 [ +  - ][ +  - ]:       2760 :     for( PPDParser::hash_type::iterator it = m_aKeys.begin(); it != m_aKeys.end(); ++it )
                 [ +  + ]
     886 [ +  - ][ +  - ]:       2700 :         delete it->second;
                 [ +  - ]
     887 [ +  - ][ +  - ]:         60 :     delete m_pTranslator;
     888                 :         60 : }
     889                 :            : 
     890                 :       2700 : void PPDParser::insertKey( const String& rKey, PPDKey* pKey )
     891                 :            : {
     892         [ +  - ]:       2700 :     m_aKeys[ rKey ] = pKey;
     893                 :       2700 :     m_aOrderedKeys.push_back( pKey );
     894                 :       2700 : }
     895                 :            : 
     896                 :          0 : const PPDKey* PPDParser::getKey( int n ) const
     897                 :            : {
     898 [ #  # ][ #  # ]:          0 :     return ((unsigned int)n < m_aOrderedKeys.size() && n >= 0) ? m_aOrderedKeys[n] : NULL;
     899                 :            : }
     900                 :            : 
     901                 :       1787 : const PPDKey* PPDParser::getKey( const String& rKey ) const
     902                 :            : {
     903 [ +  - ][ +  - ]:       1787 :     PPDParser::hash_type::const_iterator it = m_aKeys.find( rKey );
     904 [ +  + ][ +  - ]:       1787 :     return it != m_aKeys.end() ? it->second : NULL;
                 [ +  - ]
     905                 :            : }
     906                 :            : 
     907                 :        592 : bool PPDParser::hasKey( const PPDKey* pKey ) const
     908                 :            : {
     909                 :            :     return
     910                 :            :         pKey ?
     911 [ +  - ][ +  - ]:       1184 :         ( m_aKeys.find( pKey->getKey() ) != m_aKeys.end() ? true : false ) :
                 [ #  # ]
     912 [ +  - ][ +  - ]:       1776 :         false;
         [ +  - ][ +  - ]
                 [ +  - ]
           [ #  #  #  # ]
     913                 :            : }
     914                 :            : 
     915                 :          0 : static sal_uInt8 getNibble( sal_Char cChar )
     916                 :            : {
     917                 :          0 :     sal_uInt8 nRet = 0;
     918 [ #  # ][ #  # ]:          0 :     if( cChar >= '0' && cChar <= '9' )
     919                 :          0 :         nRet = sal_uInt8( cChar - '0' );
     920 [ #  # ][ #  # ]:          0 :     else if( cChar >= 'A' && cChar <= 'F' )
     921                 :          0 :         nRet = 10 + sal_uInt8( cChar - 'A' );
     922 [ #  # ][ #  # ]:          0 :     else if( cChar >= 'a' && cChar <= 'f' )
     923                 :          0 :         nRet = 10 + sal_uInt8( cChar - 'a' );
     924                 :          0 :     return nRet;
     925                 :            : }
     926                 :            : 
     927                 :       8280 : String PPDParser::handleTranslation(const rtl::OString& i_rString, bool bIsGlobalized)
     928                 :            : {
     929                 :       8280 :     sal_Int32 nOrigLen = i_rString.getLength();
     930                 :       8280 :     OStringBuffer aTrans( nOrigLen );
     931                 :       8280 :     const sal_Char* pStr = i_rString.getStr();
     932                 :       8280 :     const sal_Char* pEnd = pStr + nOrigLen;
     933         [ +  + ]:     124260 :     while( pStr < pEnd )
     934                 :            :     {
     935         [ -  + ]:     115980 :         if( *pStr == '<' )
     936                 :            :         {
     937                 :          0 :             pStr++;
     938                 :            :             sal_Char cChar;
     939 [ #  # ][ #  # ]:          0 :             while( *pStr != '>' && pStr < pEnd-1 )
                 [ #  # ]
     940                 :            :             {
     941                 :          0 :                 cChar = getNibble( *pStr++ ) << 4;
     942                 :          0 :                 cChar |= getNibble( *pStr++ );
     943         [ #  # ]:          0 :                 aTrans.append( cChar );
     944                 :            :             }
     945                 :          0 :             pStr++;
     946                 :            :         }
     947                 :            :         else
     948         [ +  - ]:     115980 :             aTrans.append( *pStr++ );
     949                 :            :     }
     950 [ -  + ][ +  - ]:       8280 :     return OStringToOUString( aTrans.makeStringAndClear(), bIsGlobalized ? RTL_TEXTENCODING_UTF8 : m_aFileEncoding );
                 [ +  - ]
     951                 :            : }
     952                 :            : 
     953                 :            : namespace
     954                 :            : {
     955                 :      27120 :     bool oddDoubleQuoteCount(rtl::OStringBuffer &rBuffer)
     956                 :            :     {
     957                 :      27120 :         bool bHasOddCount = false;
     958         [ +  + ]:    2608260 :         for (sal_Int32 i = 0; i < rBuffer.getLength(); ++i)
     959                 :            :         {
     960         [ +  + ]:    2581140 :             if (rBuffer[i] == '"')
     961                 :      46320 :                 bHasOddCount = !bHasOddCount;
     962                 :            :         }
     963                 :      27120 :         return bHasOddCount;
     964                 :            :     }
     965                 :            : }
     966                 :            : 
     967                 :         60 : void PPDParser::parse( ::std::list< rtl::OString >& rLines )
     968                 :            : {
     969                 :         60 :     std::list< rtl::OString >::iterator line = rLines.begin();
     970                 :         60 :     PPDParser::hash_type::const_iterator keyit;
     971         [ +  + ]:      28380 :     while( line != rLines.end() )
     972                 :            :     {
     973                 :      28320 :         rtl::OString aCurrentLine( *line );
     974                 :      28320 :         ++line;
     975         [ +  + ]:      28320 :         if( aCurrentLine[0] != '*' )
     976                 :       2760 :             continue;
     977         [ +  + ]:      25560 :         if( aCurrentLine[1] == '%' )
     978                 :       3000 :             continue;
     979                 :            : 
     980         [ +  - ]:      22560 :         rtl::OString aKey = GetCommandLineToken( 0, comphelper::string::getToken(aCurrentLine, 0, ':') );
     981                 :      22560 :         sal_Int32 nPos = aKey.indexOf('/');
     982         [ -  + ]:      22560 :         if (nPos != -1)
     983                 :          0 :             aKey = aKey.copy(0, nPos);
     984                 :      22560 :         aKey = aKey.copy(1); // remove the '*'
     985                 :            : 
     986 [ +  + ][ +  +  :     133080 :         if (aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("CloseUI")) ||
          +  -  +  -  +  
             +  +  -  -  
                      + ]
     987                 :      22320 :             aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("OpenGroup")) ||
     988                 :      22320 :             aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("CloseGroup")) ||
     989                 :      22320 :             aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("End")) ||
     990                 :      21780 :             aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("OpenSubGroup")) ||
     991                 :      21780 :             aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("CloseSubGroup")))
     992                 :            :         {
     993                 :        780 :             continue;
     994                 :            :         }
     995                 :            : 
     996         [ +  + ]:      21780 :         if (aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("OpenUI")))
     997                 :            :         {
     998         [ +  - ]:        240 :             parseOpenUI( aCurrentLine );
     999                 :        240 :             continue;
    1000                 :            :         }
    1001         [ +  + ]:      21540 :         else if (aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("OrderDependency")))
    1002                 :            :         {
    1003         [ +  - ]:        240 :             parseOrderDependency( aCurrentLine );
    1004                 :        240 :             continue;
    1005                 :            :         }
    1006   [ +  -  -  + ]:      42600 :         else if (aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("UIConstraints")) ||
                 [ -  + ]
    1007                 :      21300 :                  aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("NonUIConstraints")))
    1008                 :            :         {
    1009                 :          0 :             continue; // parsed in pass 2
    1010                 :            :         }
    1011         [ -  + ]:      21300 :         else if( aKey.equalsL(RTL_CONSTASCII_STRINGPARAM("CustomPageSize")) ) // currently not handled
    1012                 :          0 :             continue;
    1013                 :            : 
    1014                 :            :         // default values are parsed in pass 2
    1015         [ +  + ]:      21300 :         if (aKey.matchL(RTL_CONSTASCII_STRINGPARAM("Default")))
    1016                 :        780 :             continue;
    1017                 :            : 
    1018                 :      20520 :         bool bQuery     = false;
    1019         [ +  + ]:      20520 :         if (aKey[0] == '?')
    1020                 :            :         {
    1021                 :        180 :             aKey = aKey.copy(1);
    1022                 :        180 :             bQuery = true;
    1023                 :            :         }
    1024                 :            : 
    1025 [ +  - ][ +  - ]:      20520 :         String aUniKey(rtl::OStringToOUString(aKey, RTL_TEXTENCODING_MS_1252));
    1026                 :            :         // handle CUPS extension for globalized PPDs
    1027                 :      20520 :         bool bIsGlobalizedLine = false;
    1028                 :      20520 :         com::sun::star::lang::Locale aTransLocale;
    1029   [ +  -  +  +  :      59400 :         if( ( aUniKey.Len() > 3 && aUniKey.GetChar( 2 ) == '.' ) ||
             -  +  #  # ]
         [ -  + ][ +  - ]
    1030                 :      38880 :             ( aUniKey.Len() > 5 && aUniKey.GetChar( 2 ) == '_' && aUniKey.GetChar( 5 ) == '.' ) )
    1031                 :            :         {
    1032         [ #  # ]:          0 :             if( aUniKey.GetChar( 2 ) == '.' )
    1033                 :            :             {
    1034 [ #  # ][ #  # ]:          0 :                 aTransLocale.Language = aUniKey.Copy( 0, 2 );
                 [ #  # ]
    1035 [ #  # ][ #  # ]:          0 :                 aUniKey = aUniKey.Copy( 3 );
                 [ #  # ]
    1036                 :            :             }
    1037                 :            :             else
    1038                 :            :             {
    1039 [ #  # ][ #  # ]:          0 :                 aTransLocale.Language = aUniKey.Copy( 0, 2 );
                 [ #  # ]
    1040 [ #  # ][ #  # ]:          0 :                 aTransLocale.Country = aUniKey.Copy( 3, 2 );
                 [ #  # ]
    1041 [ #  # ][ #  # ]:          0 :                 aUniKey = aUniKey.Copy( 6 );
                 [ #  # ]
    1042                 :            :             }
    1043                 :          0 :             bIsGlobalizedLine = true;
    1044                 :            :         }
    1045                 :            : 
    1046         [ +  - ]:      20520 :         String aOption;
    1047                 :      20520 :         nPos = aCurrentLine.indexOf(':');
    1048         [ +  - ]:      20520 :         if( nPos != -1 )
    1049                 :            :         {
    1050 [ +  - ][ +  - ]:      20520 :             aOption = rtl::OStringToOUString( aCurrentLine.copy( 1, nPos-1 ), RTL_TEXTENCODING_MS_1252 );
    1051 [ +  - ][ +  - ]:      20520 :             aOption = GetCommandLineToken( 1, aOption );
                 [ +  - ]
    1052         [ +  - ]:      20520 :             int nTransPos = aOption.Search( '/' );
    1053         [ +  + ]:      20520 :             if( nTransPos != STRING_NOTFOUND )
    1054         [ +  - ]:       7860 :                 aOption.Erase( nTransPos );
    1055                 :            :         }
    1056                 :            : 
    1057                 :      20520 :         PPDValueType eType = eNo;
    1058         [ +  - ]:      20520 :         String aValue;
    1059                 :      20520 :         rtl::OUString aOptionTranslation;
    1060                 :      20520 :         rtl::OUString aValueTranslation;
    1061         [ +  - ]:      20520 :         if( nPos != STRING_NOTFOUND )
    1062                 :            :         {
    1063                 :            :             // found a colon, there may be an option
    1064                 :      20520 :             rtl::OString aLine = aCurrentLine.copy( 1, nPos-1 );
    1065         [ +  - ]:      20520 :             aLine = WhitespaceToSpace( aLine );
    1066                 :      20520 :             sal_Int32 nTransPos = aLine.indexOf('/');
    1067         [ +  + ]:      20520 :             if (nTransPos != -1)
    1068 [ +  - ][ +  - ]:       7860 :                 aOptionTranslation = handleTranslation( aLine.copy(nTransPos+1), bIsGlobalizedLine );
                 [ +  - ]
    1069                 :            : 
    1070                 :            :             // read in more lines if necessary for multiline values
    1071                 :      20520 :             aLine = aCurrentLine.copy( nPos+1 );
    1072         [ +  - ]:      20520 :             if (!aLine.isEmpty())
    1073                 :            :             {
    1074         [ +  - ]:      20520 :                 rtl::OStringBuffer aBuffer(aLine);
    1075 [ +  - ][ +  + ]:      27120 :                 while (line != rLines.end() && oddDoubleQuoteCount(aBuffer))
         [ +  - ][ +  + ]
    1076                 :            :                 {
    1077                 :            :                     // copy the newlines also
    1078         [ +  - ]:       6600 :                     aBuffer.append('\n');
    1079         [ +  - ]:       6600 :                     aBuffer.append(*line);
    1080                 :       6600 :                     ++line;
    1081                 :            :                 }
    1082                 :      20520 :                 aLine = aBuffer.makeStringAndClear();
    1083                 :            :             }
    1084         [ +  - ]:      20520 :             aLine = WhitespaceToSpace( aLine );
    1085                 :            : 
    1086                 :            :             // #i100644# handle a missing value (actually a broken PPD)
    1087         [ -  + ]:      20520 :             if( aLine.isEmpty() )
    1088                 :            :             {
    1089 [ #  # ][ #  # ]:          0 :                 if( aOption.Len() &&
                 [ #  # ]
    1090         [ #  # ]:          0 :                     aUniKey.CompareToAscii( "JCL", 3 ) != COMPARE_EQUAL )
    1091                 :          0 :                     eType = eInvocation;
    1092                 :            :                 else
    1093                 :          0 :                     eType = eQuoted;
    1094                 :            :             }
    1095                 :            :             // check for invocation or quoted value
    1096         [ +  + ]:      20520 :             else if(aLine[0] == '"')
    1097                 :            :             {
    1098                 :      17760 :                 aLine = aLine.copy(1);
    1099                 :      17760 :                 nTransPos = aLine.indexOf('"');
    1100         [ -  + ]:      17760 :                 if (nTransPos == -1)
    1101                 :          0 :                     nTransPos = aLine.getLength();
    1102 [ +  - ][ +  - ]:      17760 :                 aValue = rtl::OStringToOUString(aLine.copy(0, nTransPos), RTL_TEXTENCODING_MS_1252);
    1103                 :            :                 // after the second doublequote can follow a / and a translation
    1104         [ -  + ]:      17760 :                 if (nTransPos < aLine.getLength() - 2)
    1105                 :            :                 {
    1106 [ #  # ][ #  # ]:          0 :                     aValueTranslation = handleTranslation( aLine.copy( nTransPos+2 ), bIsGlobalizedLine );
                 [ #  # ]
    1107                 :            :                 }
    1108                 :            :                 // check for quoted value
    1109 [ +  + ][ +  - ]:      32640 :                 if( aOption.Len() &&
                 [ +  + ]
    1110         [ +  - ]:      14880 :                     aUniKey.CompareToAscii( "JCL", 3 ) != COMPARE_EQUAL )
    1111                 :      14880 :                     eType = eInvocation;
    1112                 :            :                 else
    1113                 :       2880 :                     eType = eQuoted;
    1114                 :            :             }
    1115                 :            :             // check for symbol value
    1116         [ -  + ]:       2760 :             else if(aLine[0] == '^')
    1117                 :            :             {
    1118                 :          0 :                 aLine = aLine.copy(1);
    1119 [ #  # ][ #  # ]:          0 :                 aValue = rtl::OStringToOUString(aLine, RTL_TEXTENCODING_MS_1252);
    1120                 :          0 :                 eType = eSymbol;
    1121                 :            :             }
    1122                 :            :             else
    1123                 :            :             {
    1124                 :            :                 // must be a string value then
    1125                 :            :                 // strictly this is false because string values
    1126                 :            :                 // can contain any whitespace which is reduced
    1127                 :            :                 // to one space by now
    1128                 :            :                 // who cares ...
    1129                 :       2760 :                 nTransPos = aLine.indexOf('/');
    1130         [ +  + ]:       2760 :                 if (nTransPos == -1)
    1131                 :       2460 :                     nTransPos = aLine.getLength();
    1132 [ +  - ][ +  - ]:       2760 :                 aValue = rtl::OStringToOUString(aLine.copy(0, nTransPos), RTL_TEXTENCODING_MS_1252);
    1133         [ +  + ]:       2760 :                 if (nTransPos+1 < aLine.getLength())
    1134 [ +  - ][ +  - ]:        300 :                     aValueTranslation = handleTranslation( aLine.copy( nTransPos+1 ), bIsGlobalizedLine );
                 [ +  - ]
    1135                 :       2760 :                 eType = eString;
    1136                 :      20520 :             }
    1137                 :            :         }
    1138                 :            : 
    1139                 :            :         // handle globalized PPD entries
    1140         [ -  + ]:      20520 :         if( bIsGlobalizedLine )
    1141                 :            :         {
    1142                 :            :             // handle main key translations of form:
    1143                 :            :             // *ll_CC.Translation MainKeyword/translated text: ""
    1144 [ #  # ][ #  # ]:          0 :             if( aUniKey.EqualsAscii( "Translation" ) )
    1145                 :            :             {
    1146 [ #  # ][ #  # ]:          0 :                 m_pTranslator->insertKey( aOption, aOptionTranslation, aTransLocale );
    1147                 :            :             }
    1148                 :            :             // handle options translations of for:
    1149                 :            :             // *ll_CC.MainKeyword OptionKeyword/translated text: ""
    1150                 :            :             else
    1151                 :            :             {
    1152 [ #  # ][ #  # ]:          0 :                 m_pTranslator->insertOption( aUniKey, aOption, aOptionTranslation, aTransLocale );
                 [ #  # ]
    1153                 :            :             }
    1154                 :          0 :             continue;
    1155                 :            :         }
    1156                 :            : 
    1157                 :      20520 :         PPDKey* pKey = NULL;
    1158 [ +  - ][ +  - ]:      20520 :         keyit = m_aKeys.find( aUniKey );
    1159 [ +  + ][ +  - ]:      20520 :         if( keyit == m_aKeys.end() )
    1160                 :            :         {
    1161 [ +  - ][ +  - ]:       2220 :             pKey = new PPDKey( aUniKey );
    1162         [ +  - ]:       2220 :             insertKey( aUniKey, pKey );
    1163                 :            :         }
    1164                 :            :         else
    1165         [ +  - ]:      18300 :             pKey = keyit->second;
    1166                 :            : 
    1167 [ -  + ][ #  # ]:      20520 :         if( eType == eNo && bQuery )
    1168                 :          0 :             continue;
    1169                 :            : 
    1170         [ +  - ]:      20520 :         PPDValue* pValue = pKey->insertValue( aOption );
    1171         [ +  + ]:      20520 :         if( ! pValue )
    1172                 :       1800 :             continue;
    1173                 :      18720 :         pValue->m_eType = eType;
    1174         [ +  - ]:      18720 :         pValue->m_aValue = aValue;
    1175                 :            : 
    1176         [ +  + ]:      18720 :         if( !aOptionTranslation.isEmpty() )
    1177 [ +  - ][ +  - ]:       7860 :             m_pTranslator->insertOption( aUniKey, aOption, aOptionTranslation, aTransLocale );
                 [ +  - ]
    1178         [ +  + ]:      18720 :         if( !aValueTranslation.isEmpty() )
    1179 [ +  - ][ +  - ]:         60 :             m_pTranslator->insertValue( aUniKey, aOption, aValue, aValueTranslation, aTransLocale );
         [ +  - ][ +  - ]
    1180                 :            : 
    1181                 :            :         // eventually update query and remove from option list
    1182 [ +  + ][ +  - ]:      18720 :         if( bQuery && pKey->m_bQueryValue == sal_False )
    1183                 :            :         {
    1184         [ +  - ]:        180 :             pKey->m_aQueryValue = *pValue;
    1185                 :        180 :             pKey->m_bQueryValue = true;
    1186         [ +  - ]:      18720 :             pKey->eraseValue( pValue->m_aOption );
    1187                 :            :         }
    1188 [ +  + ][ +  + ]:      28320 :     }
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
         [ +  + ][ +  - ]
         [ +  + ][ +  + ]
                 [ +  + ]
    1189                 :            : 
    1190                 :            :     // second pass: fill in defaults
    1191         [ +  + ]:      34980 :     for( line = rLines.begin(); line != rLines.end(); ++line )
    1192                 :            :     {
    1193                 :      34920 :         rtl::OString aLine(*line);
    1194         [ +  + ]:      34920 :         if (aLine.matchL(RTL_CONSTASCII_STRINGPARAM("*Default")))
    1195                 :            :         {
    1196 [ +  - ][ +  - ]:        780 :             String aKey(rtl::OStringToOUString(aLine.copy(8), RTL_TEXTENCODING_MS_1252));
    1197         [ +  - ]:        780 :             sal_uInt16 nPos = aKey.Search( ':' );
    1198         [ +  - ]:        780 :             if( nPos != STRING_NOTFOUND )
    1199                 :            :             {
    1200         [ +  - ]:        780 :                 aKey.Erase( nPos );
    1201                 :            :                 rtl::OUString aOption(rtl::OStringToOUString(
    1202                 :            :                     WhitespaceToSpace(aLine.copy(nPos+9)),
    1203 [ +  - ][ +  - ]:        780 :                     RTL_TEXTENCODING_MS_1252));
    1204 [ +  - ][ +  - ]:        780 :                 keyit = m_aKeys.find( aKey );
    1205 [ +  + ][ +  - ]:        780 :                 if( keyit != m_aKeys.end() )
    1206                 :            :                 {
    1207         [ +  - ]:        540 :                     PPDKey* pKey = keyit->second;
    1208 [ +  - ][ +  - ]:        540 :                     const PPDValue* pDefValue = pKey->getValue( aOption );
                 [ +  - ]
    1209         [ +  - ]:        540 :                     if( pKey->m_pDefaultValue == NULL )
    1210                 :        540 :                         pKey->m_pDefaultValue = pDefValue;
    1211                 :            :                 }
    1212                 :            :                 else
    1213                 :            :                 {
    1214                 :            :                     // some PPDs contain defaults for keys that
    1215                 :            :                     // do not exist otherwise
    1216                 :            :                     // (example: DefaultResolution)
    1217                 :            :                     // so invent that key here and have a default value
    1218 [ +  - ][ +  - ]:        240 :                     PPDKey* pKey = new PPDKey( aKey );
    1219 [ +  - ][ +  - ]:        240 :                     PPDValue* pNewValue = pKey->insertValue( aOption );
                 [ +  - ]
    1220                 :        240 :                     pNewValue->m_eType = eInvocation; // or what ?
    1221         [ +  - ]:        240 :                     insertKey( aKey, pKey );
    1222                 :        780 :                 }
    1223         [ +  - ]:        780 :             }
    1224                 :            :         }
    1225   [ +  -  -  + ]:      68280 :         else if (aLine.matchL(RTL_CONSTASCII_STRINGPARAM("*UIConstraints")) ||
                 [ -  + ]
    1226                 :      34140 :                  aLine.matchL(RTL_CONSTASCII_STRINGPARAM("*NonUIConstraints")))
    1227                 :            :         {
    1228         [ #  # ]:          0 :             parseConstraint( aLine );
    1229                 :            :         }
    1230                 :      34920 :     }
    1231                 :         60 : }
    1232                 :            : 
    1233                 :        240 : void PPDParser::parseOpenUI(const rtl::OString& rLine)
    1234                 :            : {
    1235         [ +  - ]:        240 :     String aTranslation;
    1236                 :        240 :     rtl::OString aKey = rLine;
    1237                 :            : 
    1238                 :        240 :     sal_Int32 nPos = aKey.indexOf(':');
    1239         [ +  - ]:        240 :     if( nPos != -1 )
    1240                 :        240 :         aKey = aKey.copy(0, nPos);
    1241                 :        240 :     nPos = aKey.indexOf('/');
    1242         [ +  + ]:        240 :     if( nPos != -1 )
    1243                 :            :     {
    1244 [ +  - ][ +  - ]:        120 :         aTranslation = handleTranslation( aKey.copy( nPos + 1 ), false );
                 [ +  - ]
    1245                 :        120 :         aKey = aKey.copy(0, nPos);
    1246                 :            :     }
    1247         [ +  - ]:        240 :     aKey = GetCommandLineToken( 1, aKey );
    1248                 :        240 :     aKey = aKey.copy(1);
    1249                 :            : 
    1250 [ +  - ][ +  - ]:        240 :     String aUniKey(rtl::OStringToOUString(aKey, RTL_TEXTENCODING_MS_1252));
    1251 [ +  - ][ +  - ]:        240 :     PPDParser::hash_type::const_iterator keyit = m_aKeys.find( aUniKey );
    1252                 :            :     PPDKey* pKey;
    1253 [ +  - ][ +  - ]:        240 :     if( keyit == m_aKeys.end() )
    1254                 :            :     {
    1255 [ +  - ][ +  - ]:        240 :         pKey = new PPDKey( aUniKey );
    1256         [ +  - ]:        240 :         insertKey( aUniKey, pKey );
    1257                 :            :     }
    1258                 :            :     else
    1259         [ #  # ]:          0 :         pKey = keyit->second;
    1260                 :            : 
    1261                 :        240 :     pKey->m_bUIOption = true;
    1262 [ +  - ][ +  - ]:        240 :     m_pTranslator->insertKey( pKey->getKey(), aTranslation );
                 [ +  - ]
    1263                 :            : 
    1264                 :        240 :     sal_Int32 nIndex = 0;
    1265         [ +  - ]:        240 :     rtl::OString aValue = WhitespaceToSpace( rLine.getToken( 1, ':', nIndex ) );
    1266         [ +  + ]:        240 :     if( aValue.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("boolean")))
    1267                 :         60 :         pKey->m_eUIType = PPDKey::Boolean;
    1268         [ -  + ]:        180 :     else if (aValue.equalsIgnoreAsciiCaseL(RTL_CONSTASCII_STRINGPARAM("pickmany")))
    1269                 :          0 :         pKey->m_eUIType = PPDKey::PickMany;
    1270                 :            :     else
    1271 [ +  - ][ +  - ]:        240 :         pKey->m_eUIType = PPDKey::PickOne;
    1272                 :        240 : }
    1273                 :            : 
    1274                 :        240 : void PPDParser::parseOrderDependency(const rtl::OString& rLine)
    1275                 :            : {
    1276                 :        240 :     rtl::OString aLine(rLine);
    1277                 :        240 :     sal_Int32 nPos = aLine.indexOf(':');
    1278         [ +  - ]:        240 :     if( nPos != -1 )
    1279                 :        240 :         aLine = aLine.copy( nPos+1 );
    1280                 :            : 
    1281         [ +  - ]:        240 :     sal_Int32 nOrder = GetCommandLineToken( 0, aLine ).toInt32();
    1282         [ +  - ]:        240 :     rtl::OString aSetup = GetCommandLineToken( 1, aLine );
    1283 [ +  - ][ +  - ]:        240 :     String aKey(rtl::OStringToOUString(GetCommandLineToken(2, aLine), RTL_TEXTENCODING_MS_1252));
                 [ +  - ]
    1284         [ -  + ]:        240 :     if( aKey.GetChar( 0 ) != '*' )
    1285                 :        240 :         return; // invalid order depency
    1286         [ +  - ]:        240 :     aKey.Erase( 0, 1 );
    1287                 :            : 
    1288                 :            :     PPDKey* pKey;
    1289 [ +  - ][ +  - ]:        240 :     PPDParser::hash_type::const_iterator keyit = m_aKeys.find( aKey );
    1290 [ -  + ][ +  - ]:        240 :     if( keyit == m_aKeys.end() )
    1291                 :            :     {
    1292 [ #  # ][ #  # ]:          0 :         pKey = new PPDKey( aKey );
    1293         [ #  # ]:          0 :         insertKey( aKey, pKey );
    1294                 :            :     }
    1295                 :            :     else
    1296         [ +  - ]:        240 :         pKey = keyit->second;
    1297                 :            : 
    1298                 :        240 :     pKey->m_nOrderDependency = nOrder;
    1299         [ -  + ]:        240 :     if( aSetup.equalsL(RTL_CONSTASCII_STRINGPARAM("ExitServer")) )
    1300                 :          0 :         pKey->m_eSetupType = PPDKey::ExitServer;
    1301         [ -  + ]:        240 :     else if( aSetup.equalsL(RTL_CONSTASCII_STRINGPARAM("Prolog")) )
    1302                 :          0 :         pKey->m_eSetupType = PPDKey::Prolog;
    1303         [ -  + ]:        240 :     else if( aSetup.equalsL(RTL_CONSTASCII_STRINGPARAM("DocumentSetup")) )
    1304                 :          0 :         pKey->m_eSetupType = PPDKey::DocumentSetup;
    1305         [ -  + ]:        240 :     else if( aSetup.equalsL(RTL_CONSTASCII_STRINGPARAM("PageSetup")) )
    1306                 :          0 :         pKey->m_eSetupType = PPDKey::PageSetup;
    1307         [ -  + ]:        240 :     else if( aSetup.equalsL(RTL_CONSTASCII_STRINGPARAM("JCLSetup")) )
    1308                 :          0 :         pKey->m_eSetupType = PPDKey::JCLSetup;
    1309                 :            :     else
    1310 [ +  - ][ -  + ]:        240 :         pKey->m_eSetupType = PPDKey::AnySetup;
         [ -  + ][ +  - ]
    1311                 :            : }
    1312                 :            : 
    1313                 :          0 : void PPDParser::parseConstraint( const rtl::OString& rLine )
    1314                 :            : {
    1315                 :          0 :     bool bFailed = false;
    1316                 :            : 
    1317 [ #  # ][ #  # ]:          0 :     String aLine(rtl::OStringToOUString(rLine, RTL_TEXTENCODING_MS_1252));
    1318         [ #  # ]:          0 :     aLine.Erase(0, rLine.indexOf(':') + 1);
    1319                 :          0 :     PPDConstraint aConstraint;
    1320 [ #  # ][ #  # ]:          0 :     int nTokens = GetCommandLineTokenCount( aLine );
    1321         [ #  # ]:          0 :     for( int i = 0; i < nTokens; i++ )
    1322                 :            :     {
    1323         [ #  # ]:          0 :         String aToken = GetCommandLineToken( i, aLine );
    1324         [ #  # ]:          0 :         if( aToken.GetChar( 0 ) == '*' )
    1325                 :            :         {
    1326         [ #  # ]:          0 :             aToken.Erase( 0, 1 );
    1327         [ #  # ]:          0 :             if( aConstraint.m_pKey1 )
    1328         [ #  # ]:          0 :                 aConstraint.m_pKey2 = getKey( aToken );
    1329                 :            :             else
    1330         [ #  # ]:          0 :                 aConstraint.m_pKey1 = getKey( aToken );
    1331                 :            :         }
    1332                 :            :         else
    1333                 :            :         {
    1334         [ #  # ]:          0 :             if( aConstraint.m_pKey2 )
    1335                 :            :             {
    1336 [ #  # ][ #  # ]:          0 :                 if( ! ( aConstraint.m_pOption2 = aConstraint.m_pKey2->getValue( aToken ) ) )
    1337                 :          0 :                     bFailed = true;
    1338                 :            :             }
    1339         [ #  # ]:          0 :             else if( aConstraint.m_pKey1 )
    1340                 :            :             {
    1341 [ #  # ][ #  # ]:          0 :                 if( ! ( aConstraint.m_pOption1 = aConstraint.m_pKey1->getValue( aToken ) ) )
    1342                 :          0 :                     bFailed = true;
    1343                 :            :             }
    1344                 :            :             else
    1345                 :            :                 // constraint for nonexistent keys; this happens
    1346                 :            :                 // e.g. in HP4PLUS3
    1347                 :          0 :                 bFailed = true;
    1348                 :            :         }
    1349         [ #  # ]:          0 :     }
    1350                 :            :     // there must be two keywords
    1351 [ #  # ][ #  # ]:          0 :     if( ! aConstraint.m_pKey1 || ! aConstraint.m_pKey2 || bFailed )
                 [ #  # ]
    1352                 :            :     {
    1353                 :            : #ifdef __DEBUG
    1354                 :            :         fprintf( stderr, "Warning: constraint \"%s\" is invalid\n", rLine.getStr() );
    1355                 :            : #endif
    1356                 :            :     }
    1357                 :            :     else
    1358 [ #  # ][ #  # ]:          0 :         m_aConstraints.push_back( aConstraint );
    1359                 :          0 : }
    1360                 :            : 
    1361                 :          0 : String PPDParser::getDefaultPaperDimension() const
    1362                 :            : {
    1363         [ #  # ]:          0 :     if( m_pDefaultPaperDimension )
    1364                 :          0 :         return m_pDefaultPaperDimension->m_aOption;
    1365                 :            : 
    1366                 :          0 :     return String();
    1367                 :            : }
    1368                 :            : 
    1369                 :        112 : bool PPDParser::getMargins(
    1370                 :            :                            const String& rPaperName,
    1371                 :            :                            int& rLeft, int& rRight,
    1372                 :            :                            int& rUpper, int& rLower ) const
    1373                 :            : {
    1374 [ +  - ][ -  + ]:        112 :     if( ! m_pImageableAreas || ! m_pPaperDimensions )
    1375                 :          0 :         return false;
    1376                 :            : 
    1377                 :        112 :     int nPDim=-1, nImArea=-1, i;
    1378 [ +  - ][ +  + ]:       3696 :     for( i = 0; i < m_pImageableAreas->countValues(); i++ )
    1379 [ +  - ][ +  - ]:       3584 :         if( rPaperName == m_pImageableAreas->getValue( i )->m_aOption )
                 [ +  + ]
    1380                 :        112 :             nImArea = i;
    1381 [ +  - ][ +  + ]:       3696 :     for( i = 0; i < m_pPaperDimensions->countValues(); i++ )
    1382 [ +  - ][ +  - ]:       3584 :         if( rPaperName == m_pPaperDimensions->getValue( i )->m_aOption )
                 [ +  + ]
    1383                 :        112 :             nPDim = i;
    1384 [ +  - ][ -  + ]:        112 :     if( nPDim == -1 || nImArea == -1 )
    1385                 :          0 :         return false;
    1386                 :            : 
    1387                 :            :     double ImLLx, ImLLy, ImURx, ImURy;
    1388                 :            :     double PDWidth, PDHeight;
    1389 [ +  - ][ +  - ]:        112 :     String aArea = m_pImageableAreas->getValue( nImArea )->m_aValue;
    1390 [ +  - ][ +  - ]:        112 :     ImLLx = StringToDouble( GetCommandLineToken( 0, aArea ) );
                 [ +  - ]
    1391 [ +  - ][ +  - ]:        112 :     ImLLy = StringToDouble( GetCommandLineToken( 1, aArea ) );
                 [ +  - ]
    1392 [ +  - ][ +  - ]:        112 :     ImURx = StringToDouble( GetCommandLineToken( 2, aArea ) );
                 [ +  - ]
    1393 [ +  - ][ +  - ]:        112 :     ImURy = StringToDouble( GetCommandLineToken( 3, aArea ) );
                 [ +  - ]
    1394 [ +  - ][ +  - ]:        112 :     aArea = m_pPaperDimensions->getValue( nPDim )->m_aValue;
    1395 [ +  - ][ +  - ]:        112 :     PDWidth     = StringToDouble( GetCommandLineToken( 0, aArea ) );
                 [ +  - ]
    1396 [ +  - ][ +  - ]:        112 :     PDHeight    = StringToDouble( GetCommandLineToken( 1, aArea ) );
                 [ +  - ]
    1397                 :        112 :     rLeft  = (int)(ImLLx + 0.5);
    1398                 :        112 :     rLower = (int)(ImLLy + 0.5);
    1399                 :        112 :     rUpper = (int)(PDHeight - ImURy + 0.5);
    1400                 :        112 :     rRight = (int)(PDWidth - ImURx + 0.5);
    1401                 :            : 
    1402         [ +  - ]:        112 :     return true;
    1403                 :            : }
    1404                 :            : 
    1405                 :        224 : bool PPDParser::getPaperDimension(
    1406                 :            :                                   const String& rPaperName,
    1407                 :            :                                   int& rWidth, int& rHeight ) const
    1408                 :            : {
    1409         [ -  + ]:        224 :     if( ! m_pPaperDimensions )
    1410                 :          0 :         return false;
    1411                 :            : 
    1412                 :        224 :     int nPDim=-1;
    1413 [ +  - ][ +  + ]:       7392 :     for( int i = 0; i < m_pPaperDimensions->countValues(); i++ )
    1414 [ +  - ][ +  - ]:       7168 :         if( rPaperName == m_pPaperDimensions->getValue( i )->m_aOption )
                 [ +  + ]
    1415                 :        224 :             nPDim = i;
    1416         [ -  + ]:        224 :     if( nPDim == -1 )
    1417                 :          0 :         return false;
    1418                 :            : 
    1419                 :            :     double PDWidth, PDHeight;
    1420 [ +  - ][ +  - ]:        224 :     String aArea = m_pPaperDimensions->getValue( nPDim )->m_aValue;
    1421 [ +  - ][ +  - ]:        224 :     PDWidth     = StringToDouble( GetCommandLineToken( 0, aArea ) );
                 [ +  - ]
    1422 [ +  - ][ +  - ]:        224 :     PDHeight    = StringToDouble( GetCommandLineToken( 1, aArea ) );
                 [ +  - ]
    1423                 :        224 :     rHeight = (int)(PDHeight + 0.5);
    1424                 :        224 :     rWidth  = (int)(PDWidth + 0.5);
    1425                 :            : 
    1426         [ +  - ]:        224 :     return true;
    1427                 :            : }
    1428                 :            : 
    1429                 :          0 : String PPDParser::matchPaper( int nWidth, int nHeight ) const
    1430                 :            : {
    1431         [ #  # ]:          0 :     if( ! m_pPaperDimensions )
    1432                 :          0 :         return String();
    1433                 :            : 
    1434                 :          0 :     int nPDim = -1;
    1435                 :            :     double PDWidth, PDHeight;
    1436                 :          0 :     double fSort = 2e36, fNewSort;
    1437                 :            : 
    1438         [ #  # ]:          0 :     for( int i = 0; i < m_pPaperDimensions->countValues(); i++ )
    1439                 :            :     {
    1440 [ #  # ][ #  # ]:          0 :         String aArea =  m_pPaperDimensions->getValue( i )->m_aValue;
    1441 [ #  # ][ #  # ]:          0 :         PDWidth     = StringToDouble( GetCommandLineToken( 0, aArea ) );
                 [ #  # ]
    1442 [ #  # ][ #  # ]:          0 :         PDHeight    = StringToDouble( GetCommandLineToken( 1, aArea ) );
                 [ #  # ]
    1443                 :          0 :         PDWidth     /= (double)nWidth;
    1444                 :          0 :         PDHeight    /= (double)nHeight;
    1445 [ #  # ][ #  # ]:          0 :         if( PDWidth >= 0.9      &&  PDWidth <= 1.1      &&
         [ #  # ][ #  # ]
    1446                 :            :             PDHeight >= 0.9     &&  PDHeight <= 1.1         )
    1447                 :            :         {
    1448                 :            :             fNewSort =
    1449                 :          0 :                 (1.0-PDWidth)*(1.0-PDWidth) + (1.0-PDHeight)*(1.0-PDHeight);
    1450         [ #  # ]:          0 :             if( fNewSort == 0.0 ) // perfect match
    1451 [ #  # ][ #  # ]:          0 :                 return m_pPaperDimensions->getValue( i )->m_aOption;
    1452                 :            : 
    1453         [ #  # ]:          0 :             if( fNewSort < fSort )
    1454                 :            :             {
    1455                 :          0 :                 fSort = fNewSort;
    1456                 :          0 :                 nPDim = i;
    1457                 :            :             }
    1458                 :            :         }
    1459 [ #  # ][ #  # ]:          0 :     }
    1460                 :            : 
    1461                 :            :     static bool bDontSwap = false;
    1462 [ #  # ][ #  # ]:          0 :     if( nPDim == -1 && ! bDontSwap )
    1463                 :            :     {
    1464                 :            :         // swap portrait/landscape and try again
    1465                 :          0 :         bDontSwap = true;
    1466         [ #  # ]:          0 :         String rRet = matchPaper( nHeight, nWidth );
    1467                 :          0 :         bDontSwap = false;
    1468 [ #  # ][ #  # ]:          0 :         return rRet;
    1469                 :            :     }
    1470                 :            : 
    1471         [ #  # ]:          0 :     return nPDim != -1 ? m_pPaperDimensions->getValue( nPDim )->m_aOption : String();
    1472                 :            : }
    1473                 :            : 
    1474                 :          0 : String PPDParser::getDefaultInputSlot() const
    1475                 :            : {
    1476         [ #  # ]:          0 :     if( m_pDefaultInputSlot )
    1477                 :          0 :         return m_pDefaultInputSlot->m_aValue;
    1478                 :          0 :     return String();
    1479                 :            : }
    1480                 :            : 
    1481                 :        333 : void PPDParser::getResolutionFromString(
    1482                 :            :                                         const String& rString,
    1483                 :            :                                         int& rXRes, int& rYRes ) const
    1484                 :            : {
    1485                 :            :     int nDPIPos;
    1486                 :            : 
    1487                 :        333 :     rXRes = rYRes = 300;
    1488                 :            : 
    1489                 :        333 :     nDPIPos = rString.SearchAscii( "dpi" );
    1490         [ +  - ]:        333 :     if( nDPIPos != STRING_NOTFOUND )
    1491                 :            :     {
    1492                 :        333 :         int nPos = 0;
    1493         [ -  + ]:        333 :         if( ( nPos = rString.Search( 'x' ) ) != STRING_NOTFOUND )
    1494                 :            :         {
    1495         [ #  # ]:          0 :             rXRes = rString.Copy( 0, nPos ).ToInt32();
    1496 [ #  # ][ #  # ]:          0 :             rYRes = rString.GetToken( 1, 'x' ).Erase( nDPIPos - nPos - 1 ).ToInt32();
    1497                 :            :         }
    1498                 :            :         else
    1499         [ +  - ]:        333 :             rXRes = rYRes = rString.Copy( 0, nDPIPos ).ToInt32();
    1500                 :            :     }
    1501                 :        333 : }
    1502                 :            : 
    1503                 :          0 : void PPDParser::getDefaultResolution( int& rXRes, int& rYRes ) const
    1504                 :            : {
    1505         [ #  # ]:          0 :     if( m_pDefaultResolution )
    1506                 :            :     {
    1507                 :          0 :         getResolutionFromString( m_pDefaultResolution->m_aValue, rXRes, rYRes );
    1508                 :          0 :         return;
    1509                 :            :     }
    1510                 :            : 
    1511                 :          0 :     rXRes = 300;
    1512                 :          0 :     rYRes = 300;
    1513                 :            : }
    1514                 :            : 
    1515                 :       3990 : String PPDParser::getFont( int nFont ) const
    1516                 :            : {
    1517         [ -  + ]:       3990 :     if( ! m_pFontList )
    1518                 :          0 :         return String();
    1519                 :            : 
    1520 [ +  - ][ +  - ]:       3990 :     if( nFont >=0 && nFont < m_pFontList->countValues() )
                 [ +  - ]
    1521                 :       3990 :         return m_pFontList->getValue( nFont )->m_aOption;
    1522                 :       3990 :     return String();
    1523                 :            : }
    1524                 :            : 
    1525                 :          0 : rtl::OUString PPDParser::translateKey( const rtl::OUString& i_rKey,
    1526                 :            :                                        const com::sun::star::lang::Locale& i_rLocale ) const
    1527                 :            : {
    1528                 :          0 :     rtl::OUString aResult( m_pTranslator->translateKey( i_rKey, i_rLocale ) );
    1529         [ #  # ]:          0 :     if( aResult.isEmpty() )
    1530                 :          0 :         aResult = i_rKey;
    1531                 :          0 :     return aResult;
    1532                 :            : }
    1533                 :            : 
    1534                 :          0 : rtl::OUString PPDParser::translateOption( const rtl::OUString& i_rKey,
    1535                 :            :                                           const rtl::OUString& i_rOption,
    1536                 :            :                                           const com::sun::star::lang::Locale& i_rLocale ) const
    1537                 :            : {
    1538                 :          0 :     rtl::OUString aResult( m_pTranslator->translateOption( i_rKey, i_rOption, i_rLocale ) );
    1539         [ #  # ]:          0 :     if( aResult.isEmpty() )
    1540                 :          0 :         aResult = i_rOption;
    1541                 :          0 :     return aResult;
    1542                 :            : }
    1543                 :            : 
    1544                 :            : /*
    1545                 :            :  *  PPDKey
    1546                 :            :  */
    1547                 :            : 
    1548                 :       2700 : PPDKey::PPDKey( const String& rKey ) :
    1549                 :            :         m_aKey( rKey ),
    1550                 :            :         m_pDefaultValue( NULL ),
    1551                 :            :         m_bQueryValue( false ),
    1552                 :            :         m_bUIOption( false ),
    1553                 :            :         m_eUIType( PickOne ),
    1554                 :            :         m_nOrderDependency( 100 ),
    1555 [ +  - ][ +  - ]:       2700 :         m_eSetupType( AnySetup )
                 [ +  - ]
    1556                 :            : {
    1557                 :       2700 : }
    1558                 :            : 
    1559                 :            : // -------------------------------------------------------------------
    1560                 :            : 
    1561 [ +  - ][ +  - ]:       2700 : PPDKey::~PPDKey()
    1562                 :            : {
    1563                 :       2700 : }
    1564                 :            : 
    1565                 :            : // -------------------------------------------------------------------
    1566                 :            : 
    1567                 :      19707 : const PPDValue* PPDKey::getValue( int n ) const
    1568                 :            : {
    1569 [ +  - ][ +  - ]:      19707 :     return ((unsigned int)n < m_aOrderedValues.size() && n >= 0) ? m_aOrderedValues[n] : NULL;
    1570                 :            : }
    1571                 :            : 
    1572                 :            : // -------------------------------------------------------------------
    1573                 :            : 
    1574                 :        895 : const PPDValue* PPDKey::getValue( const String& rOption ) const
    1575                 :            : {
    1576 [ +  - ][ +  - ]:        895 :     PPDKey::hash_type::const_iterator it = m_aValues.find( rOption );
    1577 [ +  - ][ +  - ]:        895 :     return it != m_aValues.end() ? &it->second : NULL;
                 [ +  - ]
    1578                 :            : }
    1579                 :            : 
    1580                 :            : // -------------------------------------------------------------------
    1581                 :            : 
    1582                 :          3 : const PPDValue* PPDKey::getValueCaseInsensitive( const String& rOption ) const
    1583                 :            : {
    1584                 :          3 :     const PPDValue* pValue = getValue( rOption );
    1585         [ -  + ]:          3 :     if( ! pValue )
    1586                 :            :     {
    1587 [ #  # ][ #  # ]:          0 :         for( size_t n = 0; n < m_aOrderedValues.size() && ! pValue; n++ )
                 [ #  # ]
    1588         [ #  # ]:          0 :             if( m_aOrderedValues[n]->m_aOption.EqualsIgnoreCaseAscii( rOption ) )
    1589                 :          0 :                 pValue = m_aOrderedValues[n];
    1590                 :            :     }
    1591                 :            : 
    1592                 :          3 :     return pValue;
    1593                 :            : }
    1594                 :            : 
    1595                 :            : // -------------------------------------------------------------------
    1596                 :            : 
    1597                 :        180 : void PPDKey::eraseValue( const String& rOption )
    1598                 :            : {
    1599 [ +  - ][ +  - ]:        180 :     PPDKey::hash_type::iterator it = m_aValues.find( rOption );
    1600 [ +  - ][ +  - ]:        180 :     if( it == m_aValues.end() )
    1601                 :        180 :         return;
    1602                 :            : 
    1603 [ +  - ][ +  - ]:       2100 :     for( PPDKey::value_type::iterator vit = m_aOrderedValues.begin(); vit != m_aOrderedValues.end(); ++vit )
                 [ +  - ]
    1604                 :            :     {
    1605 [ +  - ][ +  - ]:       2100 :         if( *vit == &(it->second ) )
                 [ +  + ]
    1606                 :            :         {
    1607         [ +  - ]:        180 :             m_aOrderedValues.erase( vit );
    1608                 :        180 :             break;
    1609                 :            :         }
    1610                 :            :     }
    1611         [ +  - ]:        180 :     m_aValues.erase( it );
    1612                 :            : }
    1613                 :            : 
    1614                 :            : // -------------------------------------------------------------------
    1615                 :            : 
    1616                 :      20760 : PPDValue* PPDKey::insertValue( const String& rOption )
    1617                 :            : {
    1618 [ +  - ][ +  - ]:      20760 :     if( m_aValues.find( rOption ) != m_aValues.end() )
         [ +  - ][ +  + ]
    1619                 :       1800 :         return NULL;
    1620                 :            : 
    1621         [ +  - ]:      18960 :     PPDValue aValue;
    1622         [ +  - ]:      18960 :     aValue.m_aOption = rOption;
    1623 [ +  - ][ +  - ]:      18960 :     m_aValues[ rOption ] = aValue;
                 [ +  - ]
    1624 [ +  - ][ +  - ]:      18960 :     PPDValue* pValue = &m_aValues[rOption];
    1625         [ +  - ]:      18960 :     m_aOrderedValues.push_back( pValue );
    1626         [ +  - ]:      20760 :     return pValue;
    1627                 :            : }
    1628                 :            : 
    1629                 :            : // -------------------------------------------------------------------
    1630                 :            : 
    1631                 :            : /*
    1632                 :            :  * PPDContext
    1633                 :            :  */
    1634                 :            : 
    1635                 :        681 : PPDContext::PPDContext( const PPDParser* pParser ) :
    1636         [ +  - ]:        681 :         m_pParser( pParser )
    1637                 :            : {
    1638                 :        681 : }
    1639                 :            : 
    1640                 :            : // -------------------------------------------------------------------
    1641                 :            : 
    1642                 :        477 : PPDContext& PPDContext::operator=( const PPDContext& rCopy )
    1643                 :            : {
    1644                 :        477 :     m_pParser           = rCopy.m_pParser;
    1645                 :        477 :     m_aCurrentValues    = rCopy.m_aCurrentValues;
    1646                 :        477 :     return *this;
    1647                 :            : }
    1648                 :            : 
    1649                 :            : // -------------------------------------------------------------------
    1650                 :            : 
    1651                 :        539 : PPDContext::~PPDContext()
    1652                 :            : {
    1653                 :        539 : }
    1654                 :            : 
    1655                 :            : // -------------------------------------------------------------------
    1656                 :            : 
    1657                 :        144 : const PPDKey* PPDContext::getModifiedKey( int n ) const
    1658                 :            : {
    1659                 :        144 :     hash_type::const_iterator it;
    1660 [ +  - ][ -  + ]:        144 :     for( it = m_aCurrentValues.begin(); it != m_aCurrentValues.end() && n--; ++it )
         [ +  - ][ -  + ]
                 [ +  - ]
    1661                 :            :         ;
    1662 [ +  - ][ +  - ]:        144 :     return it != m_aCurrentValues.end() ? it->first : NULL;
    1663                 :            : }
    1664                 :            : 
    1665                 :            : // -------------------------------------------------------------------
    1666                 :            : 
    1667                 :        299 : void PPDContext::setParser( const PPDParser* pParser )
    1668                 :            : {
    1669         [ +  + ]:        299 :     if( pParser != m_pParser )
    1670                 :            :     {
    1671                 :        187 :         m_aCurrentValues.clear();
    1672                 :        187 :         m_pParser = pParser;
    1673                 :            :     }
    1674                 :        299 : }
    1675                 :            : 
    1676                 :            : // -------------------------------------------------------------------
    1677                 :            : 
    1678                 :        741 : const PPDValue* PPDContext::getValue( const PPDKey* pKey ) const
    1679                 :            : {
    1680         [ -  + ]:        741 :     if( ! m_pParser )
    1681                 :          0 :         return NULL;
    1682                 :            : 
    1683                 :        741 :     hash_type::const_iterator it;
    1684         [ +  - ]:        741 :     it = m_aCurrentValues.find( pKey );
    1685         [ +  + ]:        741 :     if( it != m_aCurrentValues.end() )
    1686         [ +  - ]:        299 :         return it->second;
    1687                 :            : 
    1688 [ +  - ][ -  + ]:        442 :     if( ! m_pParser->hasKey( pKey ) )
    1689                 :          0 :         return NULL;
    1690                 :            : 
    1691                 :        442 :     const PPDValue* pValue = pKey->getDefaultValue();
    1692         [ +  + ]:        442 :     if( ! pValue )
    1693         [ +  - ]:        333 :         pValue = pKey->getValue( 0 );
    1694                 :            : 
    1695                 :        741 :     return pValue;
    1696                 :            : }
    1697                 :            : 
    1698                 :            : // -------------------------------------------------------------------
    1699                 :            : 
    1700                 :        150 : const PPDValue* PPDContext::setValue( const PPDKey* pKey, const PPDValue* pValue, bool bDontCareForConstraints )
    1701                 :            : {
    1702 [ +  - ][ -  + ]:        150 :     if( ! m_pParser || ! pKey )
    1703                 :          0 :         return NULL;
    1704                 :            : 
    1705                 :            :     // pValue can be NULL - it means ignore this option
    1706                 :            : 
    1707         [ -  + ]:        150 :     if( ! m_pParser->hasKey( pKey ) )
    1708                 :          0 :         return NULL;
    1709                 :            : 
    1710                 :            :     // check constraints
    1711         [ +  - ]:        150 :     if( pValue )
    1712                 :            :     {
    1713         [ -  + ]:        150 :         if( bDontCareForConstraints )
    1714                 :            :         {
    1715                 :          0 :             m_aCurrentValues[ pKey ] = pValue;
    1716                 :            :         }
    1717         [ +  - ]:        150 :         else if( checkConstraints( pKey, pValue, true ) )
    1718                 :            :         {
    1719         [ +  - ]:        150 :             m_aCurrentValues[ pKey ] = pValue;
    1720                 :            : 
    1721                 :            :             // after setting this value, check all constraints !
    1722         [ +  - ]:        150 :             hash_type::iterator it = m_aCurrentValues.begin();
    1723 [ +  - ][ +  + ]:        306 :             while(  it != m_aCurrentValues.end() )
    1724                 :            :             {
    1725 [ +  - ][ +  + ]:        162 :                 if( it->first != pKey &&
         [ -  + ][ -  + ]
    1726 [ +  - ][ +  - ]:          6 :                     ! checkConstraints( it->first, it->second, false ) )
                 [ +  - ]
    1727                 :            :                 {
    1728                 :            : #ifdef __DEBUG
    1729                 :            :                     fprintf( stderr, "PPDContext::setValue: option %s (%s) is constrained after setting %s to %s\n",
    1730                 :            :                              it->first->getKey().GetStr(),
    1731                 :            :                              it->second->m_aOption.GetStr(),
    1732                 :            :                              pKey->getKey().GetStr(),
    1733                 :            :                              pValue->m_aOption.GetStr() );
    1734                 :            : #endif
    1735 [ #  # ][ #  # ]:          0 :                     resetValue( it->first, true );
    1736         [ #  # ]:          0 :                     it = m_aCurrentValues.begin();
    1737                 :            :                 }
    1738                 :            :                 else
    1739                 :        156 :                     ++it;
    1740                 :            :             }
    1741                 :            :         }
    1742                 :            :     }
    1743                 :            :     else
    1744                 :          0 :         m_aCurrentValues[ pKey ] = NULL;
    1745                 :            : 
    1746                 :        150 :     return pValue;
    1747                 :            : }
    1748                 :            : 
    1749                 :            : // -------------------------------------------------------------------
    1750                 :            : 
    1751                 :          0 : bool PPDContext::checkConstraints( const PPDKey* pKey, const PPDValue* pValue )
    1752                 :            : {
    1753 [ #  # ][ #  # ]:          0 :     if( ! m_pParser || ! pKey || ! pValue )
                 [ #  # ]
    1754                 :          0 :         return false;
    1755                 :            : 
    1756                 :            :     // ensure that this key is already in the list if it exists at all
    1757 [ #  # ][ #  # ]:          0 :     if( m_aCurrentValues.find( pKey ) != m_aCurrentValues.end() )
    1758                 :          0 :         return checkConstraints( pKey, pValue, false );
    1759                 :            : 
    1760                 :            :     // it is not in the list, insert it temporarily
    1761                 :          0 :     bool bRet = false;
    1762         [ #  # ]:          0 :     if( m_pParser->hasKey( pKey ) )
    1763                 :            :     {
    1764                 :          0 :         const PPDValue* pDefValue = pKey->getDefaultValue();
    1765                 :          0 :         m_aCurrentValues[ pKey ] = pDefValue;
    1766                 :          0 :         bRet = checkConstraints( pKey, pValue, false );
    1767                 :          0 :         m_aCurrentValues.erase( pKey );
    1768                 :            :     }
    1769                 :            : 
    1770                 :          0 :     return bRet;
    1771                 :            : }
    1772                 :            : 
    1773                 :            : // -------------------------------------------------------------------
    1774                 :            : 
    1775                 :          0 : bool PPDContext::resetValue( const PPDKey* pKey, bool bDefaultable )
    1776                 :            : {
    1777 [ #  # ][ #  # ]:          0 :     if( ! pKey || ! m_pParser || ! m_pParser->hasKey( pKey ) )
         [ #  # ][ #  # ]
    1778                 :          0 :         return false;
    1779                 :            : 
    1780         [ #  # ]:          0 :     const PPDValue* pResetValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "None" ) ) );
    1781         [ #  # ]:          0 :     if( ! pResetValue )
    1782         [ #  # ]:          0 :         pResetValue = pKey->getValue( String( RTL_CONSTASCII_USTRINGPARAM( "False" ) ) );
    1783 [ #  # ][ #  # ]:          0 :     if( ! pResetValue && bDefaultable )
    1784                 :          0 :         pResetValue = pKey->getDefaultValue();
    1785                 :            : 
    1786 [ #  # ][ #  # ]:          0 :     bool bRet = pResetValue ? ( setValue( pKey, pResetValue ) == pResetValue ? true : false ) : false;
    1787                 :            : 
    1788                 :          0 :     return bRet;
    1789                 :            : }
    1790                 :            : 
    1791                 :            : // -------------------------------------------------------------------
    1792                 :            : 
    1793                 :        156 : bool PPDContext::checkConstraints( const PPDKey* pKey, const PPDValue* pNewValue, bool bDoReset )
    1794                 :            : {
    1795         [ -  + ]:        156 :     if( ! pNewValue )
    1796                 :          0 :         return true;
    1797                 :            : 
    1798                 :            :     // sanity checks
    1799         [ -  + ]:        156 :     if( ! m_pParser )
    1800                 :          0 :         return false;
    1801                 :            : 
    1802         [ -  + ]:        156 :     if( pKey->getValue( pNewValue->m_aOption ) != pNewValue )
    1803                 :          0 :         return false;
    1804                 :            : 
    1805                 :            :     // None / False and the default can always be set, but be careful !
    1806                 :            :     // setting them might influence constrained values
    1807         [ +  + ]:        306 :     if( pNewValue->m_aOption.EqualsAscii( "None" ) || pNewValue->m_aOption.EqualsAscii( "False" ) ||
           [ +  -  +  + ]
                 [ +  + ]
    1808                 :        150 :         pNewValue == pKey->getDefaultValue() )
    1809                 :         12 :         return true;
    1810                 :            : 
    1811                 :        144 :     const ::std::list< PPDParser::PPDConstraint >& rConstraints( m_pParser->getConstraints() );
    1812 [ #  # ][ +  - ]:        144 :     for( ::std::list< PPDParser::PPDConstraint >::const_iterator it = rConstraints.begin(); it != rConstraints.end(); ++it )
                 [ -  + ]
    1813                 :            :     {
    1814         [ #  # ]:          0 :         const PPDKey* pLeft     = it->m_pKey1;
    1815         [ #  # ]:          0 :         const PPDKey* pRight    = it->m_pKey2;
    1816 [ #  # ][ #  # ]:          0 :         if( ! pLeft || ! pRight || ( pKey != pLeft && pKey != pRight ) )
         [ #  # ][ #  # ]
    1817                 :          0 :             continue;
    1818                 :            : 
    1819         [ #  # ]:          0 :         const PPDKey* pOtherKey = pKey == pLeft ? pRight : pLeft;
    1820 [ #  # ][ #  # ]:          0 :         const PPDValue* pOtherKeyOption = pKey == pLeft ? it->m_pOption2 : it->m_pOption1;
                 [ #  # ]
    1821 [ #  # ][ #  # ]:          0 :         const PPDValue* pKeyOption = pKey == pLeft ? it->m_pOption1 : it->m_pOption2;
                 [ #  # ]
    1822                 :            : 
    1823                 :            :         // syntax *Key1 option1 *Key2 option2
    1824 [ #  # ][ #  # ]:          0 :         if( pKeyOption && pOtherKeyOption )
    1825                 :            :         {
    1826         [ #  # ]:          0 :             if( pNewValue != pKeyOption )
    1827                 :          0 :                 continue;
    1828 [ #  # ][ #  # ]:          0 :             if( pOtherKeyOption == getValue( pOtherKey ) )
    1829                 :            :             {
    1830                 :          0 :                 return false;
    1831                 :            :             }
    1832                 :            :         }
    1833                 :            :         // syntax *Key1 option *Key2  or  *Key1 *Key2 option
    1834 [ #  # ][ #  # ]:          0 :         else if( pOtherKeyOption || pKeyOption )
    1835                 :            :         {
    1836         [ #  # ]:          0 :             if( pKeyOption )
    1837                 :            :             {
    1838 [ #  # ][ #  # ]:          0 :                 if( ! ( pOtherKeyOption = getValue( pOtherKey ) ) )
    1839                 :          0 :                     continue; // this should not happen, PPD broken
    1840                 :            : 
    1841 [ #  # ][ #  # ]:          0 :                 if( pKeyOption == pNewValue &&
         [ #  # ][ #  # ]
    1842         [ #  # ]:          0 :                     ! pOtherKeyOption->m_aOption.EqualsAscii( "None" ) &&
    1843         [ #  # ]:          0 :                     ! pOtherKeyOption->m_aOption.EqualsAscii( "False" ) )
    1844                 :            :                 {
    1845                 :            :                     // check if the other value can be reset and
    1846                 :            :                     // do so if possible
    1847 [ #  # ][ #  # ]:          0 :                     if( bDoReset && resetValue( pOtherKey ) )
         [ #  # ][ #  # ]
    1848                 :          0 :                         continue;
    1849                 :            : 
    1850                 :          0 :                     return false;
    1851                 :            :                 }
    1852                 :            :             }
    1853         [ #  # ]:          0 :             else if( pOtherKeyOption )
    1854                 :            :             {
    1855 [ #  # ][ #  # ]:          0 :                 if( getValue( pOtherKey ) == pOtherKeyOption &&
         [ #  # ][ #  # ]
                 [ #  # ]
    1856         [ #  # ]:          0 :                     ! pNewValue->m_aOption.EqualsAscii( "None" ) &&
    1857         [ #  # ]:          0 :                     ! pNewValue->m_aOption.EqualsAscii( "False" ) )
    1858                 :          0 :                     return false;
    1859                 :            :             }
    1860                 :            :             else
    1861                 :            :             {
    1862                 :            :                 // this should not happen, PPD is broken
    1863                 :            :             }
    1864                 :            :         }
    1865                 :            :         // syntax *Key1 *Key2
    1866                 :            :         else
    1867                 :            :         {
    1868         [ #  # ]:          0 :             const PPDValue* pOtherValue = getValue( pOtherKey );
    1869 [ #  # ][ #  # ]:          0 :             if( ! pOtherValue->m_aOption.EqualsAscii( "None" )  &&
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1870         [ #  # ]:          0 :                 ! pOtherValue->m_aOption.EqualsAscii( "False" )     &&
    1871         [ #  # ]:          0 :                 ! pNewValue->m_aOption.EqualsAscii( "None" )        &&
    1872         [ #  # ]:          0 :                 ! pNewValue->m_aOption.EqualsAscii( "False" ) )
    1873                 :          0 :                 return false;
    1874                 :            :         }
    1875                 :            :     }
    1876                 :        156 :     return true;
    1877                 :            : }
    1878                 :            : 
    1879                 :            : // -------------------------------------------------------------------
    1880                 :            : 
    1881                 :        112 : char* PPDContext::getStreamableBuffer( sal_uLong& rBytes ) const
    1882                 :            : {
    1883                 :        112 :     rBytes = 0;
    1884         [ -  + ]:        112 :     if( ! m_aCurrentValues.size() )
    1885                 :          0 :         return NULL;
    1886                 :        112 :     hash_type::const_iterator it;
    1887 [ +  + ][ +  - ]:        227 :     for( it = m_aCurrentValues.begin(); it != m_aCurrentValues.end(); ++it )
    1888                 :            :     {
    1889 [ +  - ][ +  - ]:        115 :         rtl::OString aCopy(rtl::OUStringToOString(it->first->getKey(), RTL_TEXTENCODING_MS_1252));
                 [ +  - ]
    1890                 :        115 :         rBytes += aCopy.getLength();
    1891                 :        115 :         rBytes += 1; // for ':'
    1892 [ +  - ][ +  - ]:        115 :         if( it->second )
    1893                 :            :         {
    1894 [ +  - ][ +  - ]:        115 :             aCopy = rtl::OUStringToOString(it->second->m_aOption, RTL_TEXTENCODING_MS_1252);
                 [ +  - ]
    1895                 :        115 :             rBytes += aCopy.getLength();
    1896                 :            :         }
    1897                 :            :         else
    1898                 :          0 :             rBytes += 4;
    1899                 :        115 :         rBytes += 1; // for '\0'
    1900                 :        115 :     }
    1901                 :        112 :     rBytes += 1;
    1902         [ +  - ]:        112 :     char* pBuffer = new char[ rBytes ];
    1903                 :        112 :     memset( pBuffer, 0, rBytes );
    1904                 :        112 :     char* pRun = pBuffer;
    1905 [ +  - ][ +  + ]:        227 :     for( it = m_aCurrentValues.begin(); it != m_aCurrentValues.end(); ++it )
    1906                 :            :     {
    1907 [ +  - ][ +  - ]:        115 :         rtl::OString aCopy(rtl::OUStringToOString(it->first->getKey(), RTL_TEXTENCODING_MS_1252));
                 [ +  - ]
    1908                 :        115 :         int nBytes = aCopy.getLength();
    1909                 :        115 :         memcpy( pRun, aCopy.getStr(), nBytes );
    1910                 :        115 :         pRun += nBytes;
    1911                 :        115 :         *pRun++ = ':';
    1912 [ +  - ][ +  - ]:        115 :         if( it->second )
    1913 [ +  - ][ +  - ]:        115 :             aCopy = rtl::OUStringToOString(it->second->m_aOption, RTL_TEXTENCODING_MS_1252);
                 [ +  - ]
    1914                 :            :         else
    1915                 :          0 :             aCopy = "*nil";
    1916                 :        115 :         nBytes = aCopy.getLength();
    1917                 :        115 :         memcpy( pRun, aCopy.getStr(), nBytes );
    1918                 :        115 :         pRun += nBytes;
    1919                 :            : 
    1920                 :        115 :         *pRun++ = 0;
    1921                 :        115 :     }
    1922                 :        112 :     return pBuffer;
    1923                 :            : }
    1924                 :            : 
    1925                 :            : // -------------------------------------------------------------------
    1926                 :            : 
    1927                 :        115 : void PPDContext::rebuildFromStreamBuffer( char* pBuffer, sal_uLong nBytes )
    1928                 :            : {
    1929         [ +  - ]:        115 :     if( ! m_pParser )
    1930                 :        115 :         return;
    1931                 :            : 
    1932         [ +  - ]:        115 :     m_aCurrentValues.clear();
    1933                 :            : 
    1934                 :        115 :     char* pRun = pBuffer;
    1935 [ +  - ][ +  + ]:        236 :     while( nBytes && *pRun )
                 [ +  + ]
    1936                 :            :     {
    1937                 :        121 :         rtl::OString aLine( pRun );
    1938                 :        121 :         sal_Int32 nPos = aLine.indexOf(':');
    1939         [ +  - ]:        121 :         if( nPos != -1 )
    1940                 :            :         {
    1941 [ +  - ][ +  - ]:        121 :             const PPDKey* pKey = m_pParser->getKey( rtl::OStringToOUString( aLine.copy( 0, nPos ), RTL_TEXTENCODING_MS_1252 ) );
         [ +  - ][ +  - ]
    1942         [ +  - ]:        121 :             if( pKey )
    1943                 :            :             {
    1944                 :        121 :                 const PPDValue* pValue = NULL;
    1945         [ +  - ]:        121 :                 rtl::OUString aOption(rtl::OStringToOUString(aLine.copy(nPos+1), RTL_TEXTENCODING_MS_1252));
    1946         [ +  - ]:        121 :                 if (aOption != "*nil")
    1947 [ +  - ][ +  - ]:        121 :                     pValue = pKey->getValue( aOption );
                 [ +  - ]
    1948         [ +  - ]:        121 :                 m_aCurrentValues[ pKey ] = pValue;
    1949                 :            : #ifdef __DEBUG
    1950                 :            :                 fprintf( stderr, "PPDContext::rebuildFromStreamBuffer: read PPDKeyValue { %s, %s }\n", pKV->m_pKey->getKey().GetStr(), pKV->m_pCurrentValue ? pKV->m_pCurrentValue->m_aOption.GetStr() : "<nil>" );
    1951                 :            : #endif
    1952                 :            :             }
    1953                 :            :         }
    1954                 :        121 :         nBytes -= aLine.getLength()+1;
    1955                 :        121 :         pRun += aLine.getLength()+1;
    1956                 :        121 :     }
    1957                 :            : }
    1958                 :            : 
    1959                 :            : // -------------------------------------------------------------------
    1960                 :            : 
    1961                 :        333 : int PPDContext::getRenderResolution() const
    1962                 :            : {
    1963                 :            :     // initialize to reasonable default, if parser is not set
    1964                 :        333 :     int nDPI = 300;
    1965         [ +  - ]:        333 :     if( m_pParser )
    1966                 :            :     {
    1967                 :        333 :         int nDPIx = 300, nDPIy = 300;
    1968 [ +  - ][ +  - ]:        333 :         const PPDKey* pKey = m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ) );
                 [ +  - ]
    1969         [ +  - ]:        333 :         if( pKey )
    1970                 :            :         {
    1971         [ +  - ]:        333 :             const PPDValue* pValue = getValue( pKey );
    1972         [ +  - ]:        333 :             if( pValue )
    1973         [ +  - ]:        333 :                 m_pParser->getResolutionFromString( pValue->m_aOption, nDPIx, nDPIy );
    1974                 :            :             else
    1975         [ #  # ]:          0 :                 m_pParser->getDefaultResolution( nDPIx, nDPIy );
    1976                 :            :         }
    1977                 :            :         else
    1978         [ #  # ]:          0 :             m_pParser->getDefaultResolution( nDPIx, nDPIy );
    1979                 :            : 
    1980         [ -  + ]:        333 :         nDPI = (nDPIx > nDPIy) ? nDPIx : nDPIy;
    1981                 :            :     }
    1982                 :        333 :     return  nDPI;
    1983                 :            : }
    1984                 :            : 
    1985                 :            : // -------------------------------------------------------------------
    1986                 :            : 
    1987                 :        224 : void PPDContext::getPageSize( rtl::OUString& rPaper, int& rWidth, int& rHeight ) const
    1988                 :            : {
    1989                 :            :     // initialize to reasonable default, if parser is not set
    1990                 :        224 :     rPaper  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "A4" ) );
    1991                 :        224 :     rWidth  = 595;
    1992                 :        224 :     rHeight = 842;
    1993         [ +  - ]:        224 :     if( m_pParser )
    1994                 :            :     {
    1995         [ +  - ]:        224 :         const PPDKey* pKey = m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) );
    1996         [ +  - ]:        224 :         if( pKey )
    1997                 :            :         {
    1998                 :        224 :             const PPDValue* pValue = getValue( pKey );
    1999         [ +  - ]:        224 :             if( pValue )
    2000                 :            :             {
    2001                 :        224 :                 rPaper = pValue->m_aOption;
    2002         [ +  - ]:        224 :                 m_pParser->getPaperDimension( rPaper, rWidth, rHeight );
    2003                 :            :             }
    2004                 :            :             else
    2005                 :            :             {
    2006         [ #  # ]:          0 :                 rPaper = m_pParser->getDefaultPaperDimension();
    2007                 :          0 :                 m_pParser->getDefaultPaperDimension( rWidth, rHeight );
    2008                 :            :             }
    2009                 :            :         }
    2010                 :            :     }
    2011                 :        224 : }
    2012                 :            : 
    2013                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10