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 = 1024
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 if view.contiguous else view.tobytes())
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
522 def _gen():
523 for _ in range(n):
524 key = self._unpack(EX_CONSTRUCT)
525 if self._strict_map_key and type(key) not in (str, bytes):
526 raise ValueError("%s is not allowed for map key" % str(type(key)))
527 yield key, self._unpack(EX_CONSTRUCT)
528
529 ret = self._object_pairs_hook(_gen())
530 else:
531 ret = {}
532 for _ in range(n):
533 key = self._unpack(EX_CONSTRUCT)
534 if self._strict_map_key and type(key) not in (str, bytes):
535 raise ValueError("%s is not allowed for map key" % str(type(key)))
536 if isinstance(key, str):
537 key = sys.intern(key)
538 ret[key] = self._unpack(EX_CONSTRUCT)
539 if self._object_hook is not None:
540 ret = self._object_hook(ret)
541 return ret
542 if execute == EX_SKIP:
543 return
544 if typ == TYPE_RAW:
545 if self._raw:
546 obj = bytes(obj)
547 else:
548 obj = obj.decode("utf_8", self._unicode_errors)
549 return obj
550 if typ == TYPE_BIN:
551 return bytes(obj)
552 if typ == TYPE_EXT:
553 if n == -1: # timestamp
554 ts = Timestamp.from_bytes(bytes(obj))
555 if self._timestamp == 1:
556 return ts.to_unix()
557 elif self._timestamp == 2:
558 return ts.to_unix_nano()
559 elif self._timestamp == 3:
560 return ts.to_datetime()
561 else:
562 return ts
563 else:
564 return self._ext_hook(n, bytes(obj))
565 assert typ == TYPE_IMMEDIATE
566 return obj
567
568 def __iter__(self):
569 return self
570
571 def __next__(self):
572 try:
573 ret = self._unpack(EX_CONSTRUCT)
574 self._consume()
575 return ret
576 except OutOfData:
577 self._consume()
578 raise StopIteration
579 except RecursionError:
580 raise StackError
581
582 next = __next__
583
584 def skip(self):
585 self._unpack(EX_SKIP)
586 self._consume()
587
588 def unpack(self):
589 try:
590 ret = self._unpack(EX_CONSTRUCT)
591 except RecursionError:
592 raise StackError
593 self._consume()
594 return ret
595
596 def read_array_header(self):
597 ret = self._unpack(EX_READ_ARRAY_HEADER)
598 self._consume()
599 return ret
600
601 def read_map_header(self):
602 ret = self._unpack(EX_READ_MAP_HEADER)
603 self._consume()
604 return ret
605
606 def tell(self):
607 return self._stream_offset
608
609
610class Packer:
611 """
612 MessagePack Packer
613
614 Usage::
615
616 packer = Packer()
617 astream.write(packer.pack(a))
618 astream.write(packer.pack(b))
619
620 Packer's constructor has some keyword arguments:
621
622 :param default:
623 When specified, it should be callable.
624 Convert user type to builtin type that Packer supports.
625 See also simplejson's document.
626
627 :param bool use_single_float:
628 Use single precision float type for float. (default: False)
629
630 :param bool autoreset:
631 Reset buffer after each pack and return its content as `bytes`. (default: True).
632 If set this to false, use `bytes()` to get content and `.reset()` to clear buffer.
633
634 :param bool use_bin_type:
635 Use bin type introduced in msgpack spec 2.0 for bytes.
636 It also enables str8 type for unicode. (default: True)
637
638 :param bool strict_types:
639 If set to true, types will be checked to be exact. Derived classes
640 from serializable types will not be serialized and will be
641 treated as unsupported type and forwarded to default.
642 Additionally tuples will not be serialized as lists.
643 This is useful when trying to implement accurate serialization
644 for python types.
645
646 :param bool datetime:
647 If set to true, datetime with tzinfo is packed into Timestamp type.
648 Note that the tzinfo is stripped in the timestamp.
649 You can get UTC datetime with `timestamp=3` option of the Unpacker.
650
651 :param str unicode_errors:
652 The error handler for encoding unicode. (default: 'strict')
653 DO NOT USE THIS!! This option is kept for very specific usage.
654
655 :param int buf_size:
656 Internal buffer size. This option is used only for C implementation.
657 """
658
659 def __init__(
660 self,
661 *,
662 default=None,
663 use_single_float=False,
664 autoreset=True,
665 use_bin_type=True,
666 strict_types=False,
667 datetime=False,
668 unicode_errors=None,
669 buf_size=None,
670 ):
671 self._strict_types = strict_types
672 self._use_float = use_single_float
673 self._autoreset = autoreset
674 self._use_bin_type = use_bin_type
675 self._buffer = BytesIO()
676 self._datetime = bool(datetime)
677 self._unicode_errors = unicode_errors or "strict"
678 if default is not None and not callable(default):
679 raise TypeError("default must be callable")
680 self._default = default
681
682 def _pack(
683 self,
684 obj,
685 nest_limit=DEFAULT_RECURSE_LIMIT,
686 check=isinstance,
687 check_type_strict=_check_type_strict,
688 ):
689 default_used = False
690 if self._strict_types:
691 check = check_type_strict
692 list_types = list
693 else:
694 list_types = (list, tuple)
695 while True:
696 if nest_limit < 0:
697 raise ValueError("recursion limit exceeded")
698 if obj is None:
699 return self._buffer.write(b"\xc0")
700 if check(obj, bool):
701 if obj:
702 return self._buffer.write(b"\xc3")
703 return self._buffer.write(b"\xc2")
704 if check(obj, int):
705 if 0 <= obj < 0x80:
706 return self._buffer.write(struct.pack("B", obj))
707 if -0x20 <= obj < 0:
708 return self._buffer.write(struct.pack("b", obj))
709 if 0x80 <= obj <= 0xFF:
710 return self._buffer.write(struct.pack("BB", 0xCC, obj))
711 if -0x80 <= obj < 0:
712 return self._buffer.write(struct.pack(">Bb", 0xD0, obj))
713 if 0xFF < obj <= 0xFFFF:
714 return self._buffer.write(struct.pack(">BH", 0xCD, obj))
715 if -0x8000 <= obj < -0x80:
716 return self._buffer.write(struct.pack(">Bh", 0xD1, obj))
717 if 0xFFFF < obj <= 0xFFFFFFFF:
718 return self._buffer.write(struct.pack(">BI", 0xCE, obj))
719 if -0x80000000 <= obj < -0x8000:
720 return self._buffer.write(struct.pack(">Bi", 0xD2, obj))
721 if 0xFFFFFFFF < obj <= 0xFFFFFFFFFFFFFFFF:
722 return self._buffer.write(struct.pack(">BQ", 0xCF, obj))
723 if -0x8000000000000000 <= obj < -0x80000000:
724 return self._buffer.write(struct.pack(">Bq", 0xD3, obj))
725 if not default_used and self._default is not None:
726 obj = self._default(obj)
727 default_used = True
728 continue
729 raise OverflowError("Integer value out of range")
730 if check(obj, (bytes, bytearray)):
731 n = len(obj)
732 if n >= 2**32:
733 raise ValueError("%s is too large" % type(obj).__name__)
734 self._pack_bin_header(n)
735 return self._buffer.write(obj)
736 if check(obj, str):
737 obj = obj.encode("utf-8", self._unicode_errors)
738 n = len(obj)
739 if n >= 2**32:
740 raise ValueError("String is too large")
741 self._pack_raw_header(n)
742 return self._buffer.write(obj)
743 if check(obj, memoryview):
744 n = obj.nbytes
745 if n >= 2**32:
746 raise ValueError("Memoryview is too large")
747 self._pack_bin_header(n)
748 return self._buffer.write(obj)
749 if check(obj, float):
750 if self._use_float:
751 return self._buffer.write(struct.pack(">Bf", 0xCA, obj))
752 return self._buffer.write(struct.pack(">Bd", 0xCB, obj))
753 if check(obj, (ExtType, Timestamp)):
754 if check(obj, Timestamp):
755 code = -1
756 data = obj.to_bytes()
757 else:
758 code = obj.code
759 data = obj.data
760 assert isinstance(code, int)
761 assert isinstance(data, bytes)
762 L = len(data)
763 if L == 1:
764 self._buffer.write(b"\xd4")
765 elif L == 2:
766 self._buffer.write(b"\xd5")
767 elif L == 4:
768 self._buffer.write(b"\xd6")
769 elif L == 8:
770 self._buffer.write(b"\xd7")
771 elif L == 16:
772 self._buffer.write(b"\xd8")
773 elif L <= 0xFF:
774 self._buffer.write(struct.pack(">BB", 0xC7, L))
775 elif L <= 0xFFFF:
776 self._buffer.write(struct.pack(">BH", 0xC8, L))
777 else:
778 self._buffer.write(struct.pack(">BI", 0xC9, L))
779 self._buffer.write(struct.pack("b", code))
780 self._buffer.write(data)
781 return
782 if check(obj, list_types):
783 n = len(obj)
784 self._pack_array_header(n)
785 for i in range(n):
786 self._pack(obj[i], nest_limit - 1)
787 return
788 if check(obj, dict):
789 return self._pack_map_pairs(len(obj), obj.items(), nest_limit - 1)
790
791 if self._datetime and check(obj, _DateTime) and obj.tzinfo is not None:
792 obj = Timestamp.from_datetime(obj)
793 default_used = 1
794 continue
795
796 if not default_used and self._default is not None:
797 obj = self._default(obj)
798 default_used = 1
799 continue
800
801 if self._datetime and check(obj, _DateTime):
802 raise ValueError(f"Cannot serialize {obj!r} where tzinfo=None")
803
804 raise TypeError(f"Cannot serialize {obj!r}")
805
806 def pack(self, obj):
807 try:
808 self._pack(obj)
809 except:
810 self._buffer = BytesIO() # force reset
811 raise
812 if self._autoreset:
813 ret = self._buffer.getvalue()
814 self._buffer = BytesIO()
815 return ret
816
817 def pack_map_pairs(self, pairs):
818 self._pack_map_pairs(len(pairs), pairs)
819 if self._autoreset:
820 ret = self._buffer.getvalue()
821 self._buffer = BytesIO()
822 return ret
823
824 def pack_array_header(self, n):
825 if n >= 2**32:
826 raise ValueError
827 self._pack_array_header(n)
828 if self._autoreset:
829 ret = self._buffer.getvalue()
830 self._buffer = BytesIO()
831 return ret
832
833 def pack_map_header(self, n):
834 if n >= 2**32:
835 raise ValueError
836 self._pack_map_header(n)
837 if self._autoreset:
838 ret = self._buffer.getvalue()
839 self._buffer = BytesIO()
840 return ret
841
842 def pack_ext_type(self, typecode, data):
843 if not isinstance(typecode, int):
844 raise TypeError("typecode must have int type.")
845 if not 0 <= typecode <= 127:
846 raise ValueError("typecode should be 0-127")
847 if not isinstance(data, bytes):
848 raise TypeError("data must have bytes type")
849 L = len(data)
850 if L > 0xFFFFFFFF:
851 raise ValueError("Too large data")
852 if L == 1:
853 self._buffer.write(b"\xd4")
854 elif L == 2:
855 self._buffer.write(b"\xd5")
856 elif L == 4:
857 self._buffer.write(b"\xd6")
858 elif L == 8:
859 self._buffer.write(b"\xd7")
860 elif L == 16:
861 self._buffer.write(b"\xd8")
862 elif L <= 0xFF:
863 self._buffer.write(b"\xc7" + struct.pack("B", L))
864 elif L <= 0xFFFF:
865 self._buffer.write(b"\xc8" + struct.pack(">H", L))
866 else:
867 self._buffer.write(b"\xc9" + struct.pack(">I", L))
868 self._buffer.write(struct.pack("B", typecode))
869 self._buffer.write(data)
870 if self._autoreset:
871 ret = self._buffer.getvalue()
872 self._buffer = BytesIO()
873 return ret
874
875 def _pack_array_header(self, n):
876 if n <= 0x0F:
877 return self._buffer.write(struct.pack("B", 0x90 + n))
878 if n <= 0xFFFF:
879 return self._buffer.write(struct.pack(">BH", 0xDC, n))
880 if n <= 0xFFFFFFFF:
881 return self._buffer.write(struct.pack(">BI", 0xDD, n))
882 raise ValueError("Array is too large")
883
884 def _pack_map_header(self, n):
885 if n <= 0x0F:
886 return self._buffer.write(struct.pack("B", 0x80 + n))
887 if n <= 0xFFFF:
888 return self._buffer.write(struct.pack(">BH", 0xDE, n))
889 if n <= 0xFFFFFFFF:
890 return self._buffer.write(struct.pack(">BI", 0xDF, n))
891 raise ValueError("Dict is too large")
892
893 def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT):
894 self._pack_map_header(n)
895 for k, v in pairs:
896 self._pack(k, nest_limit - 1)
897 self._pack(v, nest_limit - 1)
898
899 def _pack_raw_header(self, n):
900 if n <= 0x1F:
901 self._buffer.write(struct.pack("B", 0xA0 + n))
902 elif self._use_bin_type and n <= 0xFF:
903 self._buffer.write(struct.pack(">BB", 0xD9, n))
904 elif n <= 0xFFFF:
905 self._buffer.write(struct.pack(">BH", 0xDA, n))
906 elif n <= 0xFFFFFFFF:
907 self._buffer.write(struct.pack(">BI", 0xDB, n))
908 else:
909 raise ValueError("Raw is too large")
910
911 def _pack_bin_header(self, n):
912 if not self._use_bin_type:
913 return self._pack_raw_header(n)
914 elif n <= 0xFF:
915 return self._buffer.write(struct.pack(">BB", 0xC4, n))
916 elif n <= 0xFFFF:
917 return self._buffer.write(struct.pack(">BH", 0xC5, n))
918 elif n <= 0xFFFFFFFF:
919 return self._buffer.write(struct.pack(">BI", 0xC6, n))
920 else:
921 raise ValueError("Bin is too large")
922
923 def bytes(self):
924 """Return internal buffer contents as bytes object"""
925 return self._buffer.getvalue()
926
927 def reset(self):
928 """Reset internal buffer.
929
930 This method is useful only when autoreset=False.
931 """
932 self._buffer = BytesIO()
933
934 def getbuffer(self):
935 """Return view of internal buffer."""
936 if _USING_STRINGBUILDER:
937 return memoryview(self.bytes())
938 else:
939 return self._buffer.getbuffer()