diff options
author | INADA Naoki <inada-n@klab.com> | 2013-10-20 15:40:20 +0900 |
---|---|---|
committer | INADA Naoki <inada-n@klab.com> | 2013-10-20 15:40:20 +0900 |
commit | aa68c9b8330b130d600b22ec47d5c3841499b536 (patch) | |
tree | 85fd0c30d69180b2afa1602b40bb4775ddf12459 | |
parent | 27f0cba8a5f36393517ee85d2c339847b76e0c6b (diff) | |
download | msgpack-python-aa68c9b8330b130d600b22ec47d5c3841499b536.tar.gz |
fallback: Support pack_ext_type.
-rw-r--r-- | msgpack/_packer.pyx | 2 | ||||
-rw-r--r-- | msgpack/_unpacker.pyx | 2 | ||||
-rw-r--r-- | msgpack/fallback.py | 46 | ||||
-rw-r--r-- | test/test_extension.py | 26 |
4 files changed, 53 insertions, 23 deletions
diff --git a/msgpack/_packer.pyx b/msgpack/_packer.pyx index df670ed..f033263 100644 --- a/msgpack/_packer.pyx +++ b/msgpack/_packer.pyx @@ -210,7 +210,7 @@ cdef class Packer(object): def handle_unknown_type(self, obj): return None - def pack_extended_type(self, typecode, data): + def pack_ext_type(self, typecode, data): msgpack_pack_ext(&self.pk, typecode, len(data)) msgpack_pack_raw_body(&self.pk, data, len(data)) diff --git a/msgpack/_unpacker.pyx b/msgpack/_unpacker.pyx index cf30670..b0e66db 100644 --- a/msgpack/_unpacker.pyx +++ b/msgpack/_unpacker.pyx @@ -32,8 +32,6 @@ cdef extern from "unpack.h": msgpack_user user PyObject* obj size_t count - unsigned int ct - PyObject* key ctypedef int (*execute_fn)(unpack_context* ctx, const char* data, size_t len, size_t* off) except? -1 diff --git a/msgpack/fallback.py b/msgpack/fallback.py index dfaaa54..0b29700 100644 --- a/msgpack/fallback.py +++ b/msgpack/fallback.py @@ -42,11 +42,11 @@ else: newlist_hint = lambda size: [] from msgpack.exceptions import ( - BufferFull, - OutOfData, - UnpackValueError, - PackValueError, - ExtraData) + BufferFull, + OutOfData, + UnpackValueError, + PackValueError, + ExtraData) from msgpack import ExtType @@ -65,6 +65,7 @@ TYPE_EXT = 5 DEFAULT_RECURSE_LIMIT = 511 + def unpack(stream, **kwargs): """ Unpack an object from `stream`. @@ -78,6 +79,7 @@ def unpack(stream, **kwargs): raise ExtraData(ret, unpacker._fb_get_extradata()) return ret + def unpackb(packed, **kwargs): """ Unpack an object from `packed`. @@ -95,6 +97,7 @@ def unpackb(packed, **kwargs): raise ExtraData(ret, unpacker._fb_get_extradata()) return ret + class Unpacker(object): """ Streaming unpacker. @@ -548,8 +551,8 @@ class Packer(object): if isinstance(obj, Unicode): if self._encoding is None: raise TypeError( - "Can't encode unicode string: " - "no encoding is specified") + "Can't encode unicode string: " + "no encoding is specified") obj = obj.encode(self._encoding, self._unicode_errors) n = len(obj) if n <= 0x1f: @@ -616,6 +619,35 @@ class Packer(object): self._buffer = StringIO(ret) return ret + def pack_ext_type(self, typecode, data): + if not isinstance(typecode, int): + raise TypeError("typecode must have int type.") + if not 0 <= typecode <= 127: + raise ValueError("typecode should be 0-127") + if not isinstance(data, bytes): + raise TypeError("data must have bytes type") + L = len(data) + if L > 0xffffffff: + raise ValueError("Too large data") + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + self._buffer.write(b'\xd7') + elif L == 16: + self._buffer.write(b'\xd8') + elif L <= 0xff: + self._buffer.write(b'\xc7' + struct.pack('B', L)) + elif L <= 0xffff: + self._buffer.write(b'\xc8' + struct.pack('>H', L)) + else: + self._buffer.write(b'\xc9' + struct.pack('>I', L)) + self._buffer.write(struct.pack('B', typecode)) + self._buffer.write(data) + def _fb_pack_array_header(self, n): if n <= 0x0f: return self._buffer.write(struct.pack('B', 0x90 + n)) diff --git a/test/test_extension.py b/test/test_extension.py index 94117e1..f2fa363 100644 --- a/test/test_extension.py +++ b/test/test_extension.py @@ -1,21 +1,21 @@ -import py import array -import struct import msgpack -def test_pack_extended_type(): + +def test_pack_ext_type(): def p(s): packer = msgpack.Packer() - packer.pack_extended_type(0x42, s) + packer.pack_ext_type(0x42, s) return packer.bytes() - assert p('A') == '\xd4\x42A' # fixext 1 - assert p('AB') == '\xd5\x42AB' # fixext 2 - assert p('ABCD') == '\xd6\x42ABCD' # fixext 4 - assert p('ABCDEFGH') == '\xd7\x42ABCDEFGH' # fixext 8 - assert p('A'*16) == '\xd8\x42' + 'A'*16 # fixext 16 - assert p('ABC') == '\xc7\x03\x42ABC' # ext 8 - assert p('A'*0x0123) == '\xc8\x01\x23\x42' + 'A'*0x0123 # ext 16 - assert p('A'*0x00012345) == '\xc9\x00\x01\x23\x45\x42' + 'A'*0x00012345 # ext 32 + assert p(b'A') == b'\xd4\x42A' # fixext 1 + assert p(b'AB') == b'\xd5\x42AB' # fixext 2 + assert p(b'ABCD') == b'\xd6\x42ABCD' # fixext 4 + assert p(b'ABCDEFGH') == b'\xd7\x42ABCDEFGH' # fixext 8 + assert p(b'A'*16) == b'\xd8\x42' + 'A'*16 # fixext 16 + assert p(b'ABC') == b'\xc7\x03\x42ABC' # ext 8 + assert p(b'A'*0x0123) == b'\xc8\x01\x23\x42' + b'A'*0x0123 # ext 16 + assert p(b'A'*0x00012345) == b'\xc9\x00\x01\x23\x45\x42' + b'A'*0x00012345 # ext 32 + def test_unpack_extended_type(): class MyUnpacker(msgpack.Unpacker): @@ -45,7 +45,7 @@ def test_extension_type(): if isinstance(obj, array.array): typecode = 123 # application specific typecode data = obj.tostring() - self.pack_extended_type(typecode, data) + self.pack_ext_type(typecode, data) return True class MyUnpacker(msgpack.Unpacker): |