@@ -48,6 +48,9 @@ def getvalue(self):
48
48
PackValueError ,
49
49
ExtraData )
50
50
51
+ from msgpack import ExtType
52
+
53
+
51
54
EX_SKIP = 0
52
55
EX_CONSTRUCT = 1
53
56
EX_READ_ARRAY_HEADER = 2
@@ -58,8 +61,9 @@ def getvalue(self):
58
61
TYPE_MAP = 2
59
62
TYPE_RAW = 3
60
63
TYPE_BIN = 4
64
+ TYPE_EXT = 5
61
65
62
- DEFAULT_RECURSE_LIMIT = 511
66
+ DEFAULT_RECURSE_LIMIT = 511
63
67
64
68
def unpack (stream , ** kwargs ):
65
69
"""
@@ -112,6 +116,9 @@ class Unpacker(object):
112
116
should be callable and Unpacker calls it with a list of key-value pairs
113
117
after deserializing a map.
114
118
119
+ `ext_hook` is callback for ext (User defined) type. It called with two
120
+ arguments: (code, bytes). default: `msgpack.ExtType`
121
+
115
122
`encoding` is the encoding used for decoding msgpack bytes. If it is
116
123
None (default), msgpack bytes are deserialized to Python bytes.
117
124
@@ -143,7 +150,8 @@ class Unpacker(object):
143
150
144
151
def __init__ (self , file_like = None , read_size = 0 , use_list = True ,
145
152
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 ):
147
155
if file_like is None :
148
156
self ._fb_feeding = True
149
157
else :
@@ -167,6 +175,7 @@ def __init__(self, file_like=None, read_size=0, use_list=True,
167
175
self ._list_hook = list_hook
168
176
self ._object_hook = object_hook
169
177
self ._object_pairs_hook = object_pairs_hook
178
+ self ._ext_hook = ext_hook
170
179
171
180
if list_hook is not None and not callable (list_hook ):
172
181
raise ValueError ('`list_hook` is not callable' )
@@ -177,6 +186,8 @@ def __init__(self, file_like=None, read_size=0, use_list=True,
177
186
if object_hook is not None and object_pairs_hook is not None :
178
187
raise ValueError ("object_pairs_hook and object_hook are mutually "
179
188
"exclusive" )
189
+ if not callable (ext_hook ):
190
+ raise ValueError ("`ext_hook` is not callable" )
180
191
181
192
def feed (self , next_bytes ):
182
193
if isinstance (next_bytes , array .array ):
@@ -278,6 +289,30 @@ def _read_header(self, execute=EX_CONSTRUCT, write_bytes=None):
278
289
obj = False
279
290
elif b == 0xc3 :
280
291
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 )
281
316
elif b == 0xca :
282
317
obj = struct .unpack (">f" , self ._fb_read (4 , write_bytes ))[0 ]
283
318
elif b == 0xcb :
@@ -298,30 +333,33 @@ def _read_header(self, execute=EX_CONSTRUCT, write_bytes=None):
298
333
obj = struct .unpack (">i" , self ._fb_read (4 , write_bytes ))[0 ]
299
334
elif b == 0xd3 :
300
335
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 ))
301
351
elif b == 0xd9 :
352
+ typ = TYPE_RAW
302
353
n = struct .unpack ("B" , self ._fb_read (1 , write_bytes ))[0 ]
303
354
obj = self ._fb_read (n , write_bytes )
304
- typ = TYPE_RAW
305
355
elif b == 0xda :
356
+ typ = TYPE_RAW
306
357
n = struct .unpack (">H" , self ._fb_read (2 , write_bytes ))[0 ]
307
358
obj = self ._fb_read (n , write_bytes )
308
- typ = TYPE_RAW
309
359
elif b == 0xdb :
310
- n = struct .unpack (">I" , self ._fb_read (4 , write_bytes ))[0 ]
311
- obj = self ._fb_read (n , write_bytes )
312
360
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 :
322
361
n = struct .unpack (">I" , self ._fb_read (4 , write_bytes ))[0 ]
323
362
obj = self ._fb_read (n , write_bytes )
324
- typ = TYPE_BIN
325
363
elif b == 0xdc :
326
364
n = struct .unpack (">H" , self ._fb_read (2 , write_bytes ))[0 ]
327
365
typ = TYPE_ARRAY
@@ -390,6 +428,8 @@ def _fb_unpack(self, execute=EX_CONSTRUCT, write_bytes=None):
390
428
if self ._encoding is not None :
391
429
obj = obj .decode (self ._encoding , self ._unicode_errors )
392
430
return obj
431
+ if typ == TYPE_EXT :
432
+ return self ._ext_hook (n , obj )
393
433
if typ == TYPE_BIN :
394
434
return obj
395
435
assert typ == TYPE_IMMEDIATE
0 commit comments