8000 Refactor fallback read header (#441) · shadchin/msgpack-python@3b71818 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3b71818

Browse files
authored
Refactor fallback read header (msgpack#441)
1 parent 431ef45 commit 3b71818

File tree

1 file changed

+82
-165
lines changed

1 file changed

+82
-165
lines changed

msgpack/fallback.py

Lines changed: 82 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
"""Fallback pure Python implementation of msgpack"""
2-
32
from datetime import datetime as _DateTime
43
import sys
54
import struct
@@ -148,6 +147,38 @@ def _unpack_from(f, b, o=0):
148147
else:
149148
_unpack_from = struct.unpack_from
150149

150+
_NO_FORMAT_USED = ""
151+
_MSGPACK_HEADERS = {
152+
0xC4: (1, _NO_FORMAT_USED, TYPE_BIN),
153+
0xC5: (2, ">H", TYPE_BIN),
154+
0xC6: (4, ">I", TYPE_BIN),
155+
0xC7: (2, "Bb", TYPE_EXT),
156+
0xC8: (3, ">Hb", TYPE_EXT),
157+
0xC9: (5, ">Ib", TYPE_EXT),
158+
0xCA: (4, ">f"),
159+
0xCB: (8, ">d"),
160+
0xCC: (1, _NO_FORMAT_USED),
161+
0xCD: (2, ">H"),
162+
0xCE: (4, ">I"),
163+
0xCF: (8, ">Q"),
164+
0xD0: (1, "b"),
165+
0xD1: (2, ">h"),
166+
0xD2: (4, ">i"),
167+
0xD3: (8, ">q"),
168+
0xD4: (1, "b1s", TYPE_EXT),
169+
0xD5: (2, "b2s", TYPE_EXT),
170+
0xD6: (4, "b4s", TYPE_EXT),
171+
0xD7: (8, "b8s", TYPE_EXT),
172+
0xD8: (16, "b16s", TYPE_EXT),
173+
0xD9: (1, _NO_FORMAT_USED, TYPE_RAW),
174+
0xDA: (2, ">H", TYPE_RAW),
175+
0xDB: (4, ">I", TYPE_RAW),
176+
0xDC: (2, ">H", TYPE_ARRAY),
177+
0xDD: (4, ">I", TYPE_ARRAY),
178+
0xDE: (2, ">H", TYPE_MAP),
179+
0xDF: (4, ">I", TYPE_MAP),
180+
}
181+
151182

152183
class Unpacker(object):
153184
"""Streaming unpacker.
@@ -409,7 +440,7 @@ def _reserve(self, n, raise_outofdata=True):
409440
self._buff_i = 0 # rollback
410441
raise OutOfData
411442

412-
def _read_header(self, execute=EX_CONSTRUCT):
443+
def _read_header(self):
413444
typ = TYPE_IMMEDIATE
414445
n = 0
415446
obj = None
@@ -442,187 +473,73 @@ def _read_header(self, execute=EX_CONSTRUCT):
442473
obj = False
443474
elif b == 0xC3:
444475
obj = True
445-
elif b == 0xC4:
446-
typ = TYPE_BIN
447-
self._reserve(1)
448-
n = self._buffer[self._buff_i]
449-
self._buff_i += 1
450-
if n > self._max_bin_len:
451-
raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
452-
obj = self._read(n)
453-
elif b == 0xC5:
454-
typ = TYPE_BIN
455-
self._reserve(2)
456-
n = _unpack_from(">H", self._buffer, self._buff_i)[0]
457-
self._buff_i += 2
458-
if n > self._max_bin_len:
459-
raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
460-
obj = self._read(n)
461-
elif b == 0xC6:
462-
typ = TYPE_BIN
463-
self._reserve(4)
464-
n = _unpack_from(">I", self._buffer, self._buff_i)[0]
465-
self._buff_i += 4
476+
elif 0xC4 <= b <= 0xC6:
477+
size, fmt, typ = _MSGPACK_HEADERS[b]
478+
self._reserve(size)
479+
if len(fmt) > 0:
480+
n = _unpack_from(fmt, self._buffer, self._buff_i)[0]
481+
else:
482+
n = self._buffer[self._buff_i]
483+
self._buff_i += size
466484
if n > self._max_bin_len:
467485
raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
468486
obj = self._read(n)
469-
elif b == 0xC7: # ext 8
470-
typ = TYPE_EXT
471-
self._reserve(2)
472-
L, n = _unpack_from("Bb", self._buffer, self._buff_i)
473-
self._buff_i += 2
487+
elif 0xC7 <= b <= 0xC9:
488+
size, fmt, typ = _MSGPACK_HEADERS[b]
489+
self._reserve(size)
490+
L, n = _unpack_from(fmt, self._buffer, self._buff_i)
491+
self._buff_i += size
474492
if L > self._max_ext_len:
475493
raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
476494
obj = self._read(L)
477-
elif b == 0xC8: # ext 16
478-
typ = TYPE_EXT
479-
self._reserve(3)
480-
L, n = _unpack_from(">Hb", self._buffer, self._buff_i)
481-
self._buff_i += 3
482-
if L > self._max_ext_len:
483-
raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
484-
obj = self._read(L)
485-
elif b == 0xC9: # ext 32
486-
typ = TYPE_EXT
487-
self._reserve(5)
488-
L, n = _unpack_from(">Ib", self._buffer, self._buff_i)
489-
self._buff_i += 5
490-
if L > self._max_ext_len:
491-
raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
492-
obj = self._read(L)
493-
elif b == 0xCA:
494-
self._reserve(4)
495-
obj = _unpack_from(">f", self._buffer, self._buff_i)[0]
496-
self._buff_i += 4
497-
elif b == 0xCB:
498-
self._reserve(8)
499-
obj = _unpack_from(">d", self._buffer, self._buff_i)[0]
500-
self._buff_i += 8
501-
elif b == 0xCC:
502-
self._reserve(1)
503-
obj = self._buffer[self._buff_i]
504-
self._buff_i += 1
505-
elif b == 0xCD:
506-
self._reserve(2)
507-
obj = _unpack_from(">H", self._buffer, self._buff_i)[0]
508-
self._buff_i += 2
509-
elif b == 0xCE:
510-
self._reserve(4)
511-
obj = _unpack_from(">I", self._buffer, self._buff_i)[0]
512-
self._buff_i += 4
513-
elif b == 0xCF:
514-
self._reserve(8)
515-
obj = _unpack_from(">Q", self._buffer, self._buff_i)[0]
516-
self._buff_i += 8
517-
elif b == 0xD0:
518-
self._reserve(1)
519-
obj = _unpack_from("b", self._buffer, self._buff_i)[0]
520-
self._buff_i += 1
521-
elif b == 0xD1:
522-
self._reserve(2)
523-
obj = _unpack_from(">h", self._buffer, self._buff_i)[0]
524-
self._buff_i += 2
525-
elif b == 0xD2:
526-
self._reserve(4)
527-
obj = _unpack_from(">i", self._buffer, self._buff_i)[0]
528-
self._buff_i += 4
529-
elif b == 0xD3:
530-
self._reserve(8)
531-
obj = _unpack_from(">q", self._buffer, self._buff_i)[0]
532-
self._buff_i += 8
533-
elif b == 0xD4: # fixext 1
534-
typ = TYPE_EXT
535-
if self._max_ext_len < 1:
536-
raise ValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len))
537-
self._reserve(2)
538-
n, obj = _unpack_from("b1s", self._buffer, self._buff_i)
539-
self._buff_i += 2
540-
elif b == 0xD5: # fixext 2
541-
typ = TYPE_EXT
542-
if self._max_ext_len < 2:
543-
raise ValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len))
544-
self._reserve(3)
545-
n, obj = _unpack_from("b2s", self._buffer, self._buff_i)
546-
self._buff_i += 3
547-
elif b == 0xD6: # fixext 4
548-
typ = TYPE_EXT
549-
if self._max_ext_len < 4:
550-
raise ValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len))
551-
self._reserve(5)
552-
n, obj = _unpack_from("b4s", self._buffer, self._buff_i)
553-
self._buff_i += 5
554-
elif b == 0xD7: # fixext 8
555-
typ = TYPE_EXT
556-
if self._max_ext_len < 8:
557-
raise ValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len))
558-
self._reserve(9)
559-
n, obj = _unpack_from("b8s", self._buffer, self._buff_i)
560-
self._buff_i += 9
561-
elif b == 0xD8: # fixext 16
562-
typ = TYPE_EXT
563-
if self._max_ext_len < 16:
564-
raise ValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len))
565-
self._reserve(17)
566-
n, obj = _unpack_from("b16s", self._buffer, self._buff_i)
567-
self._buff_i += 17
568-
elif b == 0xD9:
569-
typ = TYPE_RAW
570-
self._reserve(1)
571-
n = self._buffer[self._buff_i]
572-
self._buff_i += 1
573-
if n > self._max_str_len:
574-
raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
575-
obj = self._read(n)
576-
elif b == 0xDA:
577-
typ = TYPE_RAW
578-
self._reserve(2)
579-
(n,) = _unpack_from(">H", self._buffer, self._buff_i)
580-
self._buff_i += 2
581-
if n > self._max_str_len:
582-
raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
583-
obj = self._read(n)
584-
elif b == 0xDB:
585-
typ = TYPE_RAW
586-
self._reserve(4)
587-
(n,) = _unpack_from(">I", self._buffer, self._buff_i)
588-
self._buff_i += 4
495+
elif 0xCA <= b <= 0xD3:
496+
size, fmt = _MSGPACK_HEADERS[b]
497+
self._reserve(size)
498+
if len(fmt) > 0:
499+
obj = _unpack_from(fmt, self._buffer, self._buff_i)[0]
500+
else:
501+
obj = self._buffer[self._buff_i]
502+
self._buff_i += size
503+
elif 0xD4 <= b <= 0xD8:
504+
size, fmt, typ = _MSGPACK_HEADERS[b]
505+
if self._max_ext_len < size:
506+
raise ValueError(
507+
"%s exceeds max_ext_len(%s)" % (size, self._max_ext_len)
508+
)
509+
self._reserve(size + 1)
510+
n, obj = _unpack_from(fmt, self._buffer, self._buff_i)
511+
self._buff_i += size + 1
512+
elif 0xD9 <= b <= 0xDB:
513+
size, fmt, typ = _MSGPACK_HEADERS[b]
514+
self._reserve(size)
515+
if len(fmt) > 0:
516+
(n,) = _unpack_from(fmt, self._buffer, self._buff_i)
517+
else:
518+
n = self._buffer[self._buff_i]
519+
self._buff_i += size
589520
if n > self._max_str_len:
590521
raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
591522
obj = self._read(n)
592-
elif b == 0xDC:
593-
typ = TYPE_ARRAY
594-
self._reserve(2)
595-
(n,) = _unpack_from(">H", self._buffer, self._buff_i)
596-
self._buff_i += 2
597-
if n > self._max_array_len:
598-
raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len)
599-
elif b == 0xDD:
600-
typ = TYPE_ARRAY
601-
self._reserve(4)
602-
(n,) = _unpack_from(">I", self._buffer, self._buff_i)
603-
self._buff_i += 4
523+
elif 0xDC <= b <= 0xDD:
524+
size, fmt, typ = _MSGPACK_HEADERS[b]
525+
self._reserve(size)
526+
(n,) = _unpack_from(fmt, self._buffer, self._buff_i)
527+
self._buff_i += size
604528
if n > self._max_array_len:
605529
raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len)
606-
elif b == 0xDE:
607-
self._reserve(2)
608-
(n,) = _unpack_from(">H", self._buffer, self._buff_i)
609-
self._buff_i += 2
530+
elif 0xDE <= b <= 0xDF:
531+
size, fmt, typ = _MSGPACK_HEADERS[b]
532+
self._reserve(size)
533+
(n,) = _unpack_from(fmt, self._buffer, self._buff_i)
534+
self._buff_i += size
610535
if n > self._max_map_len:
611536
raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len)
612-
typ = TYPE_MAP
613-
elif b == 0xDF:
614-
self._reserve(4)
615-
(n,) = _unpack_from(">I", self._buffer, self._buff_i)
616-
self._buff_i += 4
617-
if n > self._max_map_len:
618-
raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len)
619-
typ = TYPE_MAP
620537
else:
621538
raise FormatError("Unknown header: 0x%x" % b)
622539
return typ, n, obj
623540

624541
def _unpack(self, execute=EX_CONSTRUCT):
625-
typ, n, obj = self._read_header(execute)
542+
typ, n, obj = self._read_header()
626543

627544
if execute == EX_READ_ARRAY_HEADER:
628545
if typ != TYPE_ARRAY:

0 commit comments

Comments
 (0)
0