> 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