Index: pkpgcounter/trunk/pdlanalyzer/tiff.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/tiff.py (revision 219)
+++ pkpgcounter/trunk/pdlanalyzer/tiff.py (revision 220)
@@ -29,6 +29,17 @@
 from pdlanalyzer import pdlparser
 
-class TIFFParser(pdlparser.PDLParser) :
+class Parser(pdlparser.PDLParser) :
     """A parser for TIFF documents."""
+    def isValid(self) :        
+        """Returns 1 if data is TIFF, else 0."""
+        littleendian = (chr(0x49)*2) + chr(0x2a) + chr(0)
+        bigendian = (chr(0x4d)*2) + chr(0) + chr(0x2a)
+        if self.firstblock[:4] in (littleendian, bigendian) :
+            if self.debug :  
+                sys.stderr.write("DEBUG: Input file is in the TIFF format.\n")
+            return 1
+        else :    
+            return 0
+    
     def getJobSize(self) :
         """Counts pages in a TIFF document.
@@ -77,5 +88,5 @@
             mustclose = 1
         try :
-            parser = TIFFParser(infile, debug=1)
+            parser = Parser(infile, debug=1)
             totalsize += parser.getJobSize()
         except pdlparser.PDLParserError, msg :    
Index: pkpgcounter/trunk/pdlanalyzer/pdf.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/pdf.py (revision 211)
+++ pkpgcounter/trunk/pdlanalyzer/pdf.py (revision 220)
@@ -27,6 +27,18 @@
 from pdlanalyzer import pdlparser
 
-class PDFParser(pdlparser.PDLParser) :
+class Parser(pdlparser.PDLParser) :
     """A parser for PDF documents."""
+    def isValid(self) :    
+        """Returns 1 if data is PDF, else 0."""
+        if self.firstblock.startswith("%PDF-") or \
+           self.firstblock.startswith("\033%-12345X%PDF-") or \
+           ((self.firstblock[:128].find("\033%-12345X") != -1) and (self.firstblock.upper().find("LANGUAGE=PDF") != -1)) or \
+           (self.firstblock.find("%PDF-") != -1) :
+            if self.debug :  
+                sys.stderr.write("DEBUG: Input file is in the PDF format.\n")
+            return 1
+        else :    
+            return 0
+        
     def getJobSize(self) :    
         """Counts pages in a PDF document."""
@@ -56,5 +68,5 @@
             mustclose = 1
         try :
-            parser = PDFParser(infile, debug=1)
+            parser = Parser(infile, debug=1)
             totalsize += parser.getJobSize()
         except pdlparser.PDLParserError, msg :    
Index: pkpgcounter/trunk/pdlanalyzer/pcl345.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/pcl345.py (revision 211)
+++ pkpgcounter/trunk/pdlanalyzer/pcl345.py (revision 220)
@@ -28,5 +28,5 @@
 from pdlanalyzer import pdlparser
 
-class PCL345Parser(pdlparser.PDLParser) :
+class Parser(pdlparser.PDLParser) :
     """A parser for PCL3, PCL4, PCL5 documents."""
     mediasizes = {  # ESC&l####A
@@ -77,4 +77,16 @@
                      4 : "Transparent",
                    }
+        
+    def isValid(self) :    
+        """Returns 1 if data is PCL, else 0."""
+        if self.firstblock.startswith("\033E\033") or \
+           (self.firstblock.startswith("\033*rbC") and (not self.lastblock[-3:] == "\f\033@")) or \
+           self.firstblock.startswith("\033%8\033") or \
+           (self.firstblock.find("\033%-12345X") != -1) :
+            if self.debug :  
+                sys.stderr.write("DEBUG: Input file is in the PCL3/4/5 format.\n")
+            return 1
+        else :    
+            return 0
         
     def setPageDict(self, pages, number, attribute, value) :
@@ -346,5 +358,5 @@
             mustclose = 1
         try :
-            parser = PCL345Parser(infile, debug=1)
+            parser = Parser(infile, debug=1)
             totalsize += parser.getJobSize()
         except pdlparser.PDLParserError, msg :    
Index: pkpgcounter/trunk/pdlanalyzer/postscript.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/postscript.py (revision 211)
+++ pkpgcounter/trunk/pdlanalyzer/postscript.py (revision 220)
@@ -27,6 +27,22 @@
 from pdlanalyzer import pdlparser
 
-class PostScriptParser(pdlparser.PDLParser) :
+class Parser(pdlparser.PDLParser) :
     """A parser for PostScript documents."""
+    def isValid(self) :    
+        """Returns 1 if data is PostScript, else 0."""
+        if self.firstblock.startswith("%!") or \
+           self.firstblock.startswith("\004%!") or \
+           self.firstblock.startswith("\033%-12345X%!PS") or \
+           ((self.firstblock[:128].find("\033%-12345X") != -1) and \
+             ((self.firstblock.find("LANGUAGE=POSTSCRIPT") != -1) or \
+              (self.firstblock.find("LANGUAGE = POSTSCRIPT") != -1) or \
+              (self.firstblock.find("LANGUAGE = Postscript") != -1))) or \
+              (self.firstblock.find("%!PS-Adobe") != -1) :
+            if self.debug :  
+                sys.stderr.write("DEBUG: Input file is in the PostScript format.\n")
+            return 1
+        else :    
+            return 0
+        
     def throughGhostScript(self) :
         """Get the count through GhostScript, useful for non-DSC compliant PS files."""
@@ -112,5 +128,5 @@
             mustclose = 1
         try :
-            parser = PostScriptParser(infile, debug=1)
+            parser = Parser(infile, debug=1)
             totalsize += parser.getJobSize()
         except pdlparser.PDLParserError, msg :    
Index: pkpgcounter/trunk/pdlanalyzer/escp2.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/escp2.py (revision 211)
+++ pkpgcounter/trunk/pdlanalyzer/escp2.py (revision 220)
@@ -26,6 +26,18 @@
 from pdlanalyzer import pdlparser
 
-class ESCP2Parser(pdlparser.PDLParser) :
+class Parser(pdlparser.PDLParser) :
     """A parser for ESC/P2 documents."""
+    def isValid(self) :        
+        """Returns 1 if data is ESC/P2, else 0."""
+        if self.firstblock.startswith("\033@") or \
+           self.firstblock.startswith("\033*") or \
+           self.firstblock.startswith("\n\033@") or \
+           self.firstblock.startswith("\0\0\0\033\1@EJL") : # ESC/P Raster ??? Seen on Stylus Photo 1284
+            if self.debug :  
+                sys.stderr.write("DEBUG: Input file is in the ESC/P2 format.\n")
+            return 1
+        else :    
+            return 0
+            
     def getJobSize(self) :    
         """Counts pages in an ESC/P2 document."""
@@ -76,5 +88,5 @@
             mustclose = 1
         try :
-            parser = ESCP2Parser(infile, debug=1)
+            parser = Parser(infile, debug=1)
             totalsize += parser.getJobSize()
         except pdlparser.PDLParserError, msg :    
Index: pkpgcounter/trunk/pdlanalyzer/pdlparser.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/pdlparser.py (revision 211)
+++ pkpgcounter/trunk/pdlanalyzer/pdlparser.py (revision 220)
@@ -21,4 +21,10 @@
 
 import sys
+import psyco
+
+KILOBYTE = 1024    
+MEGABYTE = 1024 * KILOBYTE    
+FIRSTBLOCKSIZE = 16 * KILOBYTE
+LASTBLOCKSIZE = int(KILOBYTE / 4)
 
 class PDLParserError(Exception):
@@ -33,10 +39,40 @@
 class PDLParser :
     """Generic PDL parser."""
-    def __init__(self, infile, debug=0) :
+    def __init__(self, infile, debug=0, firstblock=None, lastblock=None) :
         """Initialize the generic parser."""
+        self.infile = infile
         self.debug = debug
-        self.infile = infile
-                
-    def getJobSize(self) :            
-        """Counts pages in the document."""
+        if firstblock is None :
+            self.infile.seek(0)
+            firstblock = self.infile.read(FIRSTBLOCKSIZE)
+            try :
+                self.infile.seek(-LASTBLOCKSIZE, 2)
+                lastblock = self.infile.read(LASTBLOCKSIZE)
+            except IOError :    
+                lastblock = ""
+            self.infile.seek(0)
+        self.firstblock = firstblock
+        self.lastblock = lastblock
+        if not self.isValid() :
+            raise PDLParserError, "Invalid file format !"
+        try :
+            import psyco 
+        except ImportError :    
+            sys.stderr.write("WARN: you should install psyco if possible, this would greatly speedup parsing.\n")
+            pass # Psyco is not installed
+        else :    
+            # Psyco is installed, tell it to compile
+            # the CPU intensive methods : PCL and PCLXL
+            # parsing will greatly benefit from this, 
+            # for PostScript and PDF the difference is
+            # barely noticeable since they are already
+            # almost optimal, and much more speedy anyway.
+            psyco.bind(self.getJobSize)
+            
+    def isValid(self) :    
+        """Returns 1 if data is in the expected format, else 0."""
         raise RuntimeError, "Not implemented !"
+        
+    def getJobSize(self) :    
+        """Counts pages in a document."""
+        raise RuntimeError, "Not implemented !"
Index: pkpgcounter/trunk/pdlanalyzer/dvi.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/dvi.py (revision 218)
+++ pkpgcounter/trunk/pdlanalyzer/dvi.py (revision 220)
@@ -29,6 +29,18 @@
 from pdlanalyzer import pdlparser
 
-class DVIParser(pdlparser.PDLParser) :
+class Parser(pdlparser.PDLParser) :
     """A parser for DVI documents."""
+    def isValid(self) :        
+        """Returns 1 if data is DVI, else 0."""
+        try :
+            if (ord(self.firstblock[0]) == 0xf7) and (ord(self.lastblock[-1]) == 0xdf) :
+                if self.debug :  
+                    sys.stderr.write("DEBUG: Input file is in the DVI format.\n")
+                return 1
+            else :    
+                return 0
+        except IndexError :          
+            return 0
+            
     def getJobSize(self) :
         """Counts pages in a DVI document.
