mirror of
https://github.com/msgpack/msgpack-python.git
synced 2025-10-22 05:13:17 +00:00
fallback: Support pack_ext_type.
This commit is contained in:
parent
27f0cba8a5
commit
aa68c9b833
4 changed files with 53 additions and 23 deletions
|
@ -210,7 +210,7 @@ cdef class Packer(object):
|
||||||
def handle_unknown_type(self, obj):
|
def handle_unknown_type(self, obj):
|
||||||
return None
|
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_ext(&self.pk, typecode, len(data))
|
||||||
msgpack_pack_raw_body(&self.pk, data, len(data))
|
msgpack_pack_raw_body(&self.pk, data, len(data))
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,6 @@ cdef extern from "unpack.h":
|
||||||
msgpack_user user
|
msgpack_user user
|
||||||
PyObject* obj
|
PyObject* obj
|
||||||
size_t count
|
size_t count
|
||||||
unsigned int ct
|
|
||||||
PyObject* key
|
|
||||||
|
|
||||||
ctypedef int (*execute_fn)(unpack_context* ctx, const char* data,
|
ctypedef int (*execute_fn)(unpack_context* ctx, const char* data,
|
||||||
size_t len, size_t* off) except? -1
|
size_t len, size_t* off) except? -1
|
||||||
|
|
|
@ -42,11 +42,11 @@ else:
|
||||||
newlist_hint = lambda size: []
|
newlist_hint = lambda size: []
|
||||||
|
|
||||||
from msgpack.exceptions import (
|
from msgpack.exceptions import (
|
||||||
BufferFull,
|
BufferFull,
|
||||||
OutOfData,
|
OutOfData,
|
||||||
UnpackValueError,
|
UnpackValueError,
|
||||||
PackValueError,
|
PackValueError,
|
||||||
ExtraData)
|
ExtraData)
|
||||||
|
|
||||||
from msgpack import ExtType
|
from msgpack import ExtType
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ TYPE_EXT = 5
|
||||||
|
|
||||||
DEFAULT_RECURSE_LIMIT = 511
|
DEFAULT_RECURSE_LIMIT = 511
|
||||||
|
|
||||||
|
|
||||||
def unpack(stream, **kwargs):
|
def unpack(stream, **kwargs):
|
||||||
"""
|
"""
|
||||||
Unpack an object from `stream`.
|
Unpack an object from `stream`.
|
||||||
|
@ -78,6 +79,7 @@ def unpack(stream, **kwargs):
|
||||||
raise ExtraData(ret, unpacker._fb_get_extradata())
|
raise ExtraData(ret, unpacker._fb_get_extradata())
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def unpackb(packed, **kwargs):
|
def unpackb(packed, **kwargs):
|
||||||
"""
|
"""
|
||||||
Unpack an object from `packed`.
|
Unpack an object from `packed`.
|
||||||
|
@ -95,6 +97,7 @@ def unpackb(packed, **kwargs):
|
||||||
raise ExtraData(ret, unpacker._fb_get_extradata())
|
raise ExtraData(ret, unpacker._fb_get_extradata())
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
class Unpacker(object):
|
class Unpacker(object):
|
||||||
"""
|
"""
|
||||||
Streaming unpacker.
|
Streaming unpacker.
|
||||||
|
@ -548,8 +551,8 @@ class Packer(object):
|
||||||
if isinstance(obj, Unicode):
|
if isinstance(obj, Unicode):
|
||||||
if self._encoding is None:
|
if self._encoding is None:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"Can't encode unicode string: "
|
"Can't encode unicode string: "
|
||||||
"no encoding is specified")
|
"no encoding is specified")
|
||||||
obj = obj.encode(self._encoding, self._unicode_errors)
|
obj = obj.encode(self._encoding, self._unicode_errors)
|
||||||
n = len(obj)
|
n = len(obj)
|
||||||
if n <= 0x1f:
|
if n <= 0x1f:
|
||||||
|
@ -616,6 +619,35 @@ class Packer(object):
|
||||||
self._buffer = StringIO(ret)
|
self._buffer = StringIO(ret)
|
||||||
return 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):
|
def _fb_pack_array_header(self, n):
|
||||||
if n <= 0x0f:
|
if n <= 0x0f:
|
||||||
return self._buffer.write(struct.pack('B', 0x90 + n))
|
return self._buffer.write(struct.pack('B', 0x90 + n))
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import py
|
|
||||||
import array
|
import array
|
||||||
import struct
|
|
||||||
import msgpack
|
import msgpack
|
||||||
|
|
||||||
def test_pack_extended_type():
|
|
||||||
|
def test_pack_ext_type():
|
||||||
def p(s):
|
def p(s):
|
||||||
packer = msgpack.Packer()
|
packer = msgpack.Packer()
|
||||||
packer.pack_extended_type(0x42, s)
|
packer.pack_ext_type(0x42, s)
|
||||||
return packer.bytes()
|
return packer.bytes()
|
||||||
assert p('A') == '\xd4\x42A' # fixext 1
|
assert p(b'A') == b'\xd4\x42A' # fixext 1
|
||||||
assert p('AB') == '\xd5\x42AB' # fixext 2
|
assert p(b'AB') == b'\xd5\x42AB' # fixext 2
|
||||||
assert p('ABCD') == '\xd6\x42ABCD' # fixext 4
|
assert p(b'ABCD') == b'\xd6\x42ABCD' # fixext 4
|
||||||
assert p('ABCDEFGH') == '\xd7\x42ABCDEFGH' # fixext 8
|
assert p(b'ABCDEFGH') == b'\xd7\x42ABCDEFGH' # fixext 8
|
||||||
assert p('A'*16) == '\xd8\x42' + 'A'*16 # fixext 16
|
assert p(b'A'*16) == b'\xd8\x42' + 'A'*16 # fixext 16
|
||||||
assert p('ABC') == '\xc7\x03\x42ABC' # ext 8
|
assert p(b'ABC') == b'\xc7\x03\x42ABC' # ext 8
|
||||||
assert p('A'*0x0123) == '\xc8\x01\x23\x42' + 'A'*0x0123 # ext 16
|
assert p(b'A'*0x0123) == b'\xc8\x01\x23\x42' + b'A'*0x0123 # ext 16
|
||||||
assert p('A'*0x00012345) == '\xc9\x00\x01\x23\x45\x42' + 'A'*0x00012345 # ext 32
|
assert p(b'A'*0x00012345) == b'\xc9\x00\x01\x23\x45\x42' + b'A'*0x00012345 # ext 32
|
||||||
|
|
||||||
|
|
||||||
def test_unpack_extended_type():
|
def test_unpack_extended_type():
|
||||||
class MyUnpacker(msgpack.Unpacker):
|
class MyUnpacker(msgpack.Unpacker):
|
||||||
|
@ -45,7 +45,7 @@ def test_extension_type():
|
||||||
if isinstance(obj, array.array):
|
if isinstance(obj, array.array):
|
||||||
typecode = 123 # application specific typecode
|
typecode = 123 # application specific typecode
|
||||||
data = obj.tostring()
|
data = obj.tostring()
|
||||||
self.pack_extended_type(typecode, data)
|
self.pack_ext_type(typecode, data)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class MyUnpacker(msgpack.Unpacker):
|
class MyUnpacker(msgpack.Unpacker):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue