pyloxi: generic list deserialization

Since objects now handle their own type and length fields they can all use the
same generic list code. The oftype functions now generate list pack, unpack,
and init code on demand so nothing needs to be changed in pyloxi to use a new
list type.
diff --git a/py_gen/templates/generic_util.py b/py_gen/templates/generic_util.py
index 89b158d..99840ec 100644
--- a/py_gen/templates/generic_util.py
+++ b/py_gen/templates/generic_util.py
@@ -44,25 +44,6 @@
         entries.append(deserializer(reader))
     return entries
 
-def unpack_list_lv16(reader, deserializer):
-    """
-    The deserializer function should take an OFReader and return the new object.
-    """
-    def wrapper(reader):
-        length, = reader.peek('!H')
-        return deserializer(reader.slice(length))
-    return unpack_list(reader, wrapper)
-
-def unpack_list_tlv16(reader, deserializer):
-    """
-    The deserializer function should take an OFReader and an integer type
-    and return the new object.
-    """
-    def wrapper(reader):
-        typ, length, = reader.peek('!HH')
-        return deserializer(reader.slice(length), typ)
-    return unpack_list(reader, wrapper)
-
 def pad_to(alignment, length):
     """
     Return a string of zero bytes that will pad a string of length 'length' to
diff --git a/py_gen/templates/util.py b/py_gen/templates/util.py
index 73da0ea..9c9ccc1 100644
--- a/py_gen/templates/util.py
+++ b/py_gen/templates/util.py
@@ -174,57 +174,12 @@
         x >>= 1
     return value
 
-def unpack_list_flow_stats_entry(reader):
-    return loxi.generic_util.unpack_list_lv16(reader, common.flow_stats_entry.unpack)
-
-def unpack_list_queue_prop(reader):
-    def deserializer(reader, typ):
-        return common.queue_prop.unpack(reader)
-    return loxi.generic_util.unpack_list_tlv16(reader, deserializer)
-
-def unpack_list_packet_queue(reader):
-    def wrapper(reader):
-        length, = reader.peek('!4xH')
-        return common.packet_queue.unpack(reader.slice(length))
-    return loxi.generic_util.unpack_list(reader, wrapper)
-
 def unpack_list_hello_elem(reader):
-    def deserializer(reader, typ):
+    def deserializer(reader):
+        typ, length, = reader.peek('!HH')
+        reader = reader.slice(length)
         try:
             return common.hello_elem.unpack(reader)
         except loxi.ProtocolError:
             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, common.bucket.unpack)
-
-def unpack_list_group_desc_stats_entry(reader):
-    return loxi.generic_util.unpack_list_lv16(reader, common.group_desc_stats_entry.unpack)
-
-def unpack_list_group_stats_entry(reader):
-    return loxi.generic_util.unpack_list_lv16(reader, common.group_stats_entry.unpack)
-
-def unpack_list_meter_stats(reader):
-    def wrapper(reader):
-        length, = reader.peek('!4xH')
-        return common.meter_stats.unpack(reader.slice(length))
-    return loxi.generic_util.unpack_list(reader, wrapper)
-
-def unpack_list_action(reader):
-    def deserializer(reader, typ):
-        return action.action.unpack(reader)
-    return loxi.generic_util.unpack_list_tlv16(reader, deserializer)
-
-def unpack_list_instruction(reader):
-    def deserializer(reader, typ):
-        return instruction.instruction.unpack(reader)
-    return loxi.generic_util.unpack_list_tlv16(reader, deserializer)
-
-def unpack_list_meter_band(reader):
-    def deserializer(reader, typ):
-        return meter_band.meter_band.unpack(reader)
-    return loxi.generic_util.unpack_list_tlv16(reader, deserializer)
-
-def unpack_list_oxm(reader):
-    return loxi.generic_util.unpack_list(reader, oxm.oxm.unpack)
+    return [x for x in loxi.generic_util.unpack_list(reader, deserializer) if x != None]