Index: pykota/trunk/pykota/pdlanalyzer.py
===================================================================
--- pykota/trunk/pykota/pdlanalyzer.py (revision 1574)
+++ pykota/trunk/pykota/pdlanalyzer.py (revision 1575)
@@ -22,4 +22,7 @@
 #
 # $Log$
+# Revision 1.19  2004/06/28 21:20:30  jalet
+# PCLXL support now works !
+#
 # Revision 1.18  2004/06/27 22:59:37  jalet
 # More work on PCLXL parser
@@ -256,5 +259,5 @@
     def __init__(self, infile) :
         """Initialize PCLXL Analyzer."""
-        raise PDLAnalyzerError, "PCLXL (aka PCL6) is not supported yet."
+        # raise PDLAnalyzerError, "PCLXL (aka PCL6) is not supported yet."
         self.infile = infile
         self.islittleendian = None
@@ -268,7 +271,9 @@
                 endian = ord(line[0])
                 if endian == 0x29 :
-                    self.littleendian()
+                    self.littleEndian()
                 elif endian == 0x28 :    
-                    self.bigendian()
+                    self.bigEndian()
+                # elif endian == 0x27 : TODO : What can we do here ?    
+                # 
                 else :    
                     raise PDLAnalyzerError, "No endianness marker 0x%02x at start !" % endian
@@ -276,25 +281,20 @@
             raise PDLAnalyzerError, "This file doesn't seem to be PCLXL (aka PCL6)"
         else :    
-            self.tags = [ self.skipped ] * 256    
-            self.tags[0x27] = lambda: self.debug("%08x : ASCII Binding" % self.infile.tell())
-            self.tags[0x28] = self.bigendian 
-            self.tags[0x29] = self.littleendian
-            
-            self.tags[0x41] = lambda: self.debug("%08x : BeginSession" % self.infile.tell())
-            self.tags[0x42] = lambda: self.debug("%08x : EndSession" % self.infile.tell())
+            # Initialize table of tags
+            self.tags = [ 0 ] * 256    
+            
+            # GhostScript's sources tell us that HP printers
+            # only accept little endianness, but we can handle both.
+            self.tags[0x28] = self.bigEndian    # BigEndian
+            self.tags[0x29] = self.littleEndian # LittleEndian
             
             self.tags[0x43] = self.beginPage    # BeginPage
-            self.tags[0x44] = self.endPage      # EndPage
-            
-            self.tags[0x47] = lambda: self.debug("%08x : Comment" % self.infile.tell())
-            self.tags[0x48] = lambda: self.debug("%08x : OpenDataSource" % self.infile.tell())
-            self.tags[0x49] = lambda: self.debug("%08x : CloseDataSource" % self.infile.tell())
-            
-            self.tags[0xc0] = lambda: self.debug("%08x : ubyte" % self.infile.tell()) or 1 # ubyte
-            self.tags[0xc1] = lambda: self.debug("%08x : uint16" % self.infile.tell()) or 2 # uint16
-            self.tags[0xc2] = lambda: self.debug("%08x : uint32" % self.infile.tell()) or 4 # uint32
-            self.tags[0xc3] = lambda: self.debug("%08x : sint16" % self.infile.tell()) or 2 # sint16
-            self.tags[0xc4] = lambda: self.debug("%08x : sint32" % self.infile.tell()) or 4 # sint32
-            self.tags[0xc5] = lambda: self.debug("%08x : real32" % self.infile.tell()) or 4 # real32
+            
+            self.tags[0xc0] = 1 # ubyte
+            self.tags[0xc1] = 2 # uint16
+            self.tags[0xc2] = 4 # uint32
+            self.tags[0xc3] = 2 # sint16
+            self.tags[0xc4] = 4 # sint32
+            self.tags[0xc5] = 4 # real32
             
             self.tags[0xc8] = self.array_8  # ubyte_array
@@ -305,133 +305,115 @@
             self.tags[0xcd] = self.array_32 # real32_array
             
