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

Skip to content
Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

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
< C7F2 code>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