Changeset aaa1da3


Ignore:
Timestamp:
Nov 6, 2010, 9:20:53 PM (13 years ago)
Author:
Jessica B. Hamrick <jhamrick@…>
Branches:
no-cups
Children:
89fe6da
Parents:
8e43aa8
git-author:
Jessica B. Hamrick <jhamrick@…> (11/06/10 21:20:53)
git-committer:
Jessica B. Hamrick <jhamrick@…> (11/06/10 21:20:53)
Message:

Add support for parsing different value tags

File:
1 edited

Legend:

Unmodified
Added
Removed
  • server/lib/ipprequest.py

    r8e43aa8 raaa1da3  
    3737    RESOLUTION                        = 0x32
    3838    RANGE_OF_INTEGER                  = 0x33
    39     COLLECTION                        = 0x34
    4039    TEXT_WITH_LANGUAGE                = 0x35
    4140    NAME_WITH_LANGUAGE                = 0x36
     
    8988        self.value = value
    9089
     90        # out-of-band value tags
     91        if self.value_tag == IPPTags.UNSUPPORTED or \
     92               self.value_tag == IPPTags.DEFAULT or \
     93               self.value_tag == IPPTags.UNKNOWN or \
     94               self.value_tag == IPPTags.NO_VALUE:
     95            self.value = ''
     96
     97        # integer value tags
     98        elif self.value_tag == IPPTags.GENERIC_INTEGER:
     99            pass # not supported
     100        elif self.value_tag == IPPTags.INTEGER:
     101            self.value = struct.unpack('>i', value)[0]
     102        elif self.value_tag == IPPTags.BOOLEAN:
     103            self.value = struct.unpack('>?', value)[0]
     104        elif self.value_tag == IPPTags.ENUM:
     105            self.value = struct.unpack('>i', value)[0]
     106
     107        # octet string value tags
     108        elif self.value_tag == IPPTags.UNSPECIFIED_OCTETSTRING:
     109            pass
     110       
     111        elif self.value_tag == IPPTags.DATETIME:
     112            # field  octets  contents                  range
     113            # -----  ------  --------                  -----
     114            #   1      1-2   year                      0..65536
     115            #   2       3    month                     1..12
     116            #   3       4    day                       1..31
     117            #   4       5    hour                      0..23
     118            #   5       6    minutes                   0..59
     119            #   6       7    seconds                   0..60
     120            #                (use 60 for leap-second)
     121            #   7       8    deci-seconds              0..9
     122            #   8       9    direction from UTC        '+' / '-'
     123            #   9      10    hours from UTC            0..11
     124            #  10      11    minutes from UTC          0..59
     125
     126            self.value = struct.unpack('>hbbbbbbcbb', value)[0]
     127           
     128        elif self.value_tag == IPPTags.RESOLUTION:
     129            # OCTET-STRING consisting of nine octets of 2
     130            # SIGNED-INTEGERs followed by a SIGNED-BYTE. The first
     131            # SIGNED-INTEGER contains the value of cross feed
     132            # direction resolution. The second SIGNED-INTEGER contains
     133            # the value of feed direction resolution. The SIGNED-BYTE
     134            # contains the units
     135
     136            self.value = struct.unpack('>iib', value)
     137           
     138        elif self.value_tag == IPPTags.RANGE_OF_INTEGER:
     139            # Eight octets consisting of 2 SIGNED-INTEGERs.  The first
     140            # SIGNED-INTEGER contains the lower bound and the second
     141            # SIGNED-INTEGER contains the upper bound.
     142
     143            self.value = struct.unpack('>ii', value)
     144
     145        elif self.value_tag == IPPTags.TEXT_WITH_LANGUAGE or \
     146                 self.value_tag == IPPTags.NAME_WITH_LANGUAGE:
     147            a = struct.unpack('>h', value[:2])[0]
     148            b = struct.unpack('>%ss' % a, value[2:a+2])[0]
     149            c = struct.unpack('>h', value[a+2:a+4])[0]
     150            d = struct.unpack('>%ss' % c, value[a+4:][0])
     151            self.value = (a, b, c, d)
     152
     153        # character string value tags
     154        elif self.value_tag == IPPTags.TEXT_WITHOUT_LANGUAGE or \
     155                 self.value_tag == IPPTags.NAME_WITHOUT_LANGUAGE:
     156            self.value = str(value)
     157        elif self.value_tag == IPPTags.GENERIC_CHAR_STRING or \
     158                 self.value_tag == IPPTags.KEYWORD or \
     159                 self.value_tag == IPPTags.URI or \
     160                 self.value_tag == IPPTags.URI_SCHEME or \
     161                 self.value_tag == IPPTags.CHARSET or \
     162                 self.value_tag == IPPTags.NATURAL_LANGUAGE or \
     163                 self.value_tag == IPPTags.MIME_MEDIA_TYPE:
     164            self.value = str(value)
     165
     166    def valueToBinary(self):
     167
     168        # out-of-band value tags
     169        if self.value_tag == IPPTags.UNSUPPORTED or \
     170               self.value_tag == IPPTags.DEFAULT or \
     171               self.value_tag == IPPTags.UNKNOWN or \
     172               self.value_tag == IPPTags.NO_VALUE:
     173            return (0, '')
     174
     175        # integer value tags
     176        elif self.value_tag == IPPTags.GENERIC_INTEGER:
     177            pass
     178        elif self.value_tag == IPPTags.INTEGER:
     179            return (4, struct.pack('>i', self.value))
     180        elif self.value_tag == IPPTags.BOOLEAN:
     181            return (1, struct.pack('>?', self.value))
     182        elif self.value_tag == IPPTags.ENUM:
     183            return (4, struct.pack('>i', self.value))
     184
     185        # octet string value tags
     186        elif self.value_tag == IPPTags.UNSPECIFIED_OCTETSTRING:
     187            pass
     188        elif self.value_tag == IPPTags.DATETIME:
     189            # field  octets  contents                  range
     190            # -----  ------  --------                  -----
     191            #   1      1-2   year                      0..65536
     192            #   2       3    month                     1..12
     193            #   3       4    day                       1..31
     194            #   4       5    hour                      0..23
     195            #   5       6    minutes                   0..59
     196            #   6       7    seconds                   0..60
     197            #                (use 60 for leap-second)
     198            #   7       8    deci-seconds              0..9
     199            #   8       9    direction from UTC        '+' / '-'
     200            #   9      10    hours from UTC            0..11
     201            #  10      11    minutes from UTC          0..59
     202           
     203            return (11, struct.pack('>hbbbbbbcbb', self.value))
     204           
     205        elif self.value_tag == IPPTags.RESOLUTION:
     206            # OCTET-STRING consisting of nine octets of 2
     207            # SIGNED-INTEGERs followed by a SIGNED-BYTE. The first
     208            # SIGNED-INTEGER contains the value of cross feed
     209            # direction resolution. The second SIGNED-INTEGER contains
     210            # the value of feed direction resolution. The SIGNED-BYTE
     211            # contains the units
     212           
     213            return (9, struct.pack('>iib', self.value))
     214           
     215        elif self.value_tag == IPPTags.RANGE_OF_INTEGER:
     216            # Eight octets consisting of 2 SIGNED-INTEGERs.  The first
     217            # SIGNED-INTEGER contains the lower bound and the second
     218            # SIGNED-INTEGER contains the upper bound.
     219           
     220            return (8, struct.pack('>ii', self.value))
     221
     222        elif self.value_tag == IPPTags.TEXT_WITH_LANGUAGE or \
     223                 self.value_tag == IPPTags.NAME_WITH_LANGUAGE:
     224            a_bin = struct.pack('>h', self.value[0])
     225            b_bin = struct.pack('>%ss' % self.value[0], self.value[1])
     226            c_bin = struct.pack('>h', self.value[2])
     227            d_bin = struct.pack('>%ss' % self.value[2], self.value[3])
     228            return (4 + self.value[0] + self.value[2],
     229                    a_bin + b_bin + c_bin + d_bin)
     230
     231        # character string value tags
     232        elif self.value_tag == IPPTags.TEXT_WITHOUT_LANGUAGE or \
     233                 self.value_tag == IPPTags.NAME_WITHOUT_LANGUAGE:
     234            return (len(self.value), struct.pack('>%ss' % len(self.value), self.value))
     235        elif self.value_tag == IPPTags.GENERIC_CHAR_STRING or \
     236                 self.value_tag == IPPTags.KEYWORD or \
     237                 self.value_tag == IPPTags.URI or \
     238                 self.value_tag == IPPTags.URI_SCHEME or \
     239                 self.value_tag == IPPTags.CHARSET or \
     240                 self.value_tag == IPPTags.NATURAL_LANGUAGE or \
     241                 self.value_tag == IPPTags.MIME_MEDIA_TYPE:
     242            return (len(self.value), struct.pack('>%ss' % len(self.value), self.value))
     243
     244        return len(self.value), self.value
     245
    91246class IPPAttribute():
    92247    """
     
    152307        values = []
    153308        for v, i in zip(self.values, xrange(len(self.values))):
    154             name_length = len(self.name)
    155             if i > 0: name_length = 0
    156             value_length = len(v.value)
     309
     310            # get the name length (0 for everything but the first
     311            # value)
     312            if i == 0:
     313                name_length = len(self.name)
     314            else:
     315                name_length = 0
     316
     317            # get the value length and binary value
     318            value_length, value_bin = v.valueToBinary()
    157319
    158320            logger.debug("dumping name_length : %i" % name_length)
     
    172334            # the value length in binary
    173335            value_length_bin = struct.pack('>h', value_length)
    174 
    175             # the value in binary
    176             value_bin = v.value
    177336
    178337            if i == 0:
     
    362521                        # read in the value (string of value_length bytes)
    363522                        value         = request.read(value_length)
    364                         logger.debug("value : %s" % value)
     523
     524                        ippvalue = IPPValue(value_tag, value)
     525                        logger.debug("value : %s" % ippvalue.value)
    365526
    366527                        # create a new IPPAttribute from the data we just
    367528                        # read in, and add it to our attributes list
    368                         attributes.append(IPPAttribute(name,
    369                                                        [IPPValue(value_tag, value)]))
     529                        attributes.append(IPPAttribute(name, [ippvalue]))
    370530
    371531                    else:
     
    376536                        # read in the value (string of value_length bytes)
    377537                        value         = request.read(value_length)
    378                         logger.debug("value : %s" % value)
     538
     539                        ippvalue = IPPValue(value_tag, value)
     540                        logger.debug("value : %s" % ippvalue.value)
    379541
    380542                        # add another value to the last attribute
    381                         attributes[-1].values.append(IPPValue(value_tag, value))
     543                        attributes[-1].values.append(ippvalue)
    382544
    383545                    # read another byte
Note: See TracChangeset for help on using the changeset viewer.