update pyloxi to 026ff024585f1588a7f11fa4c1a9a48d44dc098d
diff --git a/src/python/loxi/of10/common.py b/src/python/loxi/of10/common.py
index 481b686..ec788ed 100644
--- a/src/python/loxi/of10/common.py
+++ b/src/python/loxi/of10/common.py
@@ -2,61 +2,19 @@
 # Copyright (c) 2011, 2012 Open Networking Foundation
 # Copyright (c) 2012, 2013 Big Switch Networks, Inc.
 # See the file LICENSE.pyloxi which should have been included in the source distribution
-# Automatically generated by LOXI from template common.py
+
+# Automatically generated by LOXI from template module.py
 # Do not modify
 
-import sys
 import struct
-import action
+import loxi
 import const
+import common
+import action
 import util
 import loxi.generic_util
 
-
-# HACK make this module visible as 'common' to simplify code generation
-common = sys.modules[__name__]
-
-def unpack_list_flow_stats_entry(reader):
-    return loxi.generic_util.unpack_list_lv16(reader, flow_stats_entry.unpack)
-
-def unpack_list_queue_prop(reader):
-    def deserializer(reader, typ):
-        if typ == const.OFPQT_MIN_RATE:
-            return queue_prop_min_rate.unpack(reader)
-        else:
-            raise loxi.ProtocolError("unknown queue prop %d" % typ)
-    return loxi.generic_util.unpack_list_tlv16(reader, deserializer)
-
-def unpack_list_packet_queue(reader):
-    def wrapper(reader):
-        length, = reader.peek('!4xH')
-        return packet_queue.unpack(reader.slice(length))
-    return loxi.generic_util.unpack_list(reader, wrapper)
-
-def unpack_list_hello_elem(reader):
-    def deserializer(reader, typ):
-        if typ == const.OFPHET_VERSIONBITMAP:
-            return hello_elem_versionbitmap.unpack(reader)
-        else:
-            return None
-    return [x for x in loxi.generic_util.unpack_list_tlv16(reader, deserializer) if x != None]
-
-def unpack_list_bucket(reader):
-    return loxi.generic_util.unpack_list_lv16(reader, bucket.unpack)
-
-def unpack_list_group_desc_stats_entry(reader):
-    return loxi.generic_util.unpack_list_lv16(reader, group_desc_stats_entry.unpack)
-
-def unpack_list_group_stats_entry(reader):
-    return loxi.generic_util.unpack_list_lv16(reader, group_stats_entry.unpack)
-
-def unpack_list_meter_stats(reader):
-    def wrapper(reader):
-        length, = reader.peek('!4xH')
-        return meter_stats.unpack(reader.slice(length))
-    return loxi.generic_util.unpack_list(reader, wrapper)
-
-class bsn_interface(object):
+class bsn_interface(loxi.OFObject):
 
     def __init__(self, hw_addr=None, name=None, ipv4_addr=None, ipv4_netmask=None):
         if hw_addr != None:
@@ -87,12 +45,8 @@
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = bsn_interface()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         obj.hw_addr = list(reader.read('!6B'))
         reader.skip(2)
         obj.name = reader.read("!16s")[0].rstrip("\x00")
@@ -108,13 +62,6 @@
         if self.ipv4_netmask != other.ipv4_netmask: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("bsn_interface {")
         with q.group():
@@ -134,7 +81,21 @@
             q.breakable()
         q.text('}')
 
-class bsn_vport_q_in_q(object):
+
+class bsn_vport(loxi.OFObject):
+    subtypes = {}
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        try:
+            subclass = bsn_vport.subtypes[subtype]
+        except KeyError:
+            raise loxi.ProtocolError("unknown bsn_vport subtype %#x" % subtype)
+        return subclass.unpack(reader)
+
+
+class bsn_vport_q_in_q(bsn_vport):
     type = 0
 
     def __init__(self, port_no=None, ingress_tpid=None, ingress_vlan_id=None, egress_tpid=None, egress_vlan_id=None, if_name=None):
@@ -179,15 +140,13 @@
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = bsn_vport_q_in_q()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         _type = reader.read("!H")[0]
         assert(_type == 0)
         _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length - (2 + 2))
         obj.port_no = reader.read("!L")[0]
         obj.ingress_tpid = reader.read("!H")[0]
         obj.ingress_vlan_id = reader.read("!H")[0]