@@ -74,5 +86,5 @@
             mustclose = 1
         try :
-            parser = DVIParser(infile, debug=1)
+            parser = Parser(infile, debug=1)
             totalsize += parser.getJobSize()
         except pdlparser.PDLParserError, msg :    
Index: pkpgcounter/trunk/pdlanalyzer/pclxl.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/pclxl.py (revision 211)
+++ pkpgcounter/trunk/pdlanalyzer/pclxl.py (revision 220)
@@ -29,5 +29,5 @@
 from pdlanalyzer import pdlparser
 
-class PCLXLParser(pdlparser.PDLParser) :
+class Parser(pdlparser.PDLParser) :
     """A parser for PCLXL (aka PCL6) documents."""
     mediasizes = { 
@@ -70,4 +70,16 @@
                    }
             
+    def isValid(self) :    
+        """Returns 1 if data is PCLXL aka PCL6, else 0."""
+        if ((self.firstblock[:128].find("\033%-12345X") != -1) and \
+             (self.firstblock.find(" HP-PCL XL;") != -1) and \
+             ((self.firstblock.find("LANGUAGE=PCLXL") != -1) or \
+              (self.firstblock.find("LANGUAGE = PCLXL") != -1))) :
+            if self.debug :  
+                sys.stderr.write("DEBUG: Input file is in the PCLXL (aka PCL6) format.\n")
+            return 1
+        else :    
+            return 0
+            
     def beginPage(self) :
         """Indicates the beginning of a new page, and extracts media information."""