-            self.tags[0xd0] = lambda: self.debug("%08x : ubyte_xy" % self.infile.tell()) or 2 # ubyte_xy
-            self.tags[0xd1] = lambda: self.debug("%08x : uint16_xy" % self.infile.tell()) or 4 # uint16_xy
-            self.tags[0xd2] = lambda: self.debug("%08x : uint32_xy" % self.infile.tell()) or 8 # uint32_xy
-            self.tags[0xd3] = lambda: self.debug("%08x : sint16_xy" % self.infile.tell()) or 4 # sint16_xy
-            self.tags[0xd4] = lambda: self.debug("%08x : sint32_xy" % self.infile.tell()) or 8 # sint32_xy
-            self.tags[0xd5] = lambda: self.debug("%08x : real32_xy" % self.infile.tell()) or 8 # real32_xy
-            
-            self.tags[0xd0] = lambda: self.debug("%08x : ubyte_box" % self.infile.tell()) or 4  # ubyte_box
-            self.tags[0xd1] = lambda: self.debug("%08x : uint16_box" % self.infile.tell()) or 8  # uint16_box
-            self.tags[0xd2] = lambda: self.debug("%08x : uint32_box" % self.infile.tell()) or 16 # uint32_box
-            self.tags[0xd3] = lambda: self.debug("%08x : sint16_box" % self.infile.tell()) or 8  # sint16_box
-            self.tags[0xd4] = lambda: self.debug("%08x : sint32_box" % self.infile.tell()) or 16 # sint32_box
-            self.tags[0xd5] = lambda: self.debug("%08x : real32_box" % self.infile.tell()) or 16 # real32_box
-            
-            self.tags[0xf8] = lambda: self.debug("%08x : attr_ubyte" % self.infile.tell()) or 1 # attr_ubyte
-            self.tags[0xf9] = lambda: self.debug("%08x : attr_uint16" % self.infile.tell()) or 2 # attr_uint16
+            self.tags[0xd0] = 2 # ubyte_xy
+            self.tags[0xd1] = 4 # uint16_xy
+            self.tags[0xd2] = 8 # uint32_xy
+            self.tags[0xd3] = 4 # sint16_xy
+            self.tags[0xd4] = 8 # sint32_xy
+            self.tags[0xd5] = 8 # real32_xy
+            
+            self.tags[0xe0] = 4  # ubyte_box
+            self.tags[0xe1] = 8  # uint16_box
+            self.tags[0xe2] = 16 # uint32_box
+            self.tags[0xe3] = 8  # sint16_box
+            self.tags[0xe4] = 16 # sint32_box
+            self.tags[0xe5] = 16 # real32_box
+            
+            self.tags[0xf8] = 1 # attr_ubyte
+            self.tags[0xf9] = 2 # attr_uint16
             
             self.tags[0xfa] = self.embeddedData      # dataLength
             self.tags[0xfb] = self.embeddedDataSmall # dataLengthByte
             
-    def debug(self, msg) :
-        """Outputs a debug message on stderr."""
-        sys.stderr.write("%s\n" % msg)
-        sys.stderr.flush()
-        
-    def skipped(self) :    
-        """Skips a byte."""
-        self.debug("%08x : skip" % self.infile.tell())
-        
     def beginPage(self) :
         """Indicates the beginning of a new page."""
         self.pagecount += 1
-        self.debug("%08x : beginPage (%i)" % (self.infile.tell(), self.pagecount))
-        
-    def endPage(self) :
-        """Indicates the end of a page."""
-        self.debug("%08x : endPage (%i)" % (self.infile.tell(), self.pagecount))
+        return 0
         
     def handleArray(self, itemsize) :        
         """Handles arrays."""
-        pos = self.infile.tell()
-        datatype = self.infile.read(1)
-        self.debug("%08x : Array of datatype 0x%02x" % (pos, ord(datatype)))
-        length = self.tags[ord(datatype)]()
+        datatype = self.minfile[self.pos]
+        self.pos += 1
+        length = self.tags[ord(datatype)]
         if length is None :
-            self.debug("Bogus array length at %s" % pos)
-        else :    
-            sarraysize = self.infile.read(length)
-            if self.islittleendian :
-                fmt = "<"
-            else :    
-                fmt = ">"
-            if length == 1 :    
-                fmt += "B"
-            elif length == 2 :    
-                fmt += "H"
-            elif length == 4 :    
-                fmt += "I"
-            else :    
-                raise PDLAnalyzerError, "Error on array size at %s" % self.infile.tell()
-            arraysize = struct.unpack(fmt, sarraysize)[0]
-            self.debug("itemsize %s * size %s = %s" % (itemsize, arraysize, itemsize*arraysize))
-            return arraysize * itemsize
+            raise PDLAnalyzerError, "Error on array length at %s" % self.pos
+        elif callable(length) :
+            length = length()
+        pos = self.pos    
+        posl = pos + length
+        sarraysize = self.minfile[pos:posl]
+        self.pos = posl
+        if self.islittleendian :
+            fmt = "<"
+        else :    
+            fmt = ">"
+        if length == 1 :    
+            fmt += "B"
+        elif length == 2 :    
+            fmt += "H"
+        elif length == 4 :    
+            fmt += "I"
+        else :    
+            raise PDLAnalyzerError, "Error on array size at %s" % self.pos
+        arraysize = struct.unpack(fmt, sarraysize)[0]
+        return arraysize * itemsize
         
     def array_8(self) :    
         """Handles byte arrays."""
