source: server/lib/gutenbach/ipp/attribute.py @ f6c6897

no-cups
Last change on this file since f6c6897 was f6c6897, checked in by Jessica B. Hamrick <jhamrick@…>, 12 years ago

Fix some errors in ipp/

  • Property mode set to 100644
File size: 5.1 KB
RevLine 
[7a1c039]1from .value import Value
[d04a689]2import sys
3import struct
4import logging
[8979f90]5
6# initialize logger
[7a1c039]7logger = logging.getLogger(__name__)
[8979f90]8
[fc427ef]9class Attribute(object):
[5c5fe6d]10    """In addition to what the RFC reports, an attribute has an
11    'attribute tag', which specifies what type of attribute it is.  It
12    is 1 bytes long, and comes before the list of values.
[8979f90]13
14    From RFC 2565:
15
16    Each attribute consists of:
17    -----------------------------------------------
18    |                   value-tag                 |   1 byte
19    -----------------------------------------------
20    |               name-length  (value is u)     |   2 bytes
21    -----------------------------------------------
22    |                     name                    |   u bytes
23    -----------------------------------------------
24    |              value-length  (value is v)     |   2 bytes
25    -----------------------------------------------
26    |                     value                   |   v bytes
27    -----------------------------------------------
28
29    An additional value consists of:
30    -----------------------------------------------------------
31    |                   value-tag                 |   1 byte  |
32    -----------------------------------------------           |
33    |            name-length  (value is 0x0000)   |   2 bytes |
34    -----------------------------------------------           |-0 or more
35    |              value-length (value is w)      |   2 bytes |
36    -----------------------------------------------           |
37    |                     value                   |   w bytes |
38    -----------------------------------------------------------
[5c5fe6d]39
[8979f90]40    """
41
[7a1c039]42    def __init__(self, name=None, values=None):
[5c5fe6d]43        """Initialize an Attribute.  This function can be called in
44        three different ways:
[c269bc7]45
46            Attribute() -- creates an empty Attribute
47
48            Attribute(name) -- creates an empty Attribute with a name
49
50            Attribute(name, values) -- creates an Attribute
51            initialized with a name and list of values
[8979f90]52       
53        Arguments:
54
55            name -- the name of the attribute
56
[ebf327d]57            values -- a list of Values.  May not be empty.
[5c5fe6d]58
[8979f90]59        """
60
[c269bc7]61        if name is not None:
62            assert isinstance(name, str), \
63                   "Attribute name must be a string!"
[7a1c039]64        if values is None:
65            values = []
[c269bc7]66        for value in values:
67            assert isinstance(value, Value), \
[f6c6897]68                   "Value %s must be of type Value" % (value,)
[c269bc7]69
[75c0cab]70        self.name = name
71        self.values = values
[c269bc7]72
[fc427ef]73    @property
74    def packed_value(self):
[5c5fe6d]75        """Packs the attribute data into binary data.
76       
[8979f90]77        """
78
[c269bc7]79        assert self.name is not None, \
80               "cannot pack unnamed attribute!"
81        assert len(self.values) > 0, \
82               "cannot pack empty attribute!"
83
[8979f90]84        # get the binary data for all the values
85        values = []
86        for v, i in zip(self.values, xrange(len(self.values))):
87
88            # get the name length (0 for everything but the first
89            # value)
90            if i == 0:
91                name_length = len(self.name)
92            else:
93                name_length = 0
94
95            # get the value length and binary value
[fc427ef]96            value_bin = v.packed_value
97            value_length = len(value_bin)
[8979f90]98
99            logger.debug("dumping name_length : %i" % name_length)
100            logger.debug("dumping name : %s" % self.name)
101            logger.debug("dumping value_length : %i" % value_length)
[f6c6897]102            logger.debug("dumping value (0x%x): %s" % (v.tag, v.value))
[8979f90]103
104            # the value tag in binary
[f6c6897]105            tag_bin = struct.pack('>b', v.tag)
[8979f90]106
107            # the name length in binary
108            name_length_bin = struct.pack('>h', name_length)
109
110            # the name in binary
111            name_bin = self.name
112
113            # the value length in binary
114            value_length_bin = struct.pack('>h', value_length)
115
116            if i == 0:
[f6c6897]117                values.append(''.join([tag_bin,
[8979f90]118                                       name_length_bin,
119                                       name_bin,
120                                       value_length_bin,
121                                       value_bin]))
122            else:
[f6c6897]123                values.append(''.join([tag_bin,
[8979f90]124                                       name_length_bin,
125                                       value_length_bin,
126                                       value_bin]))
[c269bc7]127
128        # concatenate everything together and return it along with the
129        # total length of the attribute
[fc427ef]130        return ''.join(values)
[c269bc7]131
[fc427ef]132    @property
133    def packed_value_size(self):
[5c5fe6d]134        """Gets the total size of the attribute.
135       
[c269bc7]136        """
[5c5fe6d]137
[75c0cab]138        return len(self.packed_value)
[c269bc7]139
[fc427ef]140    total_size = packed_value_size
[c269bc7]141
142    def __str__(self):
143        if len(self.values) > 0:
144            values = [str(v) for v in self.values]
145        else:
146            values = "None"
147
148        if self.name is None:
149            name = "None"
150        else:
151            name = self.name
152       
153        return "%s: %s" % (name, str(values))
[75c0cab]154
155    def __repr__(self):
156        return '<IPPAttribute (%r, %r)>' % (self.name, self.values)
Note: See TracBrowser for help on using the repository browser.