Skip to content

Commit aa68c9b

Browse files
committed
fallback: Support pack_ext_type.
1 parent 27f0cba commit aa68c9b

File tree

4 files changed

+53
-23
lines changed

4 files changed

+53
-23
lines changed

msgpack/_packer.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ cdef class Packer(object):
210210
def handle_unknown_type(self, obj):
211211
return None
212212

213-
def pack_extended_type(self, typecode, data):
213+
def pack_ext_type(self, typecode, data):
214214
msgpack_pack_ext(&self.pk, typecode, len(data))
215215
msgpack_pack_raw_body(&self.pk, data, len(data))
216216

msgpack/_unpacker.pyx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@ cdef extern from "unpack.h":
3232
msgpack_user user
3333
PyObject* obj
3434
size_t count
35-
unsigned int ct
36-
PyObject* key
3735

3836
ctypedef int (*execute_fn)(unpack_context* ctx, const char* data,
3937
size_t len, size_t* off) except? -1

msgpack/fallback.py

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ def getvalue(self):
4242
newlist_hint = lambda size: []
4343

4444
from msgpack.exceptions import (
45-
BufferFull,
46-
OutOfData,
47-
UnpackValueError,
48-
PackValueError,
49-
ExtraData)
45+
BufferFull,
46+
OutOfData,
47+
UnpackValueError,
48+
PackValueError,
49+
ExtraData)
5050

5151
from msgpack import ExtType
5252

@@ -65,6 +65,7 @@ def getvalue(self):
6565

6666
DEFAULT_RECURSE_LIMIT = 511
6767

68+
6869
def unpack(stream, **kwargs):
6970
"""
7071
Unpack an object from `stream`.
@@ -78,6 +79,7 @@ def unpack(stream, **kwargs):
7879
raise ExtraData(ret, unpacker._fb_get_extradata())
7980
return ret
8081

82+
8183
def unpackb(packed, **kwargs):
8284
"""
8385
Unpack an object from `packed`.
@@ -95,6 +97,7 @@ def unpackb(packed, **kwargs):
9597
raise ExtraData(ret, unpacker._fb_get_extradata())
9698
return ret
9799

100+
98101
class Unpacker(object):
99102
"""
100103
Streaming unpacker.
@@ -548,8 +551,8 @@ def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, isinstance=isinstance):
548551
if isinstance(obj, Unicode):
549552
if self._encoding is None:
550553
raise TypeError(
551-
"Can't encode unicode string: "
552-
"no encoding is specified")
554+
"Can't encode unicode string: "
555+
"no encoding is specified")
553556
obj = obj.encode(self._encoding, self._unicode_errors)
554557
n = len(obj)
555558
if n <= 0x1f:
@@ -616,6 +619,35 @@ def pack_map_header(self, n):
616619
self._buffer = StringIO(ret)
617620
return ret
618621

622+
def pack_ext_type(self, typecode, data):
623+
if not isinstance(typecode, int):
624+
raise TypeError("typecode must have int type.")
625+
if not 0 <= typecode <= 127:
626+
raise ValueError("typecode should be 0-127")
627+
if not isinstance(data, bytes):
628+
raise TypeError("data must have bytes type")
629+
L = len(data)
630+
if L > 0xffffffff:
631+
raise ValueError("Too large data")
632+
if L == 1:
633+
self._buffer.write(b'\xd4')
634+
elif L == 2:
635+
self._buffer.write(b'\xd5')
636+
elif L == 4:
637+
self._buffer.write(b'\xd6')
638+
elif L == 8:
639+
self._buffer.write(b'\xd7')
640+
elif L == 16:
641+
self._buffer.write(b'\xd8')
642+
elif L <= 0xff:
643+
self._buffer.write(b'\xc7' + struct.pack('B', L))
644+
elif L <= 0xffff:
645+
self._buffer.write(b'\xc8' + struct.pack('>H', L))
646+
else:
647+
self._buffer.write(b'\xc9' + struct.pack('>I', L))
648+
self._buffer.write(struct.pack('B', typecode))
649+
self._buffer.write(data)
650+
619651
def _fb_pack_array_header(self, n):
620652
if n <= 0x0f:
621653
return self._buffer.write(struct.pack('B', 0x90 + n))

test/test_extension.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
1-
import py
21
import array
3-
import struct
42
import msgpack
53

6-
def test_pack_extended_type():
4+
5+
def test_pack_ext_type():
76
def p(s):
87
packer = msgpack.Packer()
9-
packer.pack_extended_type(0x42, s)
8+
packer.pack_ext_type(0x42, s)
109
return packer.bytes()
11-
assert p('A') == '\xd4\x42A' # fixext 1
12-
assert p('AB') == '\xd5\x42AB' # fixext 2
13-
assert p('ABCD') == '\xd6\x42ABCD' # fixext 4
14-
assert p('ABCDEFGH') == '\xd7\x42ABCDEFGH' # fixext 8
15-
assert p('A'*16) == '\xd8\x42' + 'A'*16 # fixext 16
16-
assert p('ABC') == '\xc7\x03\x42ABC' # ext 8
17-
assert p('A'*0x0123) == '\xc8\x01\x23\x42' + 'A'*0x0123 # ext 16
18-
assert p('A'*0x00012345) == '\xc9\x00\x01\x23\x45\x42' + 'A'*0x00012345 # ext 32
10+
assert p(b'A') == b'\xd4\x42A' # fixext 1
11+
assert p(b'AB') == b'\xd5\x42AB' # fixext 2
12+
assert p(b'ABCD') == b'\xd6\x42ABCD' # fixext 4
13+
assert p(b'ABCDEFGH') == b'\xd7\x42ABCDEFGH' # fixext 8
14+
assert p(b'A'*16) == b'\xd8\x42' + 'A'*16 # fixext 16
15+
assert p(b'ABC') == b'\xc7\x03\x42ABC' # ext 8
16+
assert p(b'A'*0x0123) == b'\xc8\x01\x23\x42' + b'A'*0x0123 # ext 16
17+
assert p(b'A'*0x00012345) == b'\xc9\x00\x01\x23\x45\x42' + b'A'*0x00012345 # ext 32
18+
1919

2020
def test_unpack_extended_type():
2121
class MyUnpacker(msgpack.Unpacker):
@@ -45,7 +45,7 @@ def handle_unknown_type(self, obj):
4545
if isinstance(obj, array.array):
4646
typecode = 123 # application specific typecode
4747
data = obj.tostring()
48-
self.pack_extended_type(typecode, data)
48+
self.pack_ext_type(typecode, data)
4949
return True
5050

5151
class MyUnpacker(msgpack.Unpacker):

0 commit comments

Comments
 (0)