pyloxi: generate virtual class unpack methods

This is done completely from the IR now.
diff --git a/py_gen/templates/_virtual_ofclass.py b/py_gen/templates/_virtual_ofclass.py
index 29f01f7..1e5dcc2 100644
--- a/py_gen/templates/_virtual_ofclass.py
+++ b/py_gen/templates/_virtual_ofclass.py
@@ -1,3 +1,23 @@
+:: import py_gen.util as util
 :: superclass_pyname = ofclass.superclass.pyname if ofclass.superclass else "loxi.OFObject"
+:: fmts = { 1: "B", 2: "!H", 4: "!L" }
+:: fmt = fmts[ofclass.discriminator.length]
+:: trail = ' '.join([x.pyname for x in util.ancestors(ofclass)])
 class ${ofclass.pyname}(${superclass_pyname}):
-    pass
+    subtypes = {}
+
+    @staticmethod
+    def unpack(reader):
+        subtype, = reader.peek(${repr(fmt)}, ${ofclass.discriminator.offset})
+        try:
+            subclass = ${ofclass.pyname}.subtypes[subtype]
+        except KeyError:
+            raise loxi.ProtocolError("unknown ${trail} subtype %#x" % subtype)
+        return subclass.unpack(reader)
+
+:: # Register with our superclass
+:: if ofclass.superclass:
+:: type_field_name = ofclass.superclass.discriminator.name
+:: type_value = ofclass.member_by_name(type_field_name).value
+${superclass_pyname}.subtypes[${type_value}] = ${ofclass.pyname}
+:: #endif