import OpenFlow 1.2 protocol module and basic test cases from CPqD/oftest12
For now these tests will live in a separate directory. The goal is to merge
them where possible but this has to wait for an OpenFlow protocol module that
supports all versions of OpenFlow.
diff --git a/src/python/of12/base_list.py b/src/python/of12/base_list.py
new file mode 100644
index 0000000..938c68e
--- /dev/null
+++ b/src/python/of12/base_list.py
@@ -0,0 +1,158 @@
+
+"""
+Base list class for inheritance.
+Most of the list stuff is common; unpacking is the only thing that
+is left pure virtual.
+"""
+
+import copy
+
+class ofp_base_list(object):
+ """
+ Container type to maintain a list of ofp objects
+
+ Data members:
+ @arg items An array of objects
+ @arg class_list A tuple of classes that may be added to the list;
+ If None, no checking is done
+ @arg name The name to use when displaying the list
+
+ Methods:
+ @arg pack Pack the structure into a string
+ @arg unpack Unpack a string to objects, with proper typing
+ @arg add Add an item to the list; you can directly access
+ the item member, but add will validate that the added object
+ is of the right type.
+ @arg extend Add the items for another list to this list
+
+ """
+
+ def __init__(self):
+ self.items = []
+ self.class_list = None
+ self.name = "unspecified"
+
+ def pack(self):
+ """
+ Pack a list of items
+
+ Returns the packed string
+ """
+ packed = ""
+ for obj in self.items:
+ packed += obj.pack()
+ return packed
+
+ def unpack(self, binary_string, bytes=None):
+ """
+ Pure virtual function for a list of items
+
+ Unpack items from a binary string, creating an array
+ of objects of the appropriate type
+
+ @param binary_string The string to be unpacked
+
+ @param bytes The total length of the list in bytes.
+ Ignored if decode is True. If None and decode is false, the
+ list is assumed to extend through the entire string.
+
+ @return The remainder of binary_string that was not parsed
+ """
+ pass
+
+ def add(self, item):
+ """
+ Add an item to a list
+
+ @param item The item to add
+ @return True if successful, False if not proper type object
+
+ """
+
+ # Note that the second arg of isinstance can be a list which
+ # checks that the type of item is in the list
+ if (self.class_list is not None) and \
+ not isinstance(item, tuple(self.class_list)):
+ return False
+
+ tmp = copy.deepcopy(item)
+ self.items.append(tmp)
+ return True
+
+ def remove_type(self, target):
+ """
+ Remove the first item on the list of the given type
+
+ @param target The type of item to search
+
+ @return The object removed, if any; otherwise None
+
+ """
+ for index in xrange(len(self.items)):
+ if self.items[index].type == target:
+ return self.items.pop(index)
+ return None
+
+ def find_type(self, target):
+ """
+ Find the first item on the list of the given type
+
+ @param target The type of item to search
+
+ @return The object with the matching type if any; otherwise None
+
+ """
+ for index in xrange(len(self.items)):
+ if self.items[index].type == target:
+ return self.items[index]
+ return None
+
+ def extend(self, other):
+ """
+ Add the items in other to this list
+
+ @param other An object of the same type of list whose
+ entries are to be merged into this list
+
+ @return True if successful. If not successful, the list
+ may have been modified.
+
+ @todo Check if this is proper deep copy or not
+
+ """
+ for act in other.items:
+ if not self.add(act):
+ return False
+ return True
+
+ def __len__(self):
+ """
+ Length of the list packed as a string
+ """
+ length = 0
+ for item in self.items:
+ length += item.__len__()
+ return length
+
+ def __eq__(self, other):
+ if type(self) != type(other):
+ return False
+ if self.items != other.items:
+ return False
+ return True
+
+ def __ne__(self, other): return not self.__eq__(other)
+
+ # Methods to make class iterable
+ def __iter__(self):
+ return self.items.__iter__()
+
+ def show(self, prefix=''):
+ outstr = prefix + self.name + "list with " + str(len(self.items)) + \
+ " items\n"
+ count = 0
+ for obj in self.items:
+ count += 1
+ outstr += prefix + " " + self.name + " " + str(count) + ": \n"
+ outstr += obj.show(prefix + ' ')
+ return outstr