root / pkpgcounter / trunk / pkpgpdls / lidil.py @ 3488

Revision 3474, 4.0 kB (checked in by jerome, 16 years ago)

Changed copyright years.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1# -*- coding: utf-8 -*-
2#
3# pkpgcounter : a generic Page Description Language parser
4#
5# (c) 2003-2009 Jerome Alet <alet@librelogiciel.com>
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18#
19# $Id$
20#
21
22"""This modules implements a page counter for HP LIDIL format.
23
24   Documentation used :
25
26        hplip-2.7.10/prnt/ldl.py
27        hplip-2.7.10/prnt/hpijs/ldlencap.h
28"""
29
30import struct
31
32import pdlparser
33
34HEADERSIZE = 10 # LIDIL header is 10 bytes long
35
36# Packet types taken from hplip-2.7.10/prnt/ldl.py
37PACKET_TYPE_COMMAND = 0
38PACKET_TYPE_DISABLE_PACING = 1
39PACKET_TYPE_ENABLE_PACING = 2
40PACKET_TYPE_RESUME_NORMAL_OPERATION = 3
41PACKET_TYPE_DISABLE_RESPONSES = 4
42PACKET_TYPE_ENABLE_RESPONSES = 5
43PACKET_TYPE_RESET_LIDIL = 6
44PACKET_TYPE_SYNC = 7
45PACKET_TYPE_SYNC_COMPLETE = 8
46
47# Command codes we are interested in.
48LDL_LOAD_PAGE = 1
49LDL_EJECT_PAGE = 2
50
51class Parser(pdlparser.PDLParser) :
52    """A parser for HP LIDIL documents."""
53    format = "Hewlett-Packard LIDIL"
54    def isValid(self) :
55        """Returns True if data is LIDIL, else False."""
56        # Beginning Of File marker is a Sync packet, followed with
57        # a Sync Complete packet followed with a Reset packet.
58        # We just look at the start of the Sync packet for simplicity's sake.
59        BOFMarker = "$\x01\x00\x00\x07"
60        # End Of File marker is a Sync Complete packet followed
61        # with a Reset packet. We ignore the preceding Sync packet
62        # for simplicity's sake.
63        EOFMarker = "$\x00\x10\x00\x08\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff$$\x00\x10\x00\x06\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff$"
64        if self.firstblock.startswith(BOFMarker) \
65           and self.lastblock.endswith(EOFMarker) :
66            return True
67        else :
68            return False
69
70    def getJobSize(self) :
71        """Computes the number of pages in a HP LIDIL document."""
72        unpack = struct.unpack
73        ejectpage = loadpage = 0
74        try :
75            while True :
76                header = self.infile.read(HEADERSIZE)
77                if not header :
78                    break
79                if (len(header) != HEADERSIZE) or (header[0] != "$") :
80                    # Invalid header or no Frame Sync byte.
81                    raise pdlparser.PDLParserError, "This file doesn't seem to be valid Hewlett-Packard LIDIL datas."
82                (framesync,
83                 cmdlength,
84                 dummy,
85                 packettype,
86                 commandnumber,
87                 referencenumber,
88                 datalength) = unpack(">BHBBBHH", header)
89                if packettype == PACKET_TYPE_COMMAND :
90                    if commandnumber == LDL_LOAD_PAGE :
91                        loadpage += 1
92                    elif commandnumber == LDL_EJECT_PAGE :
93                        ejectpage += 1
94                self.infile.seek(cmdlength + datalength - len(header), 1) # relative seek
95        except struct.error :
96            raise pdlparser.PDLParserError, "This file doesn't seem to be valid Hewlett-Packard LIDIL datas."
97
98        # Number of page eject commands should be sufficient,
99        # but we never know : someone could try to cheat the printer
100        # by loading a page but not ejecting it, and ejecting it manually
101        # later on. Not sure if the printers would support this, but
102        # taking the max value works around the problem in any case.
103        self.logdebug("Load : %i    Eject : %i" % (loadpage, ejectpage))
104        return max(loadpage, ejectpage)
Note: See TracBrowser for help on using the browser.