@@ -206,13 +165,6 @@
         if self.if_name != other.if_name: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("bsn_vport_q_in_q {")
         with q.group():
@@ -238,7 +190,9 @@
             q.breakable()
         q.text('}')
 
-class flow_stats_entry(object):
+bsn_vport.subtypes[0] = bsn_vport_q_in_q
+
+class flow_stats_entry(loxi.OFObject):
 
     def __init__(self, table_id=None, match=None, duration_sec=None, duration_nsec=None, priority=None, idle_timeout=None, hard_timeout=None, cookie=None, packet_count=None, byte_count=None, actions=None):
         if table_id != None:
@@ -302,19 +256,17 @@
         packed.append(struct.pack("!Q", self.cookie))
         packed.append(struct.pack("!Q", self.packet_count))
         packed.append(struct.pack("!Q", self.byte_count))
-        packed.append(util.pack_list(self.actions))
+        packed.append(loxi.generic_util.pack_list(self.actions))
         length = sum([len(x) for x in packed])
         packed[0] = struct.pack("!H", length)
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = flow_stats_entry()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         _length = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_length - (0 + 2))
         obj.table_id = reader.read("!B")[0]
         reader.skip(1)
         obj.match = common.match.unpack(reader)
@@ -327,7 +279,7 @@
         obj.cookie = reader.read("!Q")[0]
         obj.packet_count = reader.read("!Q")[0]
         obj.byte_count = reader.read("!Q")[0]
-        obj.actions = action.unpack_list(reader)
+        obj.actions = loxi.generic_util.unpack_list(reader, action.action.unpack)
         return obj
 
     def __eq__(self, other):
@@ -345,13 +297,6 @@
         if self.actions != other.actions: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("flow_stats_entry {")
         with q.group():
@@ -392,7 +337,8 @@
             q.breakable()
         q.text('}')
 
-class match_v1(object):
+
+class match_v1(loxi.OFObject):
 
     def __init__(self, wildcards=None, in_port=None, eth_src=None, eth_dst=None, vlan_vid=None, vlan_pcp=None, eth_type=None, ip_dscp=None, ip_proto=None, ipv4_src=None, ipv4_dst=None, tcp_src=None, tcp_dst=None):
         if wildcards != None:
@@ -469,12 +415,8 @@
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = match_v1()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         obj.wildcards = util.unpack_wc_bmap(reader)
         obj.in_port = util.unpack_port_no(reader)
         obj.eth_src = list(reader.read('!6B'))
@@ -509,13 +451,6 @@
         if self.tcp_dst != other.tcp_dst: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("match_v1 {")
         with q.group():
@@ -562,7 +497,8 @@
             q.breakable()
         q.text('}')
 
-class packet_queue(object):
+
+class packet_queue(loxi.OFObject):
 
     def __init__(self, queue_id=None, properties=None):
         if queue_id != None:
@@ -580,22 +516,20 @@
         packed.append(struct.pack("!L", self.queue_id))
         packed.append(struct.pack("!H", 0)) # placeholder for len at index 1
         packed.append('\x00' * 2)
-        packed.append(util.pack_list(self.properties))
+        packed.append(loxi.generic_util.pack_list(self.properties))
         length = sum([len(x) for x in packed])
         packed[1] = struct.pack("!H", length)
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = packet_queue()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         obj.queue_id = reader.read("!L")[0]
         _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len - (4 + 2))
         reader.skip(2)
-        obj.properties = common.unpack_list_queue_prop(reader)
+        obj.properties = loxi.generic_util.unpack_list(reader, common.queue_prop.unpack)
         return obj
 
     def __eq__(self, other):
@@ -604,13 +538,6 @@
         if self.properties != other.properties: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("packet_queue {")
         with q.group():
@@ -624,7 +551,8 @@
             q.breakable()
         q.text('}')
 
-class port_desc(object):
+
+class port_desc(loxi.OFObject):
 
     def __init__(self, port_no=None, hw_addr=None, name=None, config=None, state=None, curr=None, advertised=None, supported=None, peer=None):
         if port_no != None:
