1. Removed type serializers, added (write|read)[0-9]*Byte[s]?(ChannelBuffer) method to value types instead.
2. Updated Masked fields for IPv4, IPv6 with specific string methods.
3. Added value types for other fields from the spec
4. Updated unit tests accordingly
5. Changed java_type.py to support multiple read/write operations per type, per OF version.
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index e88458a..8580f37 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -21,6 +21,19 @@
return camel
+ANY = 0xFFFFFFFFFFFFFFFF
+
+
+class VersionOp:
+ def __init__(self, version=ANY, read=None, write=None):
+ self.version = version
+ self.read = read
+ self.write = write
+
+ def __str__(self):
+ return "[Version: %d, Read: '%s', Write: '%s']" % (self.version, self.read, self.write)
+
+
class JType(object):
""" Wrapper class to hold C to Java type conversion information """
def __init__(self, pub_type, priv_type=None, size=None, read_op=None, write_op=None):
@@ -29,12 +42,17 @@
priv_type = pub_type
self.priv_type = priv_type # the internal storage type
self.size = size # bytes on the wire; None == variable length or hard to calc
- if read_op is None:
- read_op = 'ChannelUtils.read%s(bb)' % self.pub_type
- if write_op is None:
- write_op = 'ChannelUtils.write%s(bb, $name)' % self.pub_type
- self._read_op = read_op
- self._write_op = write_op
+ self.ops = {}
+# if read_op is None:
+# read_op = 'ChannelUtils.read%s(bb)' % self.pub_type
+# if write_op is None:
+# write_op = 'ChannelUtils.write%s(bb, $name)' % self.pub_type
+# self._read_op = read_op
+# self._write_op = write_op
+
+ def op(self, version=ANY, read=None, write=None):
+ self.ops[version] = VersionOp(version, read, write)
+ return self
@property
def public_type(self):
@@ -53,105 +71,111 @@
if length is None:
length = "length - bb.readerIndex()";
- if callable(self._read_op):
- return self._read_op(version)
+ ver = ANY if version is None else version.int_version
+ _read_op = None
+ if ver in self.ops:
+ _read_op = self.ops[ver].read or self.ops[ANY].read
+ elif ANY in self.ops:
+ _read_op = self.ops[ANY].read
+ if _read_op is None:
+ _read_op = 'ChannelUtils.read%s(bb)' % self.pub_type
+ if callable(_read_op):
+ return _read_op(version)
else:
- return self._read_op.replace("$length", str(length)).replace("$version", version.of_version)
+ return _read_op.replace("$length", str(length)).replace("$version", version.of_version)
def write_op(self, version=None, name=None):
- if callable(self._write_op):
- return self._write_op(version, name)
+ ver = ANY if version is None else version.int_version
+ _write_op = None
+ if ver in self.ops:
+ _write_op = self.ops[ver].write or self.ops[ANY].write
+ elif ANY in self.ops:
+ _write_op = self.ops[ANY].write
+ if _write_op is None:
+ _write_op = 'ChannelUtils.write%s(bb, $name)' % self.pub_type
+ if callable(_write_op):
+ return _write_op(version, name)
else:
- return self._write_op.replace("$name", str(name)).replace("$version", version.of_version)
+ return _write_op.replace("$name", str(name)).replace("$version", version.of_version)
-hello_elem_list = JType("List<OFHelloElement>",
- read_op = 'ChannelUtils.readHelloElementList(bb)',
- write_op = 'ChannelUtils.writeHelloElementList(bb)'
- )
-u8 = JType('byte', size=1, read_op='bb.readByte()',
- write_op='bb.writeByte($name)')
-u8_list = JType('List<U8>', size=1, read_op='bb.readByte()',
- write_op='bb.writeByte($name)')
-u16 = JType('int', 'int', size=2, read_op='U16.f(bb.readShort())',
- write_op='bb.writeShort(U16.t($name))')
-u32 = JType('int', 'int', size=4, read_op='bb.readInt()',
- write_op='bb.writeInt($name)')
-u32_list = JType('List<U32>', 'int[]', size=4, read_op='bb.readInt()',
- write_op='bb.writeInt($name)')
-u64 = JType('U64', 'U64', size=8, read_op='U64.of(bb.readLong())',
- write_op='bb.writeLong($name.getValue())')
-of_port= JType('OFPort',size=None,
- read_op = "OFPort.SERIALIZER_V$version.readFrom(bb)",
- write_op = "OFPort.SERIALIZER_V$version.writeTo($name, bb)")
-one_byte_array = JType('byte[]', size=1,
- read_op = 'ChannelUtils.readBytes(bb, 1)',
- write_op = 'ChannelUtils.writeBytes(bb, $name)')
-two_byte_array = JType('byte[]', size=2,
- read_op = 'ChannelUtils.readBytes(bb, 2)',
- write_op = 'ChannelUtils.writeBytes(bb, $name)')
-three_byte_array = JType('byte[]', size=3,
- read_op = 'ChannelUtils.readBytes(bb, 3)',
- write_op = 'ChannelUtils.writeBytes(bb, $name)')
-four_byte_array = JType('byte[]', size=4,
- read_op = 'ChannelUtils.readBytes(bb, 4)',
- write_op = 'ChannelUtils.writeBytes(bb, $name)')
-five_byte_array = JType('byte[]', size=5,
- read_op = 'ChannelUtils.readBytes(bb, 5)',
- write_op = 'ChannelUtils.writeBytes(bb, $name)')
-six_byte_array = JType('byte[]', size=6,
- read_op = 'ChannelUtils.readBytes(bb, 6)',
- write_op = 'ChannelUtils.writeBytes(bb, $name)')
-seven_byte_array = JType('byte[]', size=7,
- read_op = 'ChannelUtils.readBytes(bb, 7)',
- write_op = 'ChannelUtils.writeBytes(bb, $name)')
-actions_list = JType('List<OFAction>', size='ChannelUtils.calcListSize($name)',
- read_op = 'ChannelUtils.readActionsList(bb, $length)',
- write_op = 'ChannelUtils.writeActionsList(bb, $name);')
-instructions_list = JType('List<OFInstruction>', size='ChannelUtils.calcListSize($name)',
- read_op = 'ChannelUtils.readInstructionsList(bb, $length)',
- write_op = 'ChannelUtils.writeList(bb, $name)')
-buckets_list = JType('List<OFBucket>', size='ChannelUtils.calcListSize($name)',
- read_op = 'ChannelUtils.readBucketList(bb, $length)',
- write_op = 'ChannelUtils.writeList(bb, $name)')
-port_desc_list = JType('List<OFPhysicalPort>', size='ChannelUtils.calcListSize($name)',
- read_op = 'ChannelUtils.readPhysicalPortList(bb, $length)',
- write_op = 'ChannelUtils.writeList(bb, $name)')
-port_desc = JType('OFPortDesc', size='$name.getLength()',
- read_op = 'null; // TODO OFPortDescVer$version.READER.read(bb)',
- write_op = '$name.writeTo(bb)')
-packet_queue_list = JType('List<OFPacketQueue>', size='ChannelUtils.calcListSize($name)',
- read_op = 'ChannelUtils.readPacketQueueList(bb, $length)',
- write_op = 'ChannelUtils.writeList(bb, $name)')
-octets = JType('byte[]', size="$length",
- read_op = 'ChannelUtils.readBytes(bb, $length)',
- write_op = 'bb.writeBytes($name)')
-of_match = JType('Match', size="$name.getLength()",
- read_op = 'ChannelUtils.readOFMatch(bb)',
- write_op = 'ChannelUtils.writeOFMatch(bb, $name)')
-flow_mod_cmd = JType('OFFlowModCommand', 'short', size="$name.getLength()",
- read_op = lambda v: "bb.readShort()" if v.int_version == 1 else "bb.readByte()",
- write_op = lambda v, name: "bb.writeShort(%s)" % name if v.int_version == 1 else "bb.writeByte(%s)" % name)
-mac_addr = JType('MacAddress', 'byte[]', size=6,
- read_op = "MacAddress.SERIALIZER_V$version.readFrom(bb)",
- write_op = "MacAddress.SERIALIZER_V$version.writeTo($name, bb)")
-port_name = JType('String', size=16,
- read_op = 'ChannelUtils.readFixedLengthString(bb, 16)',
- write_op = 'ChannelUtils.writeFixedLengthString(bb, $name, 16)')
-desc_str = JType('String', size=256,
- read_op = 'ChannelUtils.readFixedLengthString(bb, 256)',
- write_op = 'ChannelUtils.writeFixedLengthString(bb, $name, 256)')
-serial_num = JType('String', size=32,
- read_op = 'ChannelUtils.readFixedLengthString(bb, 32)',
- write_op = 'ChannelUtils.writeFixedLengthString(bb, $name, 32)')
-table_name = JType('String', size=32,
- read_op = 'ChannelUtils.readFixedLengthString(bb, 32)',
- write_op = 'ChannelUtils.writeFixedLengthString(bb, $name, 32)')
-ipv4 = JType("IPv4",
- read_op = "IPv4.SERIALIZER_V$version.readFrom(bb)",
- write_op = "IPv4.SERIALIZER_V$version.writeTo($name, bb)")
-ipv6 = JType("IPv6",
- read_op = "IPv6.SERIALIZER_V$version.readFrom(bb)",
- write_op = "IPv6.SERIALIZER_V$version.writeTo($name, bb)")
+hello_elem_list = JType("List<OFHelloElement>") \
+ .op(read='ChannelUtils.readHelloElementList(bb)', write='ChannelUtils.writeHelloElementList(bb)')
+u8 = JType('byte', size=1) \
+ .op(read='bb.readByte()', write='bb.writeByte($name)')
+u8_list = JType('List<U8>', size=1) \
+ .op(read='bb.readByte()', write='bb.writeByte($name)')
+u16 = JType('int', 'int', size=2) \
+ .op(read='U16.f(bb.readShort())', write='bb.writeShort(U16.t($name))')
+u32 = JType('int', 'int', size=4) \
+ .op(read='bb.readInt()', write='bb.writeInt($name)')
+u32_list = JType('List<U32>', 'int[]', size=4) \
+ .op(read='bb.readInt()', write='bb.writeInt($name)')
+u64 = JType('U64', 'U64', size=8) \
+ .op(read='U64.of(bb.readLong())', write='bb.writeLong($name.getValue())')
+of_port = JType("OFPort") \
+ .op(version=1, read="OFPort.read2Bytes(bb)", write="$name.write2Bytes(bb)") \
+ .op(version=ANY, read="OFPort.read4Bytes(bb)", write="$name.write4Bytes(bb)")
+one_byte_array = JType('byte[]', size=1) \
+ .op(read='ChannelUtils.readBytes(bb, 1)', write='ChannelUtils.writeBytes(bb, $name)')
+two_byte_array = JType('byte[]', size=2) \
+ .op(read='ChannelUtils.readBytes(bb, 2)', write='ChannelUtils.writeBytes(bb, $name)')
+three_byte_array = JType('byte[]', size=3) \
+ .op(read='ChannelUtils.readBytes(bb, 3)', write='ChannelUtils.writeBytes(bb, $name)')
+four_byte_array = JType('byte[]', size=4) \
+ .op(read='ChannelUtils.readBytes(bb, 4)', write='ChannelUtils.writeBytes(bb, $name)')
+five_byte_array = JType('byte[]', size=5) \
+ .op(read='ChannelUtils.readBytes(bb, 5)', write='ChannelUtils.writeBytes(bb, $name)')
+six_byte_array = JType('byte[]', size=6) \
+ .op(read='ChannelUtils.readBytes(bb, 6)', write='ChannelUtils.writeBytes(bb, $name)')
+seven_byte_array = JType('byte[]', size=7) \
+ .op(read='ChannelUtils.readBytes(bb, 7)', write='ChannelUtils.writeBytes(bb, $name)')
+actions_list = JType('List<OFAction>', size='ChannelUtils.calcListSize($name)') \
+ .op(read='ChannelUtils.readActionsList(bb, $length)', write='ChannelUtils.writeActionsList(bb, $name);')
+instructions_list = JType('List<OFInstruction>', size='ChannelUtils.calcListSize($name)') \
+ .op(read='ChannelUtils.readInstructionsList(bb, $length)', \
+ write='ChannelUtils.writeList(bb, $name)')
+buckets_list = JType('List<OFBucket>', size='ChannelUtils.calcListSize($name)') \
+ .op(read='ChannelUtils.readBucketList(bb, $length)', \
+ write='ChannelUtils.writeList(bb, $name)')
+port_desc_list = JType('List<OFPhysicalPort>', size='ChannelUtils.calcListSize($name)') \
+ .op(read='ChannelUtils.readPhysicalPortList(bb, $length)', \
+ write='ChannelUtils.writeList(bb, $name)')
+port_desc = JType('OFPortDesc', size='$name.getLength()') \
+ .op(read='null; // TODO OFPortDescVer$version.READER.read(bb)', \
+ write='$name.writeTo(bb)')
+packet_queue_list = JType('List<OFPacketQueue>', size='ChannelUtils.calcListSize($name)') \
+ .op(read='ChannelUtils.readPacketQueueList(bb, $length)', \
+ write='ChannelUtils.writeList(bb, $name)')
+octets = JType('byte[]', size="$length") \
+ .op(read='ChannelUtils.readBytes(bb, $length)', \
+ write='bb.writeBytes($name)')
+of_match = JType('Match', size="$name.getLength()") \
+ .op(read='ChannelUtils.readOFMatch(bb)', \
+ write='ChannelUtils.writeOFMatch(bb, $name)')
+flow_mod_cmd = JType('OFFlowModCommand', 'short', size="$name.getLength()") \
+ .op(version=1, read="bb.readShort()", write="bb.writeShort($name)") \
+ .op(version=ANY, read="bb.readByte()", write="bb.writeByte($name)")
+mac_addr = JType('MacAddress', 'byte[]', size=6) \
+ .op(read="MacAddress.read6Bytes(bb)", \
+ write="$name.write6Bytes(bb)")
+port_name = JType('String', size=16) \
+ .op(read='ChannelUtils.readFixedLengthString(bb, 16)', \
+ write='ChannelUtils.writeFixedLengthString(bb, $name, 16)')
+desc_str = JType('String', size=256) \
+ .op(read='ChannelUtils.readFixedLengthString(bb, 256)', \
+ write='ChannelUtils.writeFixedLengthString(bb, $name, 256)')
+serial_num = JType('String', size=32) \
+ .op(read='ChannelUtils.readFixedLengthString(bb, 32)', \
+ write='ChannelUtils.writeFixedLengthString(bb, $name, 32)')
+table_name = JType('String', size=32) \
+ .op(read='ChannelUtils.readFixedLengthString(bb, 32)', \
+ write='ChannelUtils.writeFixedLengthString(bb, $name, 32)')
+ipv4 = JType("IPv4") \
+ .op(read="IPv4.read4Bytes(bb)", \
+ write="$name.write4Bytes(bb)")
+ipv6 = JType("IPv6") \
+ .op(read="IPv6.read16Bytes(bb)", \
+ write="$name.write16Bytes(bb)")
default_mtype_to_jtype_convert_map = {
'uint8_t' : u8,
@@ -201,10 +225,9 @@
raise Exception("Not a recgonized standard list type declaration: %s" % c_type)
base_name = m.group(1)
java_base_name = name_c_to_caps_camel(base_name)
- return JType("List<OF%s>" % java_base_name,
- read_op = 'ChannelUtils.read%sList(bb)' % java_base_name,
- write_op = 'ChannelUtils.write%sList(bb, $name)' % java_base_name
- )
+ return JType("List<OF%s>" % java_base_name) \
+ .op(read='ChannelUtils.read%sList(bb)' % java_base_name, \
+ write='ChannelUtils.write%sList(bb, $name)' % java_base_name)
def convert_to_jtype(obj_name, field_name, c_type):
""" Convert from a C type ("uint_32") to a java type ("U32")
@@ -212,14 +235,14 @@
if obj_name in exceptions and field_name in exceptions[obj_name]:
return exceptions[obj_name][field_name]
elif field_name == "type" and c_type == "uint8_t":
- return JType("OFType", 'byte', size=1, read_op='bb.readByte()',
- write_op='bb.writeByte($name)')
+ return JType("OFType", 'byte', size=1) \
+ .op(read='bb.readByte()', write='bb.writeByte($name)')
elif field_name == "type" and re.match(r'of_action.*', obj_name):
- return JType("OFActionType", 'short', size=2, read_op='bb.readShort()',
- write_op='bb.writeShort($name)')
+ return JType("OFActionType", 'short', size=2) \
+ .op(read='bb.readShort()', write='bb.writeShort($name)')
elif field_name == "version" and c_type == "uint8_t":
- return JType("OFVersion", 'byte', size=1, read_op='bb.readByte()',
- write_op='bb.writeByte($name)')
+ return JType("OFVersion", 'byte', size=1) \
+ .op(read='bb.readByte()', write='bb.writeByte($name)')
elif c_type in default_mtype_to_jtype_convert_map:
return default_mtype_to_jtype_convert_map[c_type]
elif re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type):