@@ -371,5 +383,5 @@
             mustclose = 1
         try :
-            parser = PCLXLParser(infile, debug=1)
+            parser = Parser(infile, debug=1)
             totalsize += parser.getJobSize()
         except pdlparser.PDLParserError, msg :    
Index: pkpgcounter/trunk/pdlanalyzer/analyzer.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/analyzer.py (revision 217)
+++ pkpgcounter/trunk/pdlanalyzer/analyzer.py (revision 220)
@@ -25,8 +25,4 @@
 from pdlanalyzer import version, pdlparser, postscript, pdf, pcl345, pclxl, escp2, dvi, tiff
 
-KILOBYTE = 1024    
-MEGABYTE = 1024 * KILOBYTE    
-LASTBLOCKSIZE = int(KILOBYTE / 4)
-
 class PDLAnalyzer :    
     """Class for PDL autodetection."""
@@ -40,23 +36,4 @@
         self.debug = debug
         self.filename = filename
-        try :
-            import psyco 
-        except ImportError :    
-            sys.stderr.write("pkpgcounter : you should install psyco if possible, this would greatly speedup parsing.\n")
-            pass # Psyco is not installed
-        else :    
-            # Psyco is installed, tell it to compile
-            # the CPU intensive methods : PCL and PCLXL
-            # parsing will greatly benefit from this, 
-            # for PostScript and PDF the difference is
-            # barely noticeable since they are already
-            # almost optimal, and much more speedy anyway.
-            psyco.bind(postscript.PostScriptParser.getJobSize)
-            psyco.bind(pdf.PDFParser.getJobSize)
-            psyco.bind(escp2.ESCP2Parser.getJobSize)
-            psyco.bind(pcl345.PCL345Parser.getJobSize)
-            psyco.bind(pclxl.PCLXLParser.getJobSize)
-            psyco.bind(dvi.DVIParser.getJobSize)
-            psyco.bind(tiff.TIFFParser.getJobSize)
         
     def getJobSize(self) :    
@@ -67,8 +44,8 @@
         except pdlparser.PDLParserError, msg :    
             self.closeFile()
-            raise pdlparser.PDLParserError, "ERROR : Unknown file format for %s (%s)" % (self.filename, msg)
+            raise pdlparser.PDLParserError, "Unknown file format for %s (%s)" % (self.filename, msg)
         else :
             try :
-                size = pdlhandler(self.infile, self.debug).getJobSize()
+                size = pdlhandler.getJobSize()
             finally :    
                 self.closeFile()
@@ -93,5 +70,5 @@
         self.infile = tempfile.TemporaryFile(mode="w+b")
         while 1 :
-            data = infile.read(MEGABYTE) 
+            data = infile.read(pdlparser.MEGABYTE) 
             if not data :
                 break
@@ -114,88 +91,4 @@
                 pass    # probably stdin, which is not seekable
         
-    def isPostScript(self, sdata, edata) :    
-        """Returns 1 if data is PostScript, else 0."""
-        if sdata.startswith("%!") or \
-           sdata.startswith("\004%!") or \
-           sdata.startswith("\033%-12345X%!PS") or \
-           ((sdata[:128].find("\033%-12345X") != -1) and \
-             ((sdata.find("LANGUAGE=POSTSCRIPT") != -1) or \
-              (sdata.find("LANGUAGE = POSTSCRIPT") != -1) or \
-              (sdata.find("LANGUAGE = Postscript") != -1))) or \
-              (sdata.find("%!PS-Adobe") != -1) :
-            if self.debug :  
-                sys.stderr.write("%s is a PostScript file\n" % str(self.filename))
-            return 1
-        else :    
-            return 0
-        
-    def isPDF(self, sdata, edata) :    
-        """Returns 1 if data is PDF, else 0."""
-        if sdata.startswith("%PDF-") or \
-           sdata.startswith("\033%-12345X%PDF-") or \
-           ((sdata[:128].find("\033%-12345X") != -1) and (sdata.upper().find("LANGUAGE=PDF") != -1)) or \
-           (sdata.find("%PDF-") != -1) :
-            if self.debug :  
-                sys.stderr.write("%s is a PDF file\n" % str(self.filename))
-            return 1
-        else :    
-            return 0
-        
-    def isPCL(self, sdata, edata) :    
-        """Returns 1 if data is PCL, else 0."""
-        if sdata.startswith("\033E\033") or \
-           (sdata.startswith("\033*rbC") and (not edata[-3:] == "\f\033@")) or \
-           sdata.startswith("\033%8\033") or \
-           (sdata.find("\033%-12345X") != -1) :
-            if self.debug :  
-                sys.stderr.write("%s is a PCL3/4/5 file\n" % str(self.filename))
-            return 1
-        else :    
-            return 0
-        
-    def isPCLXL(self, sdata, edata) :    
-        """Returns 1 if data is PCLXL aka PCL6, else 0."""
-        if ((sdata[:128].find("\033%-12345X") != -1) and \
-             (sdata.find(" HP-PCL XL;") != -1) and \
-             ((sdata.find("LANGUAGE=PCLXL") != -1) or \
-              (sdata.find("LANGUAGE = PCLXL") != -1))) :
-            if self.debug :  
-                sys.stderr.write("%s is a PCLXL (aka PCL6) file\n" % str(self.filename))
-            return 1
-        else :    
-            return 0
-            
-    def isESCP2(self, sdata, edata) :        
-        """Returns 1 if data is ESC/P2, else 0."""
-        if sdata.startswith("\033@") or \
-           sdata.startswith("\033*") or \
-           sdata.startswith("\n\033@") or \
-           sdata.startswith("\0\0\0\033\1@EJL") : # ESC/P Raster ??? Seen on Stylus Photo 1284
-            if self.debug :  
-                sys.stderr.write("%s is an ESC/P2 file\n" % str(self.filename))
-            return 1
-        else :    
-            return 0
-            
-    def isDVI(self, sdata, edata) :        
-        """Returns 1 if data is DVI, else 0."""
-        if (ord(sdata[0]) == 0xf7) and (ord(edata[-1]) == 0xdf) :
-            if self.debug :  
-                sys.stderr.write("%s is a DVI file\n" % str(self.filename))
-            return 1
-        else :    
-            return 0
-            
-    def isTIFF(self, sdata, edata) :        
-        """Returns 1 if data is TIFF, else 0."""
-        littleendian = (chr(0x49)*2) + chr(0x2a) + chr(0)
-        bigendian = (chr(0x4d)*2) + chr(0) + chr(0x2a)
-        if sdata[:4] in (littleendian, bigendian) :
-            if self.debug :  
-                sys.stderr.write("%s is a TIFF file\n" % str(self.filename))
-            return 1
-        else :    
-            return 0
-    
     def detectPDLHandler(self) :    
         """Tries to autodetect the document format.
@@ -203,30 +96,28 @@
            Returns the correct PDL handler class or None if format is unknown
         """   
