blob: 938c68e0b366d336a61ebaf80977ec88dea1ba97 [file] [log] [blame]
Rich Lane5ec97b82013-01-06 18:04:25 -08001
2"""
3Base list class for inheritance.
4Most of the list stuff is common; unpacking is the only thing that
5is left pure virtual.
6"""
7
8import copy
9
10class ofp_base_list(object):
11 """
12 Container type to maintain a list of ofp objects
13
14 Data members:
15 @arg items An array of objects
16 @arg class_list A tuple of classes that may be added to the list;
17 If None, no checking is done
18 @arg name The name to use when displaying the list
19
20 Methods:
21 @arg pack Pack the structure into a string
22 @arg unpack Unpack a string to objects, with proper typing
23 @arg add Add an item to the list; you can directly access
24 the item member, but add will validate that the added object
25 is of the right type.
26 @arg extend Add the items for another list to this list
27
28 """
29
30 def __init__(self):
31 self.items = []
32 self.class_list = None
33 self.name = "unspecified"
34
35 def pack(self):
36 """
37 Pack a list of items
38
39 Returns the packed string
40 """
41 packed = ""
42 for obj in self.items:
43 packed += obj.pack()
44 return packed
45
46 def unpack(self, binary_string, bytes=None):
47 """
48 Pure virtual function for a list of items
49
50 Unpack items from a binary string, creating an array
51 of objects of the appropriate type
52
53 @param binary_string The string to be unpacked
54
55 @param bytes The total length of the list in bytes.
56 Ignored if decode is True. If None and decode is false, the
57 list is assumed to extend through the entire string.
58
59 @return The remainder of binary_string that was not parsed
60 """
61 pass
62
63 def add(self, item):
64 """
65 Add an item to a list
66
67 @param item The item to add
68 @return True if successful, False if not proper type object
69
70 """
71
72 # Note that the second arg of isinstance can be a list which
73 # checks that the type of item is in the list
74 if (self.class_list is not None) and \
75 not isinstance(item, tuple(self.class_list)):
76 return False
77
78 tmp = copy.deepcopy(item)
79 self.items.append(tmp)
80 return True
81
82 def remove_type(self, target):
83 """
84 Remove the first item on the list of the given type
85
86 @param target The type of item to search
87
88 @return The object removed, if any; otherwise None
89
90 """
91 for index in xrange(len(self.items)):
92 if self.items[index].type == target:
93 return self.items.pop(index)
94 return None
95
96 def find_type(self, target):
97 """
98 Find the first item on the list of the given type
99
100 @param target The type of item to search
101
102 @return The object with the matching type if any; otherwise None
103
104 """
105 for index in xrange(len(self.items)):
106 if self.items[index].type == target:
107 return self.items[index]
108 return None
109
110 def extend(self, other):
111 """
112 Add the items in other to this list
113
114 @param other An object of the same type of list whose
115 entries are to be merged into this list
116
117 @return True if successful. If not successful, the list
118 may have been modified.
119
120 @todo Check if this is proper deep copy or not
121
122 """
123 for act in other.items:
124 if not self.add(act):
125 return False
126 return True
127
128 def __len__(self):
129 """
130 Length of the list packed as a string
131 """
132 length = 0
133 for item in self.items:
134 length += item.__len__()
135 return length
136
137 def __eq__(self, other):
138 if type(self) != type(other):
139 return False
140 if self.items != other.items:
141 return False
142 return True
143
144 def __ne__(self, other): return not self.__eq__(other)
145
146 # Methods to make class iterable
147 def __iter__(self):
148 return self.items.__iter__()
149
150 def show(self, prefix=''):
151 outstr = prefix + self.name + "list with " + str(len(self.items)) + \
152 " items\n"
153 count = 0
154 for obj in self.items:
155 count += 1
156 outstr += prefix + " " + self.name + " " + str(count) + ": \n"
157 outstr += obj.show(prefix + ' ')
158 return outstr