Changeset 631

Show
Ignore:
Timestamp:
05/13/05 23:48:18 (20 years ago)
Author:
jerome
Message:

Improved the IPP parser

Location:
tea4cups/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • tea4cups/trunk/NEWS

    r630 r631  
    2424  * 2.12alpha : 
    2525   
     26    - Greatly improved the IPP parser. 
     27     
    2628    - When printing test pages from CUPS' web interface, the empty username 
    2729      is now overwritten with the username CUPS is running as. 
  • tea4cups/trunk/tea4cups

    r630 r631  
    9191class IPPMessage : 
    9292    """A class for IPP message files.""" 
    93     def __init__(self, data) : 
     93    def __init__(self, data, debug=0) : 
    9494        """Initializes an IPP Message object.""" 
     95        self.debug = debug 
    9596        self.data = data 
    96         self._attributes = {} 
    97         self.curname = None 
     97        self.operation_attributes = {} 
     98        self.job_attributes = {} 
     99        self.printer_attributes = {} 
    98100        self.tags = [ None ] * 256      # by default all tags reserved 
    99101         
     
    141143        self.parse() 
    142144         
    143     def __getattr__(self, attrname) :     
    144         """Allows self.attributes to return the attributes names.""" 
    145         if attrname == "attributes" : 
    146             keys = self._attributes.keys() 
    147             keys.sort() 
    148             return keys 
    149         raise AttributeError, attrname 
    150              
    151     def __getitem__(self, ippattrname) :     
    152         """Fakes a dictionnary d['key'] notation.""" 
    153         value = self._attributes.get(ippattrname) 
    154         if value is not None : 
    155             if len(value) == 1 : 
    156                 value = value[0] 
    157         return value         
    158     get = __getitem__     
    159          
    160145    def parseTag(self) :     
    161146        """Extracts information from an IPP tag.""" 
    162147        pos = self.position 
    163148        valuetag = self.tags[ord(self.data[pos])] 
    164         # print valuetag.get("name") 
    165149        pos += 1 
    166150        posend = pos2 = pos + 2 
    167151        namelength = unpack(">H", self.data[pos:pos2])[0] 
    168152        if not namelength : 
    169             name = self.curname 
     153            name = self._curname 
    170154        else :     
    171155            posend += namelength 
    172             self.curname = name = self.data[pos2:posend] 
     156            self._curname = name = self.data[pos2:posend] 
    173157        pos2 = posend + 2 
    174158        valuelength = unpack(">H", self.data[posend:pos2])[0] 
    175159        posend = pos2 + valuelength 
    176160        value = self.data[pos2:posend] 
    177         oldval = self._attributes.setdefault(name, []) 
    178         oldval.append(value) 
     161        oldval = self._curdict.setdefault(name, []) 
     162        oldval.append((valuetag, value)) 
     163        self.printInfo("%s(%s) %s" % (name, valuetag, value)) 
    179164        return posend - self.position 
    180165         
    181166    def operation_attributes_tag(self) :  
    182167        """Indicates that the parser enters into an operation-attributes-tag group.""" 
     168        self.printInfo("Start of operation_attributes_tag") 
     169        self._curdict = self.operation_attributes 
    183170        return self.parseTag() 
    184171         
    185172    def job_attributes_tag(self) :  
    186         """Indicates that the parser enters into a job-attributes-tag group.""" 
     173        """Indicates that the parser enters into an operation-attributes-tag group.""" 
     174        self.printInfo("Start of job_attributes_tag") 
     175        self._curdict = self.job_attributes 
    187176        return self.parseTag() 
    188177         
    189178    def printer_attributes_tag(self) :  
    190         """Indicates that the parser enters into a printer-attributes-tag group.""" 
     179        """Indicates that the parser enters into an operation-attributes-tag group.""" 
     180        self.printInfo("Start of printer_attributes_tag") 
     181        self._curdict = self.printer_attributes 
    191182        return self.parseTag() 
    192183         
     184    def printInfo(self, msg) :     
     185        """Prints a debug message.""" 
     186        if self.debug : 
     187            sys.stderr.write("%s\n" % msg) 
     188            sys.stderr.flush() 
     189             
    193190    def parse(self) : 
    194191        """Parses an IPP Message. 
     
    197194           We are only interested in textual informations for now anyway. 
    198195        """ 
     196        self._curname = None 
     197        self._curdict = None 
    199198        self.version = "%s.%s" % (ord(self.data[0]), ord(self.data[1])) 
    200199        self.operation_id = "0x%04x" % unpack(">H", self.data[2:4])[0] 
     
    216215        except IndexError : 
    217216            raise IPPError, "Unexpected end of IPP message." 
     217             
     218        # Now transform all one-element lists into single values 
     219        for attrtype in ("operation", "job", "printer") : 
     220            attrdict = getattr(self, "%s_attributes" % attrtype) 
     221            for (key, value) in attrdict.items() : 
     222                if len(value) == 1 : 
     223                    attrdict[key] = value[0] 
    218224             
    219225class FakeConfig :     
     
    423429        (ippfilename, ippmessage) = self.parseIPPMessageFile() 
    424430        self.ControlFile = ippfilename 
    425         self.ClientHost = ippmessage.get("job-originating-host-name") 
    426         self.JobBilling = ippmessage.get("job-billing") 
     431        (chtype, self.ClientHost) = ippmessage.operation_attributes.get("job-originating-host-name", \ 
     432                                          ippmessage.job_attributes.get("job-originating-host-name", (None, None))) 
     433        (jbtype, self.JobBilling) = ippmessage.job_attributes.get("job-billing", (None, None)) 
    427434             
    428435    def getCupsConfigDirectives(self, directives=[]) :