@@ -679,12 +607,8 @@
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = port_desc()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         obj.port_no = util.unpack_port_no(reader)
         obj.hw_addr = list(reader.read('!6B'))
         obj.name = reader.read("!16s")[0].rstrip("\x00")
@@ -709,13 +633,6 @@
         if self.peer != other.peer: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("port_desc {")
         with q.group():
@@ -750,7 +667,8 @@
             q.breakable()
         q.text('}')
 
-class port_stats_entry(object):
+
+class port_stats_entry(loxi.OFObject):
 
     def __init__(self, port_no=None, rx_packets=None, tx_packets=None, rx_bytes=None, tx_bytes=None, rx_dropped=None, tx_dropped=None, rx_errors=None, tx_errors=None, rx_frame_err=None, rx_over_err=None, rx_crc_err=None, collisions=None):
         if port_no != None:
@@ -826,12 +744,8 @@
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = port_stats_entry()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         obj.port_no = util.unpack_port_no(reader)
         reader.skip(6)
         obj.rx_packets = reader.read("!Q")[0]
@@ -865,13 +779,6 @@
         if self.collisions != other.collisions: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("port_stats_entry {")
         with q.group():
@@ -918,7 +825,21 @@
             q.breakable()
         q.text('}')
 
-class queue_prop_min_rate(object):
+
+class queue_prop(loxi.OFObject):
+    subtypes = {}
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek('!H', 0)
+        try:
+            subclass = queue_prop.subtypes[subtype]
+        except KeyError:
+            raise loxi.ProtocolError("unknown queue_prop subtype %#x" % subtype)
+        return subclass.unpack(reader)
+
+
+class queue_prop_min_rate(queue_prop):
     type = 1
 
     def __init__(self, rate=None):
@@ -940,15 +861,13 @@
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = queue_prop_min_rate()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         _type = reader.read("!H")[0]
         assert(_type == 1)
         _len = reader.read("!H")[0]
+        orig_reader = reader
+        reader = orig_reader.slice(_len - (2 + 2))
         reader.skip(4)
         obj.rate = reader.read("!H")[0]
         reader.skip(6)
@@ -959,13 +878,6 @@
         if self.rate != other.rate: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("queue_prop_min_rate {")
         with q.group():
@@ -976,7 +888,9 @@
             q.breakable()
         q.text('}')
 
-class queue_stats_entry(object):
+queue_prop.subtypes[1] = queue_prop_min_rate
+
+class queue_stats_entry(loxi.OFObject):
 
     def __init__(self, port_no=None, queue_id=None, tx_bytes=None, tx_packets=None, tx_errors=None):
         if port_no != None:
@@ -1012,12 +926,8 @@
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = queue_stats_entry()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         obj.port_no = util.unpack_port_no(reader)
         reader.skip(2)
         obj.queue_id = reader.read("!L")[0]
@@ -1035,13 +945,6 @@
         if self.tx_errors != other.tx_errors: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("queue_stats_entry {")
         with q.group():
@@ -1064,7 +967,8 @@
             q.breakable()
         q.text('}')
 
-class table_stats_entry(object):
+
+class table_stats_entry(loxi.OFObject):
 
     def __init__(self, table_id=None, name=None, wildcards=None, max_entries=None, active_count=None, lookup_count=None, matched_count=None):
         if table_id != None:
@@ -1110,12 +1014,8 @@
         return ''.join(packed)
 
     @staticmethod
-    def unpack(buf):
+    def unpack(reader):
         obj = table_stats_entry()
-        if type(buf) == loxi.generic_util.OFReader:
-            reader = buf
-        else:
-            reader = loxi.generic_util.OFReader(buf)
         obj.table_id = reader.read("!B")[0]
         reader.skip(3)
         obj.name = reader.read("!32s")[0].rstrip("\x00")
@@ -1137,13 +1037,6 @@
         if self.matched_count != other.matched_count: return False
         return True
 
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def show(self):
-        import loxi.pp
-        return loxi.pp.pp(self)
-
     def pretty_print(self, q):
         q.text("table_stats_entry {")
         with q.group():
@@ -1173,4 +1066,5 @@
         q.text('}')
 
 
+
 match = match_v1