> On Fri, 23 Aug 2013 13:42:54 +0900 (JST)
> yamam...@valinux.co.jp (YAMAMOTO Takashi) wrote:
> 
>>> On Fri, 23 Aug 2013 12:18:31 +0900 (JST)
>>> yamam...@valinux.co.jp (YAMAMOTO Takashi) wrote:
>>> 
>>>>> On Fri, 16 Aug 2013 15:29:22 +0900
>>>>> YAMAMOTO Takashi <yamam...@valinux.co.jp> wrote:
>>>>> 
>>>>>> Signed-off-by: YAMAMOTO Takashi <yamam...@valinux.co.jp>
>>>>>> ---
>>>>>>  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
> Ryu-devel@lists.sourceforge.net
> 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
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to