-        self.debug("%08x : array_8" % self.infile.tell())
         return self.handleArray(1)
         
     def array_16(self) :    
         """Handles byte arrays."""
-        self.debug("%08x : array_16" % self.infile.tell())
         return self.handleArray(2)
         
     def array_32(self) :    
         """Handles byte arrays."""
-        self.debug("%08x : array_32" % self.infile.tell())
         return self.handleArray(4)
         
     def embeddedDataSmall(self) :
         """Handle small amounts of data."""
-        self.debug("%08x : small_datablock" % self.infile.tell())
-        pos = self.infile.tell()
-        val = ord(self.infile.read(1))
-        self.debug("%08x : Small datablock length : 0x%02x" % (self.infile.tell()-1, val))
-        return val
+        length = ord(self.minfile[self.pos])
+        self.pos += 1
+        return length
         
     def embeddedData(self) :
         """Handle normal amounts of data."""
-        self.debug("%08x : large_datablock" % self.infile.tell())
         if self.islittleendian :
             fmt = "<I"
         else :    
             fmt = ">I"
-        pos = self.infile.tell()
-        data = self.infile.read(4)
-        val = struct.unpack(fmt, data)[0]
-        if val & 0xff000000 : # tries to detect possible errors when we missed an indianness tag maybe
-            if fmt == "<I" :
-                fmt = ">I"
-            else :    
-                fmt = "<I"
-            val = struct.unpack(fmt, data)[0]
-        self.debug("%08x : Large datablock length : 0x%08x" % (self.infile.tell()-4, val))
-        self.debug("Endian : %i" % self.islittleendian) 
-        self.debug("Data read : %s" % str(["0x%02x" % ord(x) for x in data]))
-        return val
-        
-    def littleendian(self) :        
+        pos = self.pos
+        pos4 = pos + 4
+        data = self.minfile[pos:pos4]
+        self.pos = pos4
+        return struct.unpack(fmt, data)[0]
+        
+    def littleEndian(self) :        
         """Toggles to little endianness."""
-        self.debug("%08x : littleendian" % self.infile.tell())
         self.islittleendian = 1 # little endian
-        
-    def bigendian(self) :    
+        return 0
+        
+    def bigEndian(self) :    
         """Toggles to big endianness."""
-        self.debug("%08x : bigendian" % self.infile.tell())
         self.islittleendian = 0 # big endian
+        return 0
     
     def getJobSize(self) :
         """Counts pages in a PCLXL (PCL6) document."""
+        infileno = self.infile.fileno()
+        self.minfile = mmap.mmap(infileno, os.fstat(infileno).st_size, access=mmap.ACCESS_READ)
         self.pagecount = 0
-        while 1 :
-            char = self.infile.read(1)
-            if not char :
-                break
-            index = ord(char)    
-            length = self.tags[index]()
-            if length :    
-                self.infile.read(length)    
+        self.pos = self.infile.tell()
+        try :
+            while 1 :
+                char = self.minfile[self.pos]
+                self.pos += 1
+                length = self.tags[ord(char)]
+                if not length :    
+                    continue
+                if callable(length) :    
+                    length = length()
+                self.pos += length    
+        except IndexError : # EOF ?
+            self.minfile.close() # reached EOF
         return self.pagecount
         
Index: pykota/trunk/pykota/version.py
===================================================================
--- pykota/trunk/pykota/version.py (revision 1570)
+++ pykota/trunk/pykota/version.py (revision 1575)
@@ -22,5 +22,5 @@
 #
 
-__version__ = "1.19alpha27_unofficial"
+__version__ = "1.19alpha28_unofficial"
 
 __doc__ = """PyKota : a complete Printing Quota Solution for CUPS and LPRng."""
