source: server/lib/gutenbach/ipp/core/attributegroup.py @ ffbe41d

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

Clean up core ipp code a bit

  • Property mode set to 100644
File size: 3.2 KB
Line 
1from .attribute import Attribute
2import sys
3import struct
4import logging
5
6# initialize logger
7logger = logging.getLogger(__name__)
8
9class AttributeGroup(object):
10    """An AttributeGroup consists of an attribute-group-tag, followed
11    by a sequence of Attributes. According to RFC 2565, 'Within an
12    attribute-sequence, if two attributes have the same name, the
13    first occurrence MUST be ignored.', so we can effectively treat
14    this as an ordered dictionary.
15   
16    """
17
18    def __init__(self, tag=None, attributes=[]):
19        """Initialize an AttributeGroup.  An AttributeGroup can be
20        initialized in three ways:
21
22            AttributeGroup()
23            AttributeGroup(tag)
24            AttributeGroup(tag, attributes)
25
26        Arguments:
27
28            tag -- a signed char, holds the tag of the
29                   attribute group
30
31            attributes -- a list of attributes
32
33        """
34
35        if tag is not None and not isinstance(tag, int):
36            raise ValueError("tag must be a character")
37
38        self.tag = tag
39        self.attributes = []
40        self.extend(attributes)
41
42    def __cmp__(self, other):
43        eq = self.tag == other.tag
44        for a1, a2 in zip(self.attributes, other.attributes):
45            eq = eq and (a1 == a2)
46        return 0 if eq else 1
47
48    def __getitem__(self, name):
49        """Returns a list of attributes which have name 'name'.
50       
51        """
52       
53        attribute = filter(lambda x: x.name == name, self.attributes)
54        if attribute:
55            return attribute[0]
56        else:
57            raise KeyError("Attribute %r not found" % name)
58
59    def __contains__(self, name):
60        return len(filter(lambda x: x.name == name, self.attributes))
61
62    def __iter__(self):
63        return (a.name for a in self.attributes)
64
65    iterkeys = __iter__
66
67    def __setitem__(self, name, attribute):
68        """Sets an attribute in the attribute group. Note that the key
69        is ignored and the attribute is queried for its name.
70       
71        """
72
73        return self.append(attribute)
74
75    def __delitem__(self, name):
76        self.attributes = filter(lambda x: x.name != name,
77                                 self.attributes)
78
79    def append(self, attribute):
80        return self.extend([attribute])
81
82    def extend(self, attributes):
83        """Sets the attributes for the attribute group.
84       
85        """
86
87        for a in attributes:
88            if not isinstance(a, Attribute):
89                raise ValueError("attribute must be of type Attribute")
90
91        for a in attributes:
92            # XXX: Instead of replacing the attribute, do we want to
93            # append the value to the attribute here?
94            del self[a.name]
95            self.attributes.append(a)
96
97    @property
98    def packed_value(self):
99        """Convert the AttributeGroup to binary.
100       
101        """
102
103        # convert the tag to binary
104        tag = struct.pack('>b', self.tag)
105
106        # convert each of the attributes to binary
107        attributes = [a.packed_value for a in self.attributes]
108
109        # concatenate everything and return
110        return tag + ''.join(attributes)
111
112    def __repr__(self):
113        return '<IPPAttributeGroup (%r, %r)>' % (self.tag, self.attributes)
Note: See TracBrowser for help on using the repository browser.