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