root / pkpgcounter / trunk / pkpgpdls / pdlparser.py @ 425

Revision 425, 4.9 kB (checked in by jerome, 18 years ago)

Ensure to close the child's stdin in all cases.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Auth Date Id Rev
RevLine 
[192]1#
2# pkpgcounter : a generic Page Description Language parser
3#
[303]4# (c) 2003, 2004, 2005, 2006 Jerome Alet <alet@librelogiciel.com>
[192]5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
[211]17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
[192]18#
19# $Id$
20#
21
[360]22"""This module defines the base class for all Page Description Language parsers."""
23
[199]24import sys
[371]25import popen2
[199]26
[220]27KILOBYTE = 1024   
28MEGABYTE = 1024 * KILOBYTE   
29FIRSTBLOCKSIZE = 16 * KILOBYTE
30LASTBLOCKSIZE = int(KILOBYTE / 4)
31
[193]32class PDLParserError(Exception):
33    """An exception for PDLParser related stuff."""
34    def __init__(self, message = ""):
35        self.message = message
36        Exception.__init__(self, message)
37    def __repr__(self):
38        return self.message
39    __str__ = __repr__
40       
[192]41class PDLParser :
42    """Generic PDL parser."""
[371]43    totiffcommand = None        # Default command to convert to TIFF
[220]44    def __init__(self, infile, debug=0, firstblock=None, lastblock=None) :
[192]45        """Initialize the generic parser."""
[220]46        self.infile = infile
[192]47        self.debug = debug
[220]48        if firstblock is None :
49            self.infile.seek(0)
50            firstblock = self.infile.read(FIRSTBLOCKSIZE)
51            try :
52                self.infile.seek(-LASTBLOCKSIZE, 2)
53                lastblock = self.infile.read(LASTBLOCKSIZE)
54            except IOError :   
55                lastblock = ""
56            self.infile.seek(0)
57        self.firstblock = firstblock
58        self.lastblock = lastblock
59        if not self.isValid() :
60            raise PDLParserError, "Invalid file format !"
61        try :
62            import psyco 
63        except ImportError :   
64            pass # Psyco is not installed
65        else :   
66            # Psyco is installed, tell it to compile
67            # the CPU intensive methods : PCL and PCLXL
68            # parsing will greatly benefit from this,
69            # for PostScript and PDF the difference is
70            # barely noticeable since they are already
71            # almost optimal, and much more speedy anyway.
72            psyco.bind(self.getJobSize)
73           
[252]74    def logdebug(self, message) :       
75        """Logs a debug message if needed."""
76        if self.debug :
77            sys.stderr.write("%s\n" % message)
78           
[220]79    def isValid(self) :   
[387]80        """Returns True if data is in the expected format, else False."""
[192]81        raise RuntimeError, "Not implemented !"
[220]82       
83    def getJobSize(self) :   
84        """Counts pages in a document."""
85        raise RuntimeError, "Not implemented !"
[362]86       
[363]87    def convertToTiffMultiPage24NC(self, fname, dpi) :
[362]88        """Converts the input file to TIFF format, X dpi, 24 bits per pixel, uncompressed.
[363]89           Writes TIFF datas to the file named by fname.
[362]90        """   
[371]91        if self.totiffcommand :
[425]92            commandline = self.totiffcommand % locals()
93            child = popen2.Popen4(commandline)
[371]94            try :
95                try :
96                    data = self.infile.read(MEGABYTE)   
97                    while data :
98                        child.tochild.write(data)
99                        data = self.infile.read(MEGABYTE)
100                except (IOError, OSError), msg :   
101                    raise PDLParserError, "Problem during conversion to TIFF : %s" % msg
102            finally :   
[425]103                child.tochild.close()   
[371]104                child.fromchild.close()
105               
106            try :
107                child.wait()
108            except OSError, msg :   
109                raise PDLParserError, "Problem during conversion to TIFF : %s" % msg
110        else :       
111            raise PDLParserError, "Impossible to compute ink coverage for this file format."
[415]112           
113def test(parserclass) :       
114    """Test function."""
115    if (len(sys.argv) < 2) or ((not sys.stdin.isatty()) and ("-" not in sys.argv[1:])) :
116        sys.argv.append("-")
117    totalsize = 0   
118    for arg in sys.argv[1:] :
119        if arg == "-" :
120            infile = sys.stdin
121            mustclose = 0
122        else :   
123            infile = open(arg, "rb")
124            mustclose = 1
125        try :
126            parser = parserclass(infile, debug=1)
127            totalsize += parser.getJobSize()
128        except PDLParserError, msg :   
129            sys.stderr.write("ERROR: %s\n" % msg)
130            sys.stderr.flush()
131        if mustclose :   
132            infile.close()
133    print "%s" % totalsize
134   
Note: See TracBrowser for help on using the browser.