def test_transform_cbor_with_nested_link_to_dict(): src = dumps( { 'num': 1, 'hello': 'world', 'l1': Tag(LINK_TAG, 'takemedowntotheparadisecity'), 'secret': { 'l1': Tag(LINK_TAG, 'Ihhh ein Sekret!') }, }, sort_keys=True) expected = { 'hello': 'world', 'num': 1, 'l1': { '/': 'takemedowntotheparadisecity', }, 'secret': { 'l1': { '/': 'Ihhh ein Sekret!', }, }, } assert unmarshal(src) == expected
def transform(di): for k, v in di.items(): if isinstance(v, dict): di[k] = transform(v) if LINK_SYMBOL in di.keys(): # TODO: Support: https://github.com/jbenet/js-multiaddr link = di[LINK_SYMBOL] di.pop(LINK_SYMBOL, None) if len(di.keys()) > 1: raise KeyError('Links must not have siblings') return Tag(LINK_TAG, link) return di
def test_transform_cbor_to_dict_with_multiaddr(): addr1 = Multiaddr('/ip4/127.0.0.1/udp/1234') addr2 = Multiaddr('/ipfs/Qmafmh1Cw3H1bwdYpaaj5AbCW4LkYyUWaM7Nykpn5NZoYL') src = dumps({ 'data': 'hello world', 'size': 11, 'l1': Tag(LINK_TAG, addr1.to_bytes()), 'l2': Tag(LINK_TAG, addr2.to_bytes()), }, sort_keys=True) expected = { 'data': 'hello world', 'size': 11, 'l1': { '/': str(addr1), }, 'l2': { '/': str(addr2), } } assert unmarshal(src) == expected
def test_transform_dict_with_link_to_cbor(): src = { 'hello': 'world', 'num': 1, 'l1': { '/': 'takemedowntotheparadisecity', }, } expected = { 'num': 1, 'hello': 'world', 'l1': Tag(LINK_TAG, 'takemedowntotheparadisecity'), } assert marshal(src) == dumps(expected, sort_keys=True)
def transform(di): for k, v in di.items(): if isinstance(v, dict): di[k] = transform(v) if LINK_SYMBOL in di: link = di.pop(LINK_SYMBOL) try: link = Multiaddr(link).to_bytes() except ValueError: pass if di: raise KeyError('Links must not have siblings') return Tag(LINK_TAG, link) return di
def extract_cbor_values(msg): """Extract a dictionary of CBOR-friendly values from a ROS message. Primitive values will be casted to specific Python primitives. Typed arrays will be tagged and packed into byte arrays. """ out = {} for slot, slot_type in zip(msg.__slots__, msg._slot_types): val = getattr(msg, slot) if PYTHON2: slot = unicode(slot) # noqa: F821 # string if slot_type in STRING_TYPES: out[slot] = unicode(val) if PYTHON2 else str(val) # noqa: F821 # bool elif slot_type in BOOL_TYPES: out[slot] = bool(val) # integers elif slot_type in INT_TYPES: out[slot] = int(val) # floats elif slot_type in FLOAT_TYPES: out[slot] = float(val) # time/duration elif slot_type in TIME_TYPES: out[slot] = { 'secs': int(val.secs), 'nsecs': int(val.nsecs), } # byte array elif slot_type in BYTESTREAM_TYPES: if PYTHON2: out[slot] = bytes(bytearray(val)) else: out[slot] = bytes(val) # bool array elif slot_type in BOOL_ARRAY_TYPES: out[slot] = [bool(i) for i in val] # numeric arrays elif slot_type in TAGGED_ARRAY_FORMATS: tag, fmt = TAGGED_ARRAY_FORMATS[slot_type] fmt_to_length = fmt.format(len(val)) packed = struct.pack(fmt_to_length, *val) out[slot] = Tag(tag=tag, value=packed) # array of messages elif type(val) in LIST_TYPES: out[slot] = [extract_cbor_values(i) for i in val] # message else: out[slot] = extract_cbor_values(val) return out