8000 Add ext type support to fallback.Unpacker. · zhurs/msgpack-python@d943920 · GitHub
[go: up one dir, main page]

Skip to content

Commit d943920

Browse files
committed
Add ext type support to fallback.Unpacker.
1 parent f162bf6 commit d943920

File tree

2 files changed

+60
-16
lines changed

2 files changed

+60
-16
lines changed

msgpack/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
from msgpack._version import version
33
from msgpack.exceptions import *
44

5+
from collections import namedtuple
6+
7+
ExtType = namedtuple('ExtType', 'code data')
8+
59
import os
610
if os.environ.get('MSGPACK_PUREPYTHON'):
711
from msgpack.fallback import Packer, unpack, unpackb, Unpacker

msgpack/fallback.py

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ def getvalue(self):
4848
PackValueError,
4949
ExtraData)
5050

51+
from msgpack import ExtType
52+
53+
5154
EX_SKIP = 0
5255
EX_CONSTRUCT = 1
5356
EX_READ_ARRAY_HEADER = 2
@@ -58,8 +61,9 @@ def getvalue(self):
5861
TYPE_MAP = 2
5962
TYPE_RAW = 3
6063
TYPE_BIN = 4
64+
TYPE_EXT = 5
6165

62-
DEFAULT_RECURSE_LIMIT=511
66+
DEFAULT_RECURSE_LIMIT = 511
6367

6468
def unpack(stream, **kwargs):
6569
"""
@@ -112,6 +116,9 @@ class Unpacker(object):
112116
should be callable and Unpacker calls it with a list of key-value pairs
113117
after deserializing a map.
114118
119+
`ext_hook` is callback for ext (User defined) type. It called with two
120+
arguments: (code, bytes). default: `msgpack.ExtType`
121+
115122
`encoding` is the encoding used for decoding msgpack bytes. If it is
116123
None (default), msgpack bytes are deserialized to Python bytes.
117124
@@ -143,7 +150,8 @@ class Unpacker(object):
143150

144151
def __init__(self, file_like=None, read_size=0, use_list=True,
145152
object_hook=None, object_pairs_hook=None, list_hook=None,
146-
encoding=None, unicode_errors='strict', max_buffer_size=0):
153+
encoding=None, unicode_errors='strict', max_buffer_size=0,
154+
ext_hook=ExtType):
147155
if file_like is None:
148156
self._fb_feeding = True
149157
else:
@@ -167,6 +175,7 @@ def __init__(self, file_like=None, read_size=0, use_list=True,
167175
self._list_hook = list_hook
168176
self._object_hook = object_hook
169177
self._object_pairs_hook = object_pairs_hook
178+
self._ext_hook = ext_hook
170179

171180
if list_hook is not None and not callable(list_hook):
172181
raise ValueError('`list_hook` is not callable')
@@ -177,6 +186,8 @@ def __init__(self, file_like=None, read_size=0, use_list=True,
177186
if object_hook is not None and object_pairs_hook is not None:
178187
raise ValueError("object_pairs_hook and object_hook are mutually "
179188
"exclusive")
189+
if not callable(ext_hook):
190+
raise ValueError("`ext_hook` is not callable")
180191

181192
def feed(self, next_bytes):
182193
if isinstance(next_bytes, array.array):
@@ -278,6 +289,30 @@ def _read_header(self, execute=EX_CONSTRUCT, write_bytes=None):
278289
obj = False
279290
elif b == 0xc3:
280291
obj = True
292+
elif b == 0xc4:
293+
typ = TYPE_BIN
294+
n = struct.unpack("B", self._fb_read(1, write_bytes))[0]
295+
obj = self._fb_read(n, write_bytes)
296+
elif b == 0xc5:
297+
typ = TYPE_BIN
298+
n = struct.unpack(">H", self._fb_read(2, write_bytes))[0]
299+
obj = self._fb_read(n, write_bytes)
300+
elif b == 0xc6:
301+
typ = TYPE_BIN
302+
n = struct.unpack(">I", self._fb_read(4, write_bytes))[0]
303+
obj = self._fb_read(n, write_bytes)
304+
elif b == 0xc7: # ext 8
305+
typ = TYPE_EXT
306+
L, n = struct.unpack('Bb', self._fb_read(2, write_bytes))
307+
obj = self._fb_read(L, write_bytes)
308+
elif b == 0xc8: # ext 16
309+
typ = TYPE_EXT
310+
L, n = struct.unpack('>Hb', self._fb_read(3, write_bytes))
311+
obj = self._fb_read(L, write_bytes)
312+
elif b == 0xc9: # ext 32
313+
typ = TYPE_EXT
314+
L, n = struct.unpack('>Ib', self._fb_read(5, write_bytes))
315+
obj = self._fb_read(L, write_bytes)
281316
elif b == 0xca:
282317
obj = struct.unpack(">f", self._fb_read(4, write_bytes))[0]
283318
elif b == 0xcb:
@@ -298,30 +333,33 @@ def _read_header(self, execute=EX_CONSTRUCT, write_bytes=None):
298333
obj = struct.unpack(">i", self._fb_read(4, write_bytes))[0]
299334
elif b == 0xd3:
300335
obj = struct.unpack(">q", self._fb_read(8, write_bytes))[0]
336+
elif b == 0xd4: # fixext 1
337+
typ = TYPE_EXT
338+
n, obj = struct.unpack('b1s', self._fb_read(2, write_bytes))
339+
elif b == 0xd5: # fixext 2
340+
typ = TYPE_EXT
341+
n, obj = struct.unpack('b2s', self._fb_read(3, write_bytes))
342+
elif b == 0xd6: # fixext 4
343+
typ = TYPE_EXT
344+
n, obj = struct.unpack('b4s', self._fb_read(5, write_bytes))
345+
elif b == 0xd7: # fixext 8
346+
typ = TYPE_EXT
347+
n, obj = struct.unpack('b8s', self._fb_read(9, write_bytes))
348+
elif b == 0xd8: # fixext 16
349+
typ = TYPE_EXT
350+
n, obj = struct.unpack('b16s', self._fb_read(17, write_bytes))
301351
elif b == 0xd9:
352+
typ = TYPE_RAW
302353
n = struct.unpack("B", self._fb_read(1, write_bytes))[0]
303354
obj = self._fb_read(n, write_bytes)
304-
typ = TYPE_RAW
305355
elif b == 0xda:
356+
typ = TYPE_RAW
306357
n = struct.unpack(">H", self._fb_read(2, write_bytes))[0]
307358
obj = self._fb_read(n, write_bytes)
308-
typ = TYPE_RAW
309359
elif b == 0xdb:
310-
n = struct.unpack(">I", self._fb_read(4, write_bytes))[0]
311-
obj = self._fb_read(n, write_bytes)
312360
typ = TYPE_RAW
313-
elif b == 0xc4:
314-
n = struct.unpack("B", self._fb_read(1, write_bytes))[0]
315-
obj = self._fb_read(n, write_bytes)
316-
typ = TYPE_BIN
317-
elif b == 0xc5:
318-
n = struct.unpack(">H", self._fb_read(2, write_bytes))[0]
319-
obj = self._fb_read(n, write_bytes)
320-
typ = TYPE_BIN
321-
elif b == 0xc6:
322361
n = struct.unpack(">I", self._fb_read(4, write_bytes))[0]
323362
obj = self._fb_read(n, write_bytes)
324-
typ = TYPE_BIN
325363
elif b == 0xdc:
326364
n = struct.unpack(">H", self._fb_read(2, write_bytes))[0]
327365
typ = TYPE_ARRAY
@@ -390,6 +428,8 @@ def _fb_unpack(self, execute=EX_CONSTRUCT, write_bytes=None):
390428
if self._encoding is not None:
391429
obj = obj.decode(self._encoding, self._unicode_errors)
392430
return obj
431+
if typ == TYPE_EXT:
432+
return self._ext_hook(n, obj)
393433
if typ == TYPE_BIN:
394434
return obj
395435
assert typ == TYPE_IMMEDIATE

0 commit comments

Comments
 (0)
0