-        # Try to detect file type by reading first block of datas    
+        # Try to detect file type by reading first and last blocks of datas    
+        # Each parser can read them automatically, but here we do this only once.
         self.infile.seek(0)
-        firstblock = self.infile.read(16 * KILOBYTE)
+        firstblock = self.infile.read(pdlparser.FIRSTBLOCKSIZE)
         try :
-            self.infile.seek(-LASTBLOCKSIZE, 2)
-            lastblock = self.infile.read(LASTBLOCKSIZE)
+            self.infile.seek(-pdlparser.LASTBLOCKSIZE, 2)
+            lastblock = self.infile.read(pdlparser.LASTBLOCKSIZE)
         except IOError :    
             lastblock = ""
         self.infile.seek(0)
         if not firstblock :
-            sys.stderr.write("ERROR: input file %s is empty !\n" % str(self.filename))
+            raise pdlparser.PDLParserError, "input file %s is empty !" % str(self.filename)
         else :    
-            if self.isPostScript(firstblock, lastblock) :
-                return postscript.PostScriptParser
-            elif self.isPCLXL(firstblock, lastblock) :    
-                return pclxl.PCLXLParser
-            elif self.isPDF(firstblock, lastblock) :    
-                return pdf.PDFParser
-            elif self.isPCL(firstblock, lastblock) :    
-                return pcl345.PCL345Parser
-            elif self.isESCP2(firstblock, lastblock) :    
-                return escp2.ESCP2Parser
-            elif self.isDVI(firstblock, lastblock) :    
-                return dvi.DVIParser
-            elif self.isTIFF(firstblock, lastblock) :
-                return tiff.TIFFParser
+            for module in (postscript, \
+                           pclxl, \
+                           pdf, \
+                           pcl345, \
+                           escp2, \
+                           dvi, \
+                           tiff) :
+                try :               
+                    return getattr(module, "Parser")(self.infile, self.debug, firstblock, lastblock)
+                except pdlparser.PDLParserError :
+                    pass # try next parser
         raise pdlparser.PDLParserError, "Analysis of first data block failed."
             
Index: pkpgcounter/trunk/pdlanalyzer/version.py
===================================================================
--- pkpgcounter/trunk/pdlanalyzer/version.py (revision 217)
+++ pkpgcounter/trunk/pdlanalyzer/version.py (revision 220)
@@ -20,5 +20,5 @@
 #
 
-__version__ = "1.52"
+__version__ = "1.53"
 
 __doc__ = """pkpgcounter : a generic Page Description Languages parser."""
