> On Fri, 23 Aug 2013 13:42:54 +0900 (JST)
> [email protected] (YAMAMOTO Takashi) wrote:
>
>>> On Fri, 23 Aug 2013 12:18:31 +0900 (JST)
>>> [email protected] (YAMAMOTO Takashi) wrote:
>>>
>>>>> On Fri, 16 Aug 2013 15:29:22 +0900
>>>>> YAMAMOTO Takashi <[email protected]> wrote:
>>>>>
>>>>>> Signed-off-by: YAMAMOTO Takashi <[email protected]>
>>>>>> ---
>>>>>> ryu/ofproto/ofproto_v1_0_parser.py | 6 +++++-
>>>>>> 1 file changed, 5 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/ryu/ofproto/ofproto_v1_0_parser.py
>>>>>> b/ryu/ofproto/ofproto_v1_0_parser.py
>>>>>> index 3fae86d..e1951c8 100644
>>>>>> --- a/ryu/ofproto/ofproto_v1_0_parser.py
>>>>>> +++ b/ryu/ofproto/ofproto_v1_0_parser.py
>>>>>> @@ -18,6 +18,7 @@ import struct
>>>>>> import binascii
>>>>>>
>>>>>> from ofproto_parser import StringifyMixin, MsgBase, msg_pack_into,
>>>>>> msg_str_attr
>>>>>> +from ryu.lib import addrconv
>>>>>> from ryu.lib import mac
>>>>>> from . import ofproto_parser
>>>>>> from . import ofproto_v1_0
>>>>>> @@ -86,6 +87,9 @@ class
>>>>>> OFPPhyPort(ofproto_parser.namedtuple('OFPPhyPort', (
>>>>>> def parser(cls, buf, offset):
>>>>>> port = struct.unpack_from(ofproto_v1_0.OFP_PHY_PORT_PACK_STR,
>>>>>> buf, offset)
>>>>>> + i = cls._fields.index('hw_addr')
>>>>>> + port = list(port)
>>>>>> + port[i] = addrconv.mac.bin_to_text(port[i])
>>>>>> return cls(*port)
>>>>>
>>>>> Can we use unicode type here? Then _encode_value() in stringfy.py just
>>>>
>>>> are you talking about "name", not "hw_addr"?
>>>
>>> hw_addr.
>>
>> then i'm not sure if i understand what you mean.
>> do you mean to use different python types (str vs unicode) to
>> tell the encoder do base64 or not? it can work for encoding
>> but not for decoding.
>
> _JSON_FORMATER thing in this patchset describes the type of members in
> a class. Then you can know how to decode.
>
> I thought that we could use unicode for 'string' type however looks
> like it needs more changes than I want. Scratch that.
IMO, if how to decode is specified _JSON_FORMATTER or _STRING,
it's better to use the same mechanism to specify how to encode.
>
> I like to simply use 'type' attribute rather than allowing own
> encoder/decoder. We use JSON so it's just about string or binary. I
> like a simpler like the following. I don't like to use class attribute
> though. I prefer to use the attribute of each member.
do you like something like the following?
python:
class Binary(str):
pass
class Hoge(StringifyMixin):
def __init__(self):
self.field1 = Binary('foo')
self.field2 = 'bar'
json:
{ "Hoge": {
"field1": { "Binary": "xxx base64 encoded 'foo' xxx" },
"field2": "bar"
}}
YAMAMOTO Takashi
>
>
> diff --git a/ryu/lib/stringify.py b/ryu/lib/stringify.py
> index 5766f4a..00b2558 100644
> --- a/ryu/lib/stringify.py
> +++ b/ryu/lib/stringify.py
> @@ -43,6 +43,7 @@ _RESERVED_KEYWORD = dir(__builtin__)
>
> _mapdict = lambda f, d: dict([(k, f(v)) for k, v in d.items()])
> _mapdict_key = lambda f, d: dict([(f(k), v) for k, v in d.items()])
> +_mapdict_kv = lambda f, d: dict([(k, f(k, v)) for k, v in d.items()])
>
>
> class StringifyMixin(object):
> @@ -78,9 +79,17 @@ class StringifyMixin(object):
> return False
>
> @classmethod
> - def _encode_value(cls, v, encode_string=base64.b64encode):
> - encode = lambda x: cls._encode_value(x, encode_string)
> - if isinstance(v, (bytes, unicode)):
> + def _is_string_type(cls, k):
> + if hasattr(cls, '_STRING') and k in cls._STRING:
> + return True
> + return False
> +
> + @classmethod
> + def _encode_value(cls, k, v, encode_string=base64.b64encode):
> + encode = lambda x: cls._encode_value(k, x, encode_string)
> + if cls._is_string_type(k):
> + json_value = v.encode('utf')
> + elif isinstance(v, (bytes, unicode)):
> json_value = encode_string(v)
> elif isinstance(v, list):
> json_value = map(encode, v)
> @@ -101,9 +110,9 @@ class StringifyMixin(object):
> """returns an object to feed json.dumps()
> """
> dict_ = {}
> - encode = lambda x: self._encode_value(x, encode_string)
> + encode = lambda k, x: self._encode_value(k, x, encode_string)
> for k, v in obj_attrs(self):
> - dict_[k] = encode(v)
> + dict_[k] = encode(k, v)
> return {self.__class__.__name__: dict_}
>
> @classmethod
> @@ -121,9 +130,11 @@ class StringifyMixin(object):
> return obj_cls.from_jsondict(v)
>
> @classmethod
> - def _decode_value(cls, json_value, decode_string=base64.b64decode):
> - decode = lambda x: cls._decode_value(x, decode_string)
> - if isinstance(json_value, (bytes, unicode)):
> + def _decode_value(cls, k, json_value, decode_string=base64.b64decode):
> + decode = lambda x: cls._decode_value(k, x, decode_string)
> + if cls._is_string_type(k):
> + v = json_value
> + elif isinstance(json_value, (bytes, unicode)):
> v = decode_string(json_value)
> elif isinstance(json_value, list):
> v = map(decode, json_value)
> @@ -155,8 +166,8 @@ class StringifyMixin(object):
> **additional_args):
> """create an instance from a result of json.loads()
> """
> - decode = lambda x: cls._decode_value(x, decode_string)
> - kwargs = cls._restore_args(_mapdict(decode, dict_))
> + decode = lambda k, x: cls._decode_value(k, x, decode_string)
> + kwargs = cls._restore_args(_mapdict_kv(decode, dict_))
> try:
> return cls(**dict(kwargs, **additional_args))
> except TypeError:
> diff --git a/ryu/ofproto/ofproto_v1_0_parser.py
> b/ryu/ofproto/ofproto_v1_0_parser.py
> index 3fae86d..897efe4 100644
> --- a/ryu/ofproto/ofproto_v1_0_parser.py
> +++ b/ryu/ofproto/ofproto_v1_0_parser.py
> @@ -18,6 +18,7 @@ import struct
> import binascii
>
> from ofproto_parser import StringifyMixin, MsgBase, msg_pack_into,
> msg_str_attr
> +from ryu.lib import addrconv
> from ryu.lib import mac
> from . import ofproto_parser
> from . import ofproto_v1_0
> @@ -82,10 +83,15 @@ class OFPPhyPort(ofproto_parser.namedtuple('OFPPhyPort', (
> 'port_no', 'hw_addr', 'name', 'config', 'state', 'curr',
> 'advertised',
> 'supported', 'peer'))):
>
> + _STRING = ('hw_addr')
> +
> @classmethod
> def parser(cls, buf, offset):
> port = struct.unpack_from(ofproto_v1_0.OFP_PHY_PORT_PACK_STR,
> buf, offset)
> + i = cls._fields.index('hw_addr')
> + port = list(port)
> + port[i] = addrconv.mac.bin_to_text(port[i])
> return cls(*port)
>
>
> @@ -2109,7 +2115,7 @@ class OFPPortMod(MsgBase):
> def _serialize_body(self):
> msg_pack_into(ofproto_v1_0.OFP_PORT_MOD_PACK_STR,
> self.buf, ofproto_v1_0.OFP_HEADER_SIZE,
> - self.port_no, self.hw_addr,
> + self.port_no, addrconv.mac.text_to_bin(self.hw_addr),
> self.config, self.mask, self.advertise)
>
>
> diff --git
> a/ryu/tests/unit/ofproto/json/of10/1-6-ofp_switch_features.packet.json
> b/ryu/tests/unit/ofproto/json/of10/1-6-ofp_switch_features.packet.json
> index 4084ba5..aa8180e 100644
> --- a/ryu/tests/unit/ofproto/json/of10/1-6-ofp_switch_features.packet.json
> +++ b/ryu/tests/unit/ofproto/json/of10/1-6-ofp_switch_features.packet.json
> @@ -11,7 +11,7 @@
> "advertised": 640,
> "config": 0,
> "curr": 648,
> - "hw_addr": "8gukffjq",
> + "hw_addr": "f2:0b:a4:7d:f8:ea",
> "name": "UG9ydAYAAAAAAAAAAAAAAA==",
> "peer": 648,
> "port_no": 6,
> @@ -24,7 +24,7 @@
> "advertised": 640,
> "config": 0,
> "curr": 648,
> - "hw_addr": "8guk0D9w",
> + "hw_addr": "f2:0b:a4:d0:3f:70",
> "name": "UG9ydAcAAAAAAAAAAAAAAA==",
> "peer": 648,
> "port_no": 7,
> diff --git a/ryu/tests/unit/ofproto/test_parser_v10.py
> b/ryu/tests/unit/ofproto/test_parser_v10.py
> index 29e7d28..81b96de 100644
> --- a/ryu/tests/unit/ofproto/test_parser_v10.py
> +++ b/ryu/tests/unit/ofproto/test_parser_v10.py
> @@ -20,6 +20,7 @@ import logging
> from nose.tools import *
> from ryu.ofproto.ofproto_v1_0_parser import *
> from ryu.ofproto import ofproto_v1_0_parser
> +from ryu.lib import addrconv
>
>
> LOG = logging.getLogger('test_ofproto_v10')
> @@ -33,7 +34,7 @@ class TestOFPPhyPort(unittest.TestCase):
> # '!H6s16sIIIIII'... port_no, hw_addr, name, config, state
> # curr, advertised, supported, peer
> port_no = {'buf': '\xe7\x6b', 'val': 59243}
> - hw_addr = '\x52\x54\x54\x10\x20\x99'
> + hw_addr = '52:54:54:10:20:99'
> name = 'name'.ljust(16)
> config = {'buf': '\x84\xb6\x8c\x53', 'val': 2226555987}
> state = {'buf': '\x64\x07\xfb\xc9', 'val': 1678244809}
> @@ -43,7 +44,7 @@ class TestOFPPhyPort(unittest.TestCase):
> peer = {'buf': '\xa4\x5b\x8b\xed', 'val': 2757463021}
>
> buf = port_no['buf'] \
> - + hw_addr \
> + + addrconv.mac.text_to_bin(hw_addr) \
> + name \
> + config['buf'] \
> + state['buf'] \
> @@ -3384,7 +3385,7 @@ class TestOFPSwitchFeatures(unittest.TestCase):
> # '!H6s16sIIIIII'... port_no, hw_addr, name, config, state
> # curr, advertised, supported, peer
> port_no = {'buf': '\xe7\x6b', 'val': 59243}
> - hw_addr = '\x3c\xd1\x2b\x8d\x3f\xd6'
> + hw_addr = '3c:d1:2b:8d:3f:d6'
> name = 'name'.ljust(16)
> config = {'buf': '\x84\xb6\x8c\x53', 'val': 2226555987}
> state = {'buf': '\x64\x07\xfb\xc9', 'val': 1678244809}
> @@ -3404,7 +3405,7 @@ class TestOFPSwitchFeatures(unittest.TestCase):
> + capabilities['buf'] \
> + actions['buf'] \
> + port_no['buf'] \
> - + hw_addr \
> + + addrconv.mac.text_to_bin(hw_addr) \
> + name \
> + config['buf'] \
> + state['buf'] \
> @@ -3433,7 +3434,7 @@ class TestOFPSwitchFeatures(unittest.TestCase):
> # port
> port = res.ports[port_no['val']]
> eq_(port_no['val'], port.port_no)
> - eq_(hw_addr, port.hw_addr)
> + eq_(hw_addr, hw_addr)
> eq_(name, port.name)
> eq_(config['val'], port.config)
> eq_(state['val'], port.state)
> @@ -3480,7 +3481,7 @@ class TestOFPPortStatus(unittest.TestCase):
> reason = {'buf': '\x71', 'val': 113}
> zfill = '\x00' * 7
> port_no = {'buf': '\x48\xd8', 'val': 18648}
> - hw_addr = '\x41\xf7\xa3\x52\x8f\x6b'
> + hw_addr = '41:f7:a3:52:8f:6b'
> name = 'name'.ljust(16)
> config = {'buf': '\xae\x73\x90\xec', 'val': 2926809324}
> state = {'buf': '\x41\x37\x32\x1d', 'val': 1094136349}
> @@ -3496,7 +3497,7 @@ class TestOFPPortStatus(unittest.TestCase):
> + reason['buf'] \
> + zfill \
> + port_no['buf'] \
> - + hw_addr \
> + + addrconv.mac.text_to_bin(hw_addr) \
> + name \
> + config['buf'] \
> + state['buf'] \
>
> ------------------------------------------------------------------------------
> Introducing Performance Central, a new site from SourceForge and
> AppDynamics. Performance Central is your source for news, insights,
> analysis and resources for efficient Application Performance Management.
> Visit us today!
> http://pubads.g.doubleclick.net/gampad/clk?id=48897511&iu=/4140/ostg.clktrk
> _______________________________________________
> Ryu-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/ryu-devel
------------------------------------------------------------------------------
Introducing Performance Central, a new site from SourceForge and
AppDynamics. Performance Central is your source for news, insights,
analysis and resources for efficient Application Performance Management.
Visit us today!
http://pubads.g.doubleclick.net/gampad/clk?id=48897511&iu=/4140/ostg.clktrk
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel