1"""Fallback pure Python implementation of msgpack"""
2
3import struct
4import sys
5from datetime import datetime as _DateTime
6
7if hasattr(sys, "pypy_version_info"):
8 from __pypy__ import newlist_hint
9 from __pypy__.builders import BytesBuilder
10
11 _USING_STRINGBUILDER = True
12
13 class BytesIO:
14 def __init__(self, s=b""):
15 if s:
16 self.builder = BytesBuilder(len(s))
17 self.builder.append(s)
18 else:
19 self.builder = BytesBuilder()
20
21 def write(self, s):
22 if isinstance(s, memoryview):
23 s = s.tobytes()
24 elif isinstance(s, bytearray):
25 s = bytes(s)
26 self.builder.append(s)
27
28 def getvalue(self):
29 return self.builder.build()
30
31else:
32 from io import BytesIO
33
34 _USING_STRINGBUILDER = False
35
36 def newlist_hint(size):
37 return []
38
39
40from .exceptions import BufferFull, ExtraData, FormatError, OutOfData, StackError
41from .ext import ExtType, Timestamp
42
43EX_SKIP = 0
44EX_CONSTRUCT = 1
45EX_READ_ARRAY_HEADER = 2
46EX_READ_MAP_HEADER = 3
47
48TYPE_IMMEDIATE = 0
49TYPE_ARRAY = 1
50TYPE_MAP = 2
51TYPE_RAW = 3
52TYPE_BIN = 4
53TYPE_EXT = 5
54
55DEFAULT_RECURSE_LIMIT = 511
56
57
58def _check_type_strict(obj, t, type=type, tuple=tuple):
59 if type(t) is tuple:
60 return type(obj) in t
61 else:
62 return type(obj) is t
63
64
65def _get_data_from_buffer(obj):
66 view = memoryview(obj)
67 if view.itemsize != 1:
68 raise ValueError("cannot unpack from multi-byte object")
69 return view
70
71
72def unpackb(packed, **kwargs):
73 """
74 Unpack an object from `packed`.
75
76 Raises ``ExtraData`` when *packed* contains extra bytes.
77 Raises ``ValueError`` when *packed* is incomplete.
78 Raises ``FormatError`` when *packed* is not valid msgpack.
79 Raises ``StackError`` when *packed* contains too nested.
80 Other exceptions can be raised during unpacking.
81
82 See :class:`Unpacker` for options.
83 """
84 unpacker = Unpacker(None, max_buffer_size=len(packed), **kwargs)
85 unpacker.feed(packed)
86 try:
87 ret = unpacker._unpack()
88 except OutOfData:
89 raise ValueError("Unpack failed: incomplete input")
90 except RecursionError:
91 raise StackError
92 if unpacker._got_extradata():
93 raise ExtraData(ret, unpacker._get_extradata())
94 return ret
95
96
97_NO_FORMAT_USED = ""
98_MSGPACK_HEADERS = {
99 0xC4: (1, _NO_FORMAT_USED, TYPE_BIN),
100 0xC5: (2, ">H", TYPE_BIN),
101 0xC6: (4, ">I", TYPE_BIN),
102 0xC7: (2, "Bb", TYPE_EXT),
103 0xC8: (3, ">Hb", TYPE_EXT),
104 0xC9: (5, ">Ib", TYPE_EXT),
105 0xCA: (4, ">f"),
106 0xCB: (8, ">d"),
107 0xCC: (1, _NO_FORMAT_USED),
108 0xCD: (2, ">H"),
109 0xCE: (4, ">I"),
110 0xCF: (8, ">Q"),
111 0xD0: (1, "b"),
112 0xD1: (2, ">h"),
113 0xD2: (4, ">i"),
114 0xD3: (8, ">q"),
115 0xD4: (1, "b1s", TYPE_EXT),
116 0xD5: (2, "b2s", TYPE_EXT),
117 0xD6: (4, "b4s", TYPE_EXT),
118 0xD7: (8, "b8s", TYPE_EXT),
119 0xD8: (16, "b16s", TYPE_EXT),
120 0xD9: (1, _NO_FORMAT_USED, TYPE_RAW),
121 0xDA: (2, ">H", TYPE_RAW),
122 0xDB: (4, ">I", TYPE_RAW),
123 0xDC: (2, ">H", TYPE_ARRAY),
124 0xDD: (4, ">I", TYPE_ARRAY),
125 0xDE: (2, ">H", TYPE_MAP),
126 0xDF: (4, ">I", TYPE_MAP),
127}
128
129
130class Unpacker:
131 """Streaming unpacker.
132
133 Arguments:
134
135 :param file_like:
136 File-like object having `.read(n)` method.
137 If specified, unpacker reads serialized data from it and `.feed()` is not usable.
138
139 :param int read_size:
140 Used as `file_like.read(read_size)`. (default: `min(16*1024, max_buffer_size)`)
141
142 :param bool use_list:
143 If true, unpack msgpack array to Python list.
144 Otherwise, unpack to Python tuple. (default: True)
145
146 :param bool raw:
147 If true, unpack msgpack raw to Python bytes.
148 Otherwise, unpack to Python str by decoding with UTF-8 encoding (default).
149
150 :param int timestamp:
151 Control how timestamp type is unpacked:
152
153 0 - Timestamp
154 1 - float (Seconds from the EPOCH)
155 2 - int (Nanoseconds from the EPOCH)
156 3 - datetime.datetime (UTC).
157
158 :param bool strict_map_key:
159 If true (default), only str or bytes are accepted for map (dict) keys.
160
161 :param object_hook:
162 When specified, it should be callable.
163 Unpacker calls it with a dict argument after unpacking msgpack map.
164 (See also simplejson)
165
166 :param object_pairs_hook:
167 When specified, it should be callable.
168 Unpacker calls it with a list of key-value pairs after unpacking msgpack map.
169 (See also simplejson)
170
171 :param str unicode_errors:
172 The error handler for decoding unicode. (default: 'strict')
173 This option should be used only when you have msgpack data which
174 contains invalid UTF-8 string.
175
176 :param int max_buffer_size:
177 Limits size of data waiting unpacked. 0 means 2**32-1.
178 The default value is 100*1024*1024 (100MiB).
179 Raises `BufferFull` exception when it is insufficient.
180 You should set this parameter when unpacking data from untrusted source.
181
182 :param int max_str_len:
183 Deprecated, use *max_buffer_size* instead.
184 Limits max length of str. (default: max_buffer_size)
185
186 :param int max_bin_len:
187 Deprecated, use *max_buffer_size* instead.
188 Limits max length of bin. (default: max_buffer_size)
189
190 :param int max_array_len:
191 Limits max length of array.
192 (default: max_buffer_size)
193
194 :param int max_map_len:
195 Limits max length of map.
196 (default: max_buffer_size//2)
197
198 :param int max_ext_len:
199 Deprecated, use *max_buffer_size* instead.
200 Limits max size of ext type. (default: max_buffer_size)
201
202 Example of streaming deserialize from file-like object::
203
204 unpacker = Unpacker(file_like)
205 for o in unpacker:
206 process(o)
207
208 Example of streaming deserialize from socket::
209
210 unpacker = Unpacker()
211 while True:
212 buf = sock.recv(1024**2)
213 if not buf:
214 break
215 unpacker.feed(buf)
216 for o in unpacker:
217 process(o)
218
219 Raises ``ExtraData`` when *packed* contains extra bytes.
220 Raises ``OutOfData`` when *packed* is incomplete.
221 Raises ``FormatError`` when *packed* is not valid msgpack.
222 Raises ``StackError`` when *packed* contains too nested.
223 Other exceptions can be raised during unpacking.
224 """
225
226 def __init__(
227 self,
228 file_like=None,
229 *,
230 read_size=0,
231 use_list=True,
232 raw=False,
233 timestamp=0,
234 strict_map_key=True,
235 object_hook=None,
236 object_pairs_hook=None,
237 list_hook=None,
238 unicode_errors=None,
239 max_buffer_size=100 * 1024 * 1024,
240 ext_hook=ExtType,
241 max_str_len=-1,
242 max_bin_len=-1,
243 max_array_len=-1,
244 max_map_len=-1,
245 max_ext_len=-1,
246 ):
247 if unicode_errors is None:
248 unicode_errors = "strict"
249
250 if file_like is None:
251 self._feeding = True
252 else:
253 if not callable(file_like.read):
254 raise TypeError("`file_like.read` must be callable")
255 self.file_like = file_like
256 self._feeding = False
257
258 #: array of bytes fed.
259 self._buffer = bytearray()
260 #: Which position we currently reads
261 self._buff_i = 0
262
263 # When Unpacker is used as an iterable, between the calls to next(),
264 # the buffer is not "consumed" completely, for efficiency sake.
265 # Instead, it is done sloppily. To make sure we raise BufferFull at
266 # the correct moments, we have to keep track of how sloppy we were.
267 # Furthermore, when the buffer is incomplete (that is: in the case
268 # we raise an OutOfData) we need to rollback the buffer to the correct
269 # state, which _buf_checkpoint records.
270 self._buf_checkpoint = 0
271
272 if not max_buffer_size:
273 max_buffer_size = 2**31 - 1
274 if max_str_len == -1:
275 max_str_len = max_buffer_size
276 if max_bin_len == -1:
277 max_bin_len = max_buffer_size
278 if max_array_len == -1:
279 max_array_len = max_buffer_size
280 if max_map_len == -1:
281 max_map_len = max_buffer_size // 2
282 if max_ext_len == -1:
283 max_ext_len = max_buffer_size
284
285 self._max_buffer_size = max_buffer_size
286 if read_size > self._max_buffer_size:
287 raise ValueError("read_size must be smaller than max_buffer_size")
288 self._read_size = read_size or min(self._max_buffer_size, 16 * 1024)
289 self._raw = bool(raw)
290 self._strict_map_key = bool(strict_map_key)
291 self._unicode_errors = unicode_errors
292 self._use_list = use_list
293 if not (0 <= timestamp <= 3):
294 raise ValueError("timestamp must be 0..3")
295 self._timestamp = timestamp
296 self._list_hook = list_hook
297 self._object_hook = object_hook
298 self._object_pairs_hook = object_pairs_hook
299 self._ext_hook = ext_hook
300 self._max_str_len = max_str_len
301 self._max_bin_len = max_bin_len
302 self._max_array_len = max_array_len
303 self._max_map_len = max_map_len
304 self._max_ext_len = max_ext_len
305 self._stream_offset = 0
306
307 if list_hook is not None and not callable(list_hook):
308 raise TypeError("`list_hook` is not callable")
309 if object_hook is not None and not callable(object_hook):
310 raise TypeError("`object_hook` is not callable")
311 if object_pairs_hook is not None and not callable(object_pairs_hook):
312 raise TypeError("`object_pairs_hook` is not callable")
313 if object_hook is not None and object_pairs_hook is not None:
314 raise TypeError("object_pairs_hook and object_hook are mutually exclusive")
315 if not callable(ext_hook):
316 raise TypeError("`ext_hook` is not callable")
317
318 def feed(self, next_bytes):
319 assert self._feeding
320 view = _get_data_from_buffer(next_bytes)
321 if len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size:
322 raise BufferFull
323
324 # Strip buffer before checkpoint before reading file.
325 if self._buf_checkpoint > 0:
326 del self._buffer[: self._buf_checkpoint]
327 self._buff_i -= self._buf_checkpoint
328 self._buf_checkpoint = 0
329
330 # Use extend here: INPLACE_ADD += doesn't reliably typecast memoryview in jython
331 self._buffer.extend(view)
332 view.release()
333
334 def _consume(self):
335 """Gets rid of the used parts of the buffer."""
336 self._stream_offset += self._buff_i - self._buf_checkpoint
337 self._buf_checkpoint = self._buff_i
338
339 def _got_extradata(self):
340 return self._buff_i < len(self._buffer)
341
342 def _get_extradata(self):
343 return self._buffer[self._buff_i :]
344
345 def read_bytes(self, n):
346 ret = self._read(n, raise_outofdata=False)
347 self._consume()
348 return ret
349
350 def _read(self, n, raise_outofdata=True):
351 # (int) -> bytearray
352 self._reserve(n, raise_outofdata=raise_outofdata)
353 i = self._buff_i
354 ret = self._buffer[i : i + n]
355 self._buff_i = i + len(ret)
356 return ret
357
358 def _reserve(self, n, raise_outofdata=True):
359 remain_bytes = len(self._buffer) - self._buff_i - n
360
361 # Fast path: buffer has n bytes already
362 if remain_bytes >= 0:
363 return
364
365 if self._feeding:
366 self._buff_i = self._buf_checkpoint
367 raise OutOfData
368
369 # Strip buffer before checkpoint before reading file.
370 if self._buf_checkpoint > 0:
371 del self._buffer[: self._buf_checkpoint]
372 self._buff_i -= self._buf_checkpoint
373 self._buf_checkpoint = 0
374
375 # Read from file
376 remain_bytes = -remain_bytes
377 if remain_bytes + len(self._buffer) > self._max_buffer_size:
378 raise BufferFull
379 while remain_bytes > 0:
380 to_read_bytes = max(self._read_size, remain_bytes)
381 read_data = self.file_like.read(to_read_bytes)
382 if not read_data:
383 break
384 assert isinstance(read_data, bytes)
385 self._buffer += read_data
386 remain_bytes -= len(read_data)
387
388 if len(self._buffer) < n + self._buff_i and raise_outofdata:
389 self._buff_i = 0 # rollback
390 raise OutOfData
391
392 def _read_header(self):
393 typ = TYPE_IMMEDIATE
394 n = 0
395 obj = None
396 self._reserve(1)
397 b = self._buffer[self._buff_i]
398 self._buff_i += 1
399 if b & 0b10000000 == 0:
400 obj = b
401 elif b & 0b11100000 == 0b11100000:
402 obj = -1 - (b ^ 0xFF)
403 elif b & 0b11100000 == 0b10100000:
404 n = b & 0b00011111
405 typ = TYPE_RAW
406 if n > self._max_str_len:
407 raise ValueError(f"{n} exceeds max_str_len({self._max_str_len})")
408 obj = self._read(n)
409 elif b & 0b11110000 == 0b10010000:
410 n = b & 0b00001111
411 typ = TYPE_ARRAY
412 if n > self._max_array_len:
413 raise ValueError(f"{n} exceeds max_array_len({self._max_array_len})")
414 elif b & 0b11110000 == 0b10000000:
415 n = b & 0b00001111
416 typ = TYPE_MAP
417 if n > self._max_map_len:
418 raise ValueError(f"{n} exceeds max_map_len({self._max_map_len})")
419 elif b == 0xC0:
420 obj = None
421 elif b == 0xC2:
422 obj = False
423 elif b == 0xC3:
424 obj = True
425 elif 0xC4 <= b <= 0xC6:
426 size, fmt, typ = _MSGPACK_HEADERS[b]
427 self._reserve(size)
428 if len(fmt) > 0:
429 n = struct.unpack_from(fmt, self._buffer, self._buff_i)[0]
430 else:
431 n = self._buffer[self._buff_i]
432 self._buff_i += size
433 if n > self._max_bin_len:
434 raise ValueError(f"{n} exceeds max_bin_len({self._max_bin_len})")
435 obj = self._read(n)
436 elif 0xC7 <= b <= 0xC9:
437 size, fmt, typ = _MSGPACK_HEADERS[b]
438 self._reserve(size)
439 L, n = struct.unpack_from(fmt, self._buffer, self._buff_i)
440 self._buff_i += size
441 if L > self._max_ext_len:
442 raise ValueError(f"{L} exceeds max_ext_len({self._max_ext_len})")
443 obj = self._read(L)
444 elif 0xCA <= b <= 0xD3:
445 size, fmt = _MSGPACK_HEADERS[b]
446 self._reserve(size)
447 if len(fmt) > 0:
448 obj = struct.unpack_from(fmt, self._buffer, self._buff_i)[0]
449 else:
450 obj = self._buffer[self._buff_i]
451 self._buff_i += size
452 elif 0xD4 <= b <= 0xD8:
453 size, fmt, typ = _MSGPACK_HEADERS[b]
454 if self._max_ext_len < size:
455 raise ValueError(f"{size} exceeds max_ext_len({self._max_ext_len})")
456 self._reserve(size + 1)
457 n, obj = struct.unpack_from(fmt, self._buffer, self._buff_i)
458 self._buff_i += size + 1
459 elif 0xD9 <= b <= 0xDB:
460 size, fmt, typ = _MSGPACK_HEADERS[b]
461 self._reserve(size)
462 if len(fmt) > 0:
463 (n,) = struct.unpack_from(fmt, self._buffer, self._buff_i)
464 else:
465 n = self._buffer[self._buff_i]
466 self._buff_i += size
467 if n > self._max_str_len:
468 raise ValueError(f"{n} exceeds max_str_len({self._max_str_len})")
469 obj = self._read(n)
470 elif 0xDC <= b <= 0xDD:
471 size, fmt, typ = _MSGPACK_HEADERS[b]
472 self._reserve(size)
473 (n,) = struct.unpack_from(fmt, self._buffer, self._buff_i)
474 self._buff_i += size
475 if n > self._max_array_len:
476 raise ValueError(f"{n} exceeds max_array_len({self._max_array_len})")
477 elif 0xDE <= b <= 0xDF:
478 size, fmt, typ = _MSGPACK_HEADERS[b]
479 self._reserve(size)
480 (n,) = struct.unpack_from(fmt, self._buffer, self._buff_i)
481 self._buff_i += size
482 if n > self._max_map_len:
483 raise ValueError(f"{n} exceeds max_map_len({self._max_map_len})")
484 else:
485 raise FormatError("Unknown header: 0x%x" % b)
486 return typ, n, obj
487
488 def _unpack(self, execute=EX_CONSTRUCT):
489 typ, n, obj = self._read_header()
490
491 if execute == EX_READ_ARRAY_HEADER:
492 if typ != TYPE_ARRAY:
493 raise ValueError("Expected array")
494 return n
495 if execute == EX_READ_MAP_HEADER:
496 if typ != TYPE_MAP:
497 raise ValueError("Expected map")
498 return n
499 # TODO should we eliminate the recursion?
500 if typ == TYPE_ARRAY:
501 if execute == EX_SKIP:
502 for i in range(n):
503 # TODO check whether we need to call `list_hook`
504 self._unpack(EX_SKIP)
505 return
506 ret = newlist_hint(n)
507 for i in range(n):
508 ret.append(self._unpack(EX_CONSTRUCT))
509 if self._list_hook is not None:
510 ret = self._list_hook(ret)
511 # TODO is the interaction between `list_hook` and `use_list` ok?
512 return ret if self._use_list else tuple(ret)
513 if typ == TYPE_MAP:
514 if execute == EX_SKIP:
515 for i in range(n):
516 # TODO check whether we need to call hooks
517 self._unpack(EX_SKIP)
518 self._unpack(EX_SKIP)
519 return
520 if self._object_pairs_hook is not None:
521 ret = self._object_pairs_hook(
522 (self._unpack(EX_CONSTRUCT), self._unpack(EX_CONSTRUCT)) for _ in range(n)
523 )
524 else:
525 ret = {}
526 for _ in range(n):
527 key = self._unpack(EX_CONSTRUCT)
528 if self._strict_map_key and type(key) not in (str, bytes):
529 raise ValueError("%s is not allowed for map key" % str(type(key)))
530 if isinstance(key, str):
531 key = sys.intern(key)
532 ret[key] = self._unpack(EX_CONSTRUCT)
533 if self._object_hook is not None:
534 ret = self._object_hook(ret)
535 return ret
536 if execute == EX_SKIP:
537 return
538 if typ == TYPE_RAW:
539 if self._raw:
540 obj = bytes(obj)
541 else:
542 obj = obj.decode("utf_8", self._unicode_errors)
543 return obj
544 if typ == TYPE_BIN:
545 return bytes(obj)
546 if typ == TYPE_EXT:
547 if n == -1: # timestamp
548 ts = Timestamp.from_bytes(bytes(obj))
549 if self._timestamp == 1:
550 return ts.to_unix()
551 elif self._timestamp == 2:
552 return ts.to_unix_nano()
553 elif self._timestamp == 3:
554 return ts.to_datetime()
555 else:
556 return ts
557 else:
558 return self._ext_hook(n, bytes(obj))
559 assert typ == TYPE_IMMEDIATE
560 return obj
561
562 def __iter__(self):
563 return self
564
565 def __next__(self):
566 try:
567 ret = self._unpack(EX_CONSTRUCT)
568 self._consume()
569 return ret
570 except OutOfData:
571 self._consume()
572 raise StopIteration
573 except RecursionError:
574 raise StackError
575
576 next = __next__
577
578 def skip(self):
579 self._unpack(EX_SKIP)
580 self._consume()
581
582 def unpack(self):
583 try:
584 ret = self._unpack(EX_CONSTRUCT)
585 except RecursionError:
586 raise StackError
587 self._consume()
588 return ret
589
590 def read_array_header(self):
591 ret = self._unpack(EX_READ_ARRAY_HEADER)
592 self._consume()
593 return ret
594
595 def read_map_header(self):
596 ret = self._unpack(EX_READ_MAP_HEADER)
597 self._consume()
598 return ret
599
600 def tell(self):
601 return self._stream_offset
602
603
604class Packer:
605 """
606 MessagePack Packer
607
608 Usage::
609
610 packer = Packer()
611 astream.write(packer.pack(a))
612 astream.write(packer.pack(b))
613
614 Packer's constructor has some keyword arguments:
615
616 :param default:
617 When specified, it should be callable.
618 Convert user type to builtin type that Packer supports.
619 See also simplejson's document.
620
621 :param bool use_single_float:
622 Use single precision float type for float. (default: False)
623
624 :param bool autoreset:
625 Reset buffer after each pack and return its content as `bytes`. (default: True).
626 If set this to false, use `bytes()` to get content and `.reset()` to clear buffer.
627
628 :param bool use_bin_type:
629 Use bin type introduced in msgpack spec 2.0 for bytes.
630 It also enables str8 type for unicode. (default: True)
631
632 :param bool strict_types:
633 If set to true, types will be checked to be exact. Derived classes
634 from serializable types will not be serialized and will be
635 treated as unsupported type and forwarded to default.
636 Additionally tuples will not be serialized as lists.
637 This is useful when trying to implement accurate serialization
638 for python types.
639
640 :param bool datetime:
641 If set to true, datetime with tzinfo is packed into Timestamp type.
642 Note that the tzinfo is stripped in the timestamp.
643 You can get UTC datetime with `timestamp=3` option of the Unpacker.
644
645 :param str unicode_errors:
646 The error handler for encoding unicode. (default: 'strict')
647 DO NOT USE THIS!! This option is kept for very specific usage.
648
649 :param int buf_size:
650 Internal buffer size. This option is used only for C implementation.
651 """
652
653 def __init__(
654 self,
655 *,
656 default=None,
657 use_single_float=False,
658 autoreset=True,
659 use_bin_type=True,
660 strict_types=False,
661 datetime=False,
662 unicode_errors=None,
663 buf_size=None,
664 ):
665 self._strict_types = strict_types
666 self._use_float = use_single_float
667 self._autoreset = autoreset
668 self._use_bin_type = use_bin_type
669 self._buffer = BytesIO()
670 self._datetime = bool(datetime)
671 self._unicode_errors = unicode_errors or "strict"
672 if default is not None and not callable(default):
673 raise TypeError("default must be callable")
674 self._default = default
675
676 def _pack(
677 self,
678 obj,
679 nest_limit=DEFAULT_RECURSE_LIMIT,
680 check=isinstance,
681 check_type_strict=_check_type_strict,
682 ):
683 default_used = False
684 if self._strict_types:
685 check = check_type_strict
686 list_types = list
687 else:
688 list_types = (list, tuple)
689 while True:
690 if nest_limit < 0:
691 raise ValueError("recursion limit exceeded")
692 if obj is None:
693 return self._buffer.write(b"\xc0")
694 if check(obj, bool):
695 if obj:
696 return self._buffer.write(b"\xc3")
697 return self._buffer.write(b"\xc2")
698 if check(obj, int):
699 if 0 <= obj < 0x80:
700 return self._buffer.write(struct.pack("B", obj))
701 if -0x20 <= obj < 0:
702 return self._buffer.write(struct.pack("b", obj))
703 if 0x80 <= obj <= 0xFF:
704 return self._buffer.write(struct.pack("BB", 0xCC, obj))
705 if -0x80 <= obj < 0:
706 return self._buffer.write(struct.pack(">Bb", 0xD0, obj))
707 if 0xFF < obj <= 0xFFFF:
708 return self._buffer.write(struct.pack(">BH", 0xCD, obj))
709 if -0x8000 <= obj < -0x80:
710 return self._buffer.write(struct.pack(">Bh", 0xD1, obj))
711 if 0xFFFF < obj <= 0xFFFFFFFF:
712 return self._buffer.write(struct.pack(">BI", 0xCE, obj))
713 if -0x80000000 <= obj < -0x8000:
714 return self._buffer.write(struct.pack(">Bi", 0xD2, obj))
715 if 0xFFFFFFFF < obj <= 0xFFFFFFFFFFFFFFFF:
716 return self._buffer.write(struct.pack(">BQ", 0xCF, obj))
717 if -0x8000000000000000 <= obj < -0x80000000:
718 return self._buffer.write(struct.pack(">Bq", 0xD3, obj))
719 if not default_used and self._default is not None:
720 obj = self._default(obj)
721 default_used = True
722 continue
723 raise OverflowError("Integer value out of range")
724 if check(obj, (bytes, bytearray)):
725 n = len(obj)
726 if n >= 2**32:
727 raise ValueError("%s is too large" % type(obj).__name__)
728 self._pack_bin_header(n)
729 return self._buffer.write(obj)
730 if check(obj, str):
731 obj = obj.encode("utf-8", self._unicode_errors)
732 n = len(obj)
733 if n >= 2**32:
734 raise ValueError("String is too large")
735 self._pack_raw_header(n)
736 return self._buffer.write(obj)
737 if check(obj, memoryview):
738 n = obj.nbytes
739 if n >= 2**32:
740 raise ValueError("Memoryview is too large")
741 self._pack_bin_header(n)
742 return self._buffer.write(obj)
743 if check(obj, float):
744 if self._use_float:
745 return self._buffer.write(struct.pack(">Bf", 0xCA, obj))
746 return self._buffer.write(struct.pack(">Bd", 0xCB, obj))
747 if check(obj, (ExtType, Timestamp)):
748 if check(obj, Timestamp):
749 code = -1
750 data = obj.to_bytes()
751 else:
752 code = obj.code
753 data = obj.data
754 assert isinstance(code, int)
755 assert isinstance(data, bytes)
756 L = len(data)
757 if L == 1:
758 self._buffer.write(b"\xd4")
759 elif L == 2:
760 self._buffer.write(b"\xd5")
761 elif L == 4:
762 self._buffer.write(b"\xd6")
763 elif L == 8:
764 self._buffer.write(b"\xd7")
765 elif L == 16:
766 self._buffer.write(b"\xd8")
767 elif L <= 0xFF:
768 self._buffer.write(struct.pack(">BB", 0xC7, L))
769 elif L <= 0xFFFF:
770 self._buffer.write(struct.pack(">BH", 0xC8, L))
771 else:
772 self._buffer.write(struct.pack(">BI", 0xC9, L))
773 self._buffer.write(struct.pack("b", code))
774 self._buffer.write(data)
775 return
776 if check(obj, list_types):
777 n = len(obj)
778 self._pack_array_header(n)
779 for i in range(n):
780 self._pack(obj[i], nest_limit - 1)
781 return
782 if check(obj, dict):
783 return self._pack_map_pairs(len(obj), obj.items(), nest_limit - 1)
784
785 if self._datetime and check(obj, _DateTime) and obj.tzinfo is not None:
786 obj = Timestamp.from_datetime(obj)
787 default_used = 1
788 continue
789
790 if not default_used and self._default is not None:
791 obj = self._default(obj)
792 default_used = 1
793 continue
794
795 if self._datetime and check(obj, _DateTime):
796 raise ValueError(f"Cannot serialize {obj!r} where tzinfo=None")
797
798 raise TypeError(f"Cannot serialize {obj!r}")
799
800 def pack(self, obj):
801 try:
802 self._pack(obj)
803 except:
804 self._buffer = BytesIO() # force reset
805 raise
806 if self._autoreset:
807 ret = self._buffer.getvalue()
808 self._buffer = BytesIO()
809 return ret
810
811 def pack_map_pairs(self, pairs):
812 self._pack_map_pairs(len(pairs), pairs)
813 if self._autoreset:
814 ret = self._buffer.getvalue()
815 self._buffer = BytesIO()
816 return ret
817
818 def pack_array_header(self, n):
819 if n >= 2**32:
820 raise ValueError
821 self._pack_array_header(n)
822 if self._autoreset:
823 ret = self._buffer.getvalue()
824 self._buffer = BytesIO()
825 return ret
826
827 def pack_map_header(self, n):
828 if n >= 2**32:
829 raise ValueError
830 self._pack_map_header(n)
831 if self._autoreset:
832 ret = self._buffer.getvalue()
833 self._buffer = BytesIO()
834 return ret
835
836 def pack_ext_type(self, typecode, data):
837 if not isinstance(typecode, int):
838 raise TypeError("typecode must have int type.")
839 if not 0 <= typecode <= 127:
840 raise ValueError("typecode should be 0-127")
841 if not isinstance(data, bytes):
842 raise TypeError("data must have bytes type")
843 L = len(data)
844 if L > 0xFFFFFFFF:
845 raise ValueError("Too large data")
846 if L == 1:
847 self._buffer.write(b"\xd4")
848 elif L == 2:
849 self._buffer.write(b"\xd5")
850 elif L == 4:
851 self._buffer.write(b"\xd6")
852 elif L == 8:
853 self._buffer.write(b"\xd7")
854 elif L == 16:
855 self._buffer.write(b"\xd8")
856 elif L <= 0xFF:
857 self._buffer.write(b"\xc7" + struct.pack("B", L))
858 elif L <= 0xFFFF:
859 self._buffer.write(b"\xc8" + struct.pack(">H", L))
860 else:
861 self._buffer.write(b"\xc9" + struct.pack(">I", L))
862 self._buffer.write(struct.pack("B", typecode))
863 self._buffer.write(data)
864
865 def _pack_array_header(self, n):
866 if n <= 0x0F:
867 return self._buffer.write(struct.pack("B", 0x90 + n))
868 if n <= 0xFFFF:
869 return self._buffer.write(struct.pack(">BH", 0xDC, n))
870 if n <= 0xFFFFFFFF:
871 return self._buffer.write(struct.pack(">BI", 0xDD, n))
872 raise ValueError("Array is too large")
873
874 def _pack_map_header(self, n):
875 if n <= 0x0F:
876 return self._buffer.write(struct.pack("B", 0x80 + n))
877 if n <= 0xFFFF:
878 return self._buffer.write(struct.pack(">BH", 0xDE, n))
879 if n <= 0xFFFFFFFF:
880 return self._buffer.write(struct.pack(">BI", 0xDF, n))
881 raise ValueError("Dict is too large")
882
883 def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT):
884 self._pack_map_header(n)
885 for k, v in pairs:
886 self._pack(k, nest_limit - 1)
887 self._pack(v, nest_limit - 1)
888
889 def _pack_raw_header(self, n):
890 if n <= 0x1F:
891 self._buffer.write(struct.pack("B", 0xA0 + n))
892 elif self._use_bin_type and n <= 0xFF:
893 self._buffer.write(struct.pack(">BB", 0xD9, n))
894 elif n <= 0xFFFF:
895 self._buffer.write(struct.pack(">BH", 0xDA, n))
896 elif n <= 0xFFFFFFFF:
897 self._buffer.write(struct.pack(">BI", 0xDB, n))
898 else:
899 raise ValueError("Raw is too large")
900
901 def _pack_bin_header(self, n):
902 if not self._use_bin_type:
903 return self._pack_raw_header(n)
904 elif n <= 0xFF:
905 return self._buffer.write(struct.pack(">BB", 0xC4, n))
906 elif n <= 0xFFFF:
907 return self._buffer.write(struct.pack(">BH", 0xC5, n))
908 elif n <= 0xFFFFFFFF:
909 return self._buffer.write(struct.pack(">BI", 0xC6, n))
910 else:
911 raise ValueError("Bin is too large")
912
913 def bytes(self):
914 """Return internal buffer contents as bytes object"""
915 return self._buffer.getvalue()
916
917 def reset(self):
918 """Reset internal buffer.
919
920 This method is useful only when autoreset=False.
921 """
922 self._buffer = BytesIO()
923
924 def getbuffer(self):
925 """Return view of internal buffer."""
926 if _USING_STRINGBUILDER:
927 return memoryview(self.bytes())
928 else:
929 return self._buffer.getbuffer()