Signed-off-by: YAMAMOTO Takashi <[email protected]>
---
ryu/ofproto/ofproto_parser.py | 71 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/ryu/ofproto/ofproto_parser.py b/ryu/ofproto/ofproto_parser.py
index 148507b..ae2f75e 100644
--- a/ryu/ofproto/ofproto_parser.py
+++ b/ryu/ofproto/ofproto_parser.py
@@ -14,8 +14,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import base64
+import collections
import logging
import struct
+import sys
import functools
import inspect
@@ -61,6 +64,9 @@ def create_list_of_base_attributes(f):
return wrapper
+_mapdict_key = lambda f, d: dict([(k, f(v)) for k, v in d.items()])
+
+
class StringifyMixin(object):
def __str__(self):
buf = ''
@@ -72,6 +78,57 @@ class StringifyMixin(object):
return self.__class__.__name__ + '(' + buf + ')'
__repr__ = __str__ # note: str(list) uses __repr__ for elements
+ @staticmethod
+ def _encode_value(v):
+ if isinstance(v, (bytes, unicode)):
+ json_value = base64.b64encode(v)
+ elif isinstance(v, list):
+ json_value = map(StringifyMixin._encode_value, v)
+ elif isinstance(v, dict):
+ json_value = _mapdict_key(StringifyMixin._encode_value, v)
+ else:
+ try:
+ json_value = v.to_jsondict()
+ except:
+ json_value = v
+ return json_value
+
+ def to_jsondict(self):
+ """returns an object to feed json.dumps()
+ """
+ dict = {}
+ for k, v in ofp_attrs(self):
+ # XXX type_ vs type
+ dict[k] = self._encode_value(v)
+ return {self.__class__.__name__: dict}
+
+ @staticmethod
+ def _decode_value(json_value):
+ if isinstance(json_value, (bytes, unicode)):
+ v = base64.b64decode(json_value)
+ elif isinstance(json_value, list):
+ v = map(StringifyMixin._decode_value, json_value)
+ elif isinstance(json_value, dict):
+ v = _mapdict_key(StringifyMixin._decode_value, json_value)
+ else:
+ v = json_value
+ return v
+
+ @classmethod
+ def from_jsondict(cls, dict):
+ """create an instance from a result of json.loads()
+ """
+ dict2 = {}
+ for k, v in dict.iteritems():
+ dict2[k] = cls._decode_value(v)
+ return cls(**dict2)
+
+
+def ofp_from_jsondict(parser, jsondict):
+ assert len(jsondict) == 1
+ for k, v in jsondict.iteritems():
+ return getattr(parser, k).from_jsondict(v)
+
class MsgBase(StringifyMixin):
@create_list_of_base_attributes
@@ -161,6 +218,13 @@ def msg_pack_into(fmt, buf, offset, *args):
def ofp_attrs(msg):
+ import collections
+ # a special case for namedtuple which seems widely used in
+ # ofp parser implementations.
+ if hasattr(msg, '_fields'):
+ for k in msg._fields:
+ yield(k, getattr(msg, k))
+ return
base = getattr(msg, '_base_attributes', [])
for k, v in inspect.getmembers(msg):
if k.startswith('_'):
@@ -174,6 +238,13 @@ def ofp_attrs(msg):
yield (k, v)
+def namedtuple(typename, fields, **kwargs):
+ class _namedtuple(StringifyMixin,
+ collections.namedtuple(typename, fields, **kwargs)):
+ pass
+ return _namedtuple
+
+
def msg_str_attr(msg, buf, attr_list=None):
if attr_list is None:
attr_list = ofp_attr(msg)
--
1.8.0.1
------------------------------------------------------------------------------
AlienVault Unified Security Management (USM) platform delivers complete
security visibility with the essential security capabilities. Easily and
efficiently configure, manage, and operate all of your security controls
from a single console and one unified framework. Download a free trial.
http://p.sf.net/sfu/alienvault_d2d
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel