pyloxi: move version-independent utility code to a new file
Also adds a test for unpack_list.
diff --git a/py_gen/templates/action.py b/py_gen/templates/action.py
index 8462dfd..1c7a75a 100644
--- a/py_gen/templates/action.py
+++ b/py_gen/templates/action.py
@@ -34,6 +34,7 @@
import struct
import const
import util
+import loxi.generic_util
import loxi
def unpack_list(buf):
@@ -44,7 +45,7 @@
parser = parsers.get(type)
if not parser: raise loxi.ProtocolError("unknown action type %d" % type)
return parser(buf)
- return util.unpack_list(deserializer, "!2xH", buf)
+ return loxi.generic_util.unpack_list(deserializer, "!2xH", buf)
class Action(object):
type = None # override in subclass
diff --git a/py_gen/templates/common.py b/py_gen/templates/common.py
index 2f9310e..516bf05 100644
--- a/py_gen/templates/common.py
+++ b/py_gen/templates/common.py
@@ -34,12 +34,13 @@
import action
import const
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(buf):
- return util.unpack_list(flow_stats_entry.unpack, "!H", buf)
+ return loxi.generic_util.unpack_list(flow_stats_entry.unpack, "!H", buf)
def unpack_list_queue_prop(buf):
def deserializer(buf):
@@ -48,10 +49,10 @@
return queue_prop_min_rate.unpack(buf)
else:
raise loxi.ProtocolError("unknown queue prop %d" % type)
- return util.unpack_list(deserializer, "!2xH", buf)
+ return loxi.generic_util.unpack_list(deserializer, "!2xH", buf)
def unpack_list_packet_queue(buf):
- return util.unpack_list(packet_queue.unpack, "!4xH", buf)
+ return loxi.generic_util.unpack_list(packet_queue.unpack, "!4xH", buf)
def unpack_list_hello_elem(buf):
def deserializer(buf):
@@ -60,7 +61,7 @@
return hello_elem_versionbitmap.unpack(buf)
else:
return None
- return [x for x in util.unpack_list(deserializer, "!2xH", buf) if x != None]
+ return [x for x in loxi.generic_util.unpack_list(deserializer, "!2xH", buf) if x != None]
:: for ofclass in ofclasses:
:: include('_ofclass.py', ofclass=ofclass, superclass="object")
diff --git a/py_gen/templates/generic_util.py b/py_gen/templates/generic_util.py
new file mode 100644
index 0000000..cba8c86
--- /dev/null
+++ b/py_gen/templates/generic_util.py
@@ -0,0 +1,66 @@
+:: # Copyright 2013, Big Switch Networks, Inc.
+:: #
+:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
+:: # the following special exception:
+:: #
+:: # LOXI Exception
+:: #
+:: # As a special exception to the terms of the EPL, you may distribute libraries
+:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
+:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
+:: # from the LoxiGen Libraries and the notice provided below is (i) included in
+:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
+:: # documentation for the LoxiGen Libraries, if distributed in binary form.
+:: #
+:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
+:: #
+:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
+:: # a copy of the EPL at:
+:: #
+:: # http://www.eclipse.org/legal/epl-v10.html
+:: #
+:: # Unless required by applicable law or agreed to in writing, software
+:: # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+:: # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+:: # EPL for the specific language governing permissions and limitations
+:: # under the EPL.
+::
+:: include('_copyright.py')
+"""
+Utility functions independent of the protocol version
+"""
+
+:: include('_autogen.py')
+
+import loxi
+import struct
+
+def unpack_array(deserializer, element_size, buf):
+ """
+ Deserialize an array of fixed length elements.
+ The deserializer function should take a buffer and return the new object.
+ """
+ if len(buf) % element_size != 0: raise loxi.ProtocolError("invalid array length")
+ n = len(buf) / element_size
+ return [deserializer(buffer(buf, i*element_size, element_size)) for i in range(n)]
+
+def unpack_list(deserializer, length_fmt, buf, extra_len=0):
+ """
+ Deserialize a list of variable-length entries.
+ 'length_fmt' is a struct format string with exactly one non-padding format
+ character that returns the length of the given element, minus extra_len.
+ The deserializer function should take a buffer and return the new object.
+ """
+ entries = []
+ offset = 0
+ length_struct = struct.Struct(length_fmt)
+ n = len(buf)
+ while offset < n:
+ if offset + length_struct.size > len(buf): raise loxi.ProtocolError("entry header overruns list length")
+ length, = length_struct.unpack_from(buf, offset)
+ length += extra_len
+ if length < length_struct.size: raise loxi.ProtocolError("entry length is less than the header length")
+ if offset + length > len(buf): raise loxi.ProtocolError("entry length overruns list length")
+ entries.append(deserializer(buffer(buf, offset, length)))
+ offset += length
+ return entries
diff --git a/py_gen/templates/message.py b/py_gen/templates/message.py
index 8eb051d..d501854 100644
--- a/py_gen/templates/message.py
+++ b/py_gen/templates/message.py
@@ -37,6 +37,7 @@
import common
import action # for unpack_list
import util
+import loxi.generic_util
class Message(object):
version = const.OFP_VERSION
diff --git a/py_gen/templates/oxm.py b/py_gen/templates/oxm.py
index 14ea259..66886e0 100644
--- a/py_gen/templates/oxm.py
+++ b/py_gen/templates/oxm.py
@@ -34,6 +34,7 @@
import struct
import const
import util
+import loxi.generic_util
import loxi
class OXM(object):
diff --git a/py_gen/templates/util.py b/py_gen/templates/util.py
index fead78f..f2f7a96 100644
--- a/py_gen/templates/util.py
+++ b/py_gen/templates/util.py
@@ -33,35 +33,6 @@
import const
import struct
-def unpack_array(deserializer, element_size, buf):
- """
- Deserialize an array of fixed length elements.
- The deserializer function should take a buffer and return the new object.
- """
- if len(buf) % element_size != 0: raise loxi.ProtocolError("invalid array length")
- n = len(buf) / element_size
- return [deserializer(buffer(buf, i*element_size, element_size)) for i in range(n)]
-
-def unpack_list(deserializer, length_fmt, buf):
- """
- Deserialize a list of variable-length entries.
- 'length_fmt' is a struct format string with exactly one non-padding format
- character that returns the length of the given element.
- The deserializer function should take a buffer and return the new object.
- """
- entries = []
- offset = 0
- length_struct = struct.Struct(length_fmt)
- n = len(buf)
- while offset < n:
- if offset + length_struct.size > len(buf): raise loxi.ProtocolError("entry header overruns list length")
- length, = length_struct.unpack_from(buf, offset)
- if length < length_struct.size: raise loxi.ProtocolError("entry length is less than the header length")
- if offset + length > len(buf): raise loxi.ProtocolError("entry length overruns list length")
- entries.append(deserializer(buffer(buf, offset, length)))
- offset += length
- return entries
-
def pretty_mac(mac):
return ':'.join(["%02x" % x for x in mac])