mirror of
https://github.com/msgpack/msgpack-python.git
synced 2025-10-20 04:13:16 +00:00
Refactor fallback read header (#441)
This commit is contained in:
parent
431ef45c8e
commit
3b71818bb0
1 changed files with 82 additions and 165 deletions
|
@ -1,5 +1,4 @@
|
||||||
"""Fallback pure Python implementation of msgpack"""
|
"""Fallback pure Python implementation of msgpack"""
|
||||||
|
|
||||||
from datetime import datetime as _DateTime
|
from datetime import datetime as _DateTime
|
||||||
import sys
|
import sys
|
||||||
import struct
|
import struct
|
||||||
|
@ -148,6 +147,38 @@ if sys.version_info < (2, 7, 6):
|
||||||
else:
|
else:
|
||||||
_unpack_from = struct.unpack_from
|
_unpack_from = struct.unpack_from
|
||||||
|
|
||||||
|
_NO_FORMAT_USED = ""
|
||||||
|
_MSGPACK_HEADERS = {
|
||||||
|
0xC4: (1, _NO_FORMAT_USED, TYPE_BIN),
|
||||||
|
0xC5: (2, ">H", TYPE_BIN),
|
||||||
|
0xC6: (4, ">I", TYPE_BIN),
|
||||||
|
0xC7: (2, "Bb", TYPE_EXT),
|
||||||
|
0xC8: (3, ">Hb", TYPE_EXT),
|
||||||
|
0xC9: (5, ">Ib", TYPE_EXT),
|
||||||
|
0xCA: (4, ">f"),
|
||||||
|
0xCB: (8, ">d"),
|
||||||
|
0xCC: (1, _NO_FORMAT_USED),
|
||||||
|
0xCD: (2, ">H"),
|
||||||
|
0xCE: (4, ">I"),
|
||||||
|
0xCF: (8, ">Q"),
|
||||||
|
0xD0: (1, "b"),
|
||||||
|
0xD1: (2, ">h"),
|
||||||
|
0xD2: (4, ">i"),
|
||||||
|
0xD3: (8, ">q"),
|
||||||
|
0xD4: (1, "b1s", TYPE_EXT),
|
||||||
|
0xD5: (2, "b2s", TYPE_EXT),
|
||||||
|
0xD6: (4, "b4s", TYPE_EXT),
|
||||||
|
0xD7: (8, "b8s", TYPE_EXT),
|
||||||
|
0xD8: (16, "b16s", TYPE_EXT),
|
||||||
|
0xD9: (1, _NO_FORMAT_USED, TYPE_RAW),
|
||||||
|
0xDA: (2, ">H", TYPE_RAW),
|
||||||
|
0xDB: (4, ">I", TYPE_RAW),
|
||||||
|
0xDC: (2, ">H", TYPE_ARRAY),
|
||||||
|
0xDD: (4, ">I", TYPE_ARRAY),
|
||||||
|
0xDE: (2, ">H", TYPE_MAP),
|
||||||
|
0xDF: (4, ">I", TYPE_MAP),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Unpacker(object):
|
class Unpacker(object):
|
||||||
"""Streaming unpacker.
|
"""Streaming unpacker.
|
||||||
|
@ -409,7 +440,7 @@ class Unpacker(object):
|
||||||
self._buff_i = 0 # rollback
|
self._buff_i = 0 # rollback
|
||||||
raise OutOfData
|
raise OutOfData
|
||||||
|
|
||||||
def _read_header(self, execute=EX_CONSTRUCT):
|
def _read_header(self):
|
||||||
typ = TYPE_IMMEDIATE
|
typ = TYPE_IMMEDIATE
|
||||||
n = 0
|
n = 0
|
||||||
obj = None
|
obj = None
|
||||||
|
@ -442,187 +473,73 @@ class Unpacker(object):
|
||||||
obj = False
|
obj = False
|
||||||
elif b == 0xC3:
|
elif b == 0xC3:
|
||||||
obj = True
|
obj = True
|
||||||
elif b == 0xC4:
|
elif 0xC4 <= b <= 0xC6:
|
||||||
typ = TYPE_BIN
|
size, fmt, typ = _MSGPACK_HEADERS[b]
|
||||||
self._reserve(1)
|
self._reserve(size)
|
||||||
n = self._buffer[self._buff_i]
|
if len(fmt) > 0:
|
||||||
self._buff_i += 1
|
n = _unpack_from(fmt, self._buffer, self._buff_i)[0]
|
||||||
|
else:
|
||||||
|
n = self._buffer[self._buff_i]
|
||||||
|
self._buff_i += size
|
||||||
if n > self._max_bin_len:
|
if n > self._max_bin_len:
|
||||||
raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
|
raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
|
||||||
obj = self._read(n)
|
obj = self._read(n)
|
||||||
elif b == 0xC5:
|
elif 0xC7 <= b <= 0xC9:
|
||||||
typ = TYPE_BIN
|
size, fmt, typ = _MSGPACK_HEADERS[b]
|
||||||
self._reserve(2)
|
self._reserve(size)
|
||||||
n = _unpack_from(">H", self._buffer, self._buff_i)[0]
|
L, n = _unpack_from(fmt, self._buffer, self._buff_i)
|
||||||
self._buff_i += 2
|
self._buff_i += size
|
||||||
if n > self._max_bin_len:
|
|
||||||
raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
|
|
||||||
obj = self._read(n)
|
|
||||||
elif b == 0xC6:
|
|
||||||
typ = TYPE_BIN
|
|
||||||
self._reserve(4)
|
|
||||||
n = _unpack_from(">I", self._buffer, self._buff_i)[0]
|
|
||||||
self._buff_i += 4
|
|
||||||
if n > self._max_bin_len:
|
|
||||||
raise ValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len))
|
|
||||||
obj = self._read(n)
|
|
||||||
elif b == 0xC7: # ext 8
|
|
||||||
typ = TYPE_EXT
|
|
||||||
self._reserve(2)
|
|
||||||
L, n = _unpack_from("Bb", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 2
|
|
||||||
if L > self._max_ext_len:
|
if L > self._max_ext_len:
|
||||||
raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
|
raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
|
||||||
obj = self._read(L)
|
obj = self._read(L)
|
||||||
elif b == 0xC8: # ext 16
|
elif 0xCA <= b <= 0xD3:
|
||||||
typ = TYPE_EXT
|
size, fmt = _MSGPACK_HEADERS[b]
|
||||||
self._reserve(3)
|
self._reserve(size)
|
||||||
L, n = _unpack_from(">Hb", self._buffer, self._buff_i)
|
if len(fmt) > 0:
|
||||||
self._buff_i += 3
|
obj = _unpack_from(fmt, self._buffer, self._buff_i)[0]
|
||||||
if L > self._max_ext_len:
|
else:
|
||||||
raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
|
obj = self._buffer[self._buff_i]
|
||||||
obj = self._read(L)
|
self._buff_i += size
|
||||||
elif b == 0xC9: # ext 32
|
elif 0xD4 <= b <= 0xD8:
|
||||||
typ = TYPE_EXT
|
size, fmt, typ = _MSGPACK_HEADERS[b]
|
||||||
self._reserve(5)
|
if self._max_ext_len < size:
|
||||||
L, n = _unpack_from(">Ib", self._buffer, self._buff_i)
|
raise ValueError(
|
||||||
self._buff_i += 5
|
"%s exceeds max_ext_len(%s)" % (size, self._max_ext_len)
|
||||||
if L > self._max_ext_len:
|
)
|
||||||
raise ValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len))
|
self._reserve(size + 1)
|
||||||
obj = self._read(L)
|
n, obj = _unpack_from(fmt, self._buffer, self._buff_i)
|
||||||
elif b == 0xCA:
|
self._buff_i += size + 1
|
||||||
self._reserve(4)
|
elif 0xD9 <= b <= 0xDB:
|
||||||
obj = _unpack_from(">f", self._buffer, self._buff_i)[0]
|
size, fmt, typ = _MSGPACK_HEADERS[b]
|
||||||
self._buff_i += 4
|
self._reserve(size)
|
||||||
elif b == 0xCB:
|
if len(fmt) > 0:
|
||||||
self._reserve(8)
|
(n,) = _unpack_from(fmt, self._buffer, self._buff_i)
|
||||||
obj = _unpack_from(">d", self._buffer, self._buff_i)[0]
|
else:
|
||||||
self._buff_i += 8
|
n = self._buffer[self._buff_i]
|
||||||
elif b == 0xCC:
|
self._buff_i += size
|
||||||
self._reserve(1)
|
|
||||||
obj = self._buffer[self._buff_i]
|
|
||||||
self._buff_i += 1
|
|
||||||
elif b == 0xCD:
|
|
||||||
self._reserve(2)
|
|
||||||
obj = _unpack_from(">H", self._buffer, self._buff_i)[0]
|
|
||||||
self._buff_i += 2
|
|
||||||
elif b == 0xCE:
|
|
||||||
self._reserve(4)
|
|
||||||
obj = _unpack_from(">I", self._buffer, self._buff_i)[0]
|
|
||||||
self._buff_i += 4
|
|
||||||
elif b == 0xCF:
|
|
||||||
self._reserve(8)
|
|
||||||
obj = _unpack_from(">Q", self._buffer, self._buff_i)[0]
|
|
||||||
self._buff_i += 8
|
|
||||||
elif b == 0xD0:
|
|
||||||
self._reserve(1)
|
|
||||||
obj = _unpack_from("b", self._buffer, self._buff_i)[0]
|
|
||||||
self._buff_i += 1
|
|
||||||
elif b == 0xD1:
|
|
||||||
self._reserve(2)
|
|
||||||
obj = _unpack_from(">h", self._buffer, self._buff_i)[0]
|
|
||||||
self._buff_i += 2
|
|
||||||
elif b == 0xD2:
|
|
||||||
self._reserve(4)
|
|
||||||
obj = _unpack_from(">i", self._buffer, self._buff_i)[0]
|
|
||||||
self._buff_i += 4
|
|
||||||
elif b == 0xD3:
|
|
||||||
self._reserve(8)
|
|
||||||
obj = _unpack_from(">q", self._buffer, self._buff_i)[0]
|
|
||||||
self._buff_i += 8
|
|
||||||
elif b == 0xD4: # fixext 1
|
|
||||||
typ = TYPE_EXT
|
|
||||||
if self._max_ext_len < 1:
|
|
||||||
raise ValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len))
|
|
||||||
self._reserve(2)
|
|
||||||
n, obj = _unpack_from("b1s", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 2
|
|
||||||
elif b == 0xD5: # fixext 2
|
|
||||||
typ = TYPE_EXT
|
|
||||||
if self._max_ext_len < 2:
|
|
||||||
raise ValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len))
|
|
||||||
self._reserve(3)
|
|
||||||
n, obj = _unpack_from("b2s", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 3
|
|
||||||
elif b == 0xD6: # fixext 4
|
|
||||||
typ = TYPE_EXT
|
|
||||||
if self._max_ext_len < 4:
|
|
||||||
raise ValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len))
|
|
||||||
self._reserve(5)
|
|
||||||
n, obj = _unpack_from("b4s", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 5
|
|
||||||
elif b == 0xD7: # fixext 8
|
|
||||||
typ = TYPE_EXT
|
|
||||||
if self._max_ext_len < 8:
|
|
||||||
raise ValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len))
|
|
||||||
self._reserve(9)
|
|
||||||
n, obj = _unpack_from("b8s", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 9
|
|
||||||
elif b == 0xD8: # fixext 16
|
|
||||||
typ = TYPE_EXT
|
|
||||||
if self._max_ext_len < 16:
|
|
||||||
raise ValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len))
|
|
||||||
self._reserve(17)
|
|
||||||
n, obj = _unpack_from("b16s", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 17
|
|
||||||
elif b == 0xD9:
|
|
||||||
typ = TYPE_RAW
|
|
||||||
self._reserve(1)
|
|
||||||
n = self._buffer[self._buff_i]
|
|
||||||
self._buff_i += 1
|
|
||||||
if n > self._max_str_len:
|
if n > self._max_str_len:
|
||||||
raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
|
raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
|
||||||
obj = self._read(n)
|
obj = self._read(n)
|
||||||
elif b == 0xDA:
|
elif 0xDC <= b <= 0xDD:
|
||||||
typ = TYPE_RAW
|
size, fmt, typ = _MSGPACK_HEADERS[b]
|
||||||
self._reserve(2)
|
self._reserve(size)
|
||||||
(n,) = _unpack_from(">H", self._buffer, self._buff_i)
|
(n,) = _unpack_from(fmt, self._buffer, self._buff_i)
|
||||||
self._buff_i += 2
|
self._buff_i += size
|
||||||
if n > self._max_str_len:
|
|
||||||
raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
|
|
||||||
obj = self._read(n)
|
|
||||||
elif b == 0xDB:
|
|
||||||
typ = TYPE_RAW
|
|
||||||
self._reserve(4)
|
|
||||||
(n,) = _unpack_from(">I", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 4
|
|
||||||
if n > self._max_str_len:
|
|
||||||
raise ValueError("%s exceeds max_str_len(%s)", n, self._max_str_len)
|
|
||||||
obj = self._read(n)
|
|
||||||
elif b == 0xDC:
|
|
||||||
typ = TYPE_ARRAY
|
|
||||||
self._reserve(2)
|
|
||||||
(n,) = _unpack_from(">H", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 2
|
|
||||||
if n > self._max_array_len:
|
if n > self._max_array_len:
|
||||||
raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len)
|
raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len)
|
||||||
elif b == 0xDD:
|
elif 0xDE <= b <= 0xDF:
|
||||||
typ = TYPE_ARRAY
|
size, fmt, typ = _MSGPACK_HEADERS[b]
|
||||||
self._reserve(4)
|
self._reserve(size)
|
||||||
(n,) = _unpack_from(">I", self._buffer, self._buff_i)
|
(n,) = _unpack_from(fmt, self._buffer, self._buff_i)
|
||||||
self._buff_i += 4
|
self._buff_i += size
|
||||||
if n > self._max_array_len:
|
|
||||||
raise ValueError("%s exceeds max_array_len(%s)", n, self._max_array_len)
|
|
||||||
elif b == 0xDE:
|
|
||||||
self._reserve(2)
|
|
||||||
(n,) = _unpack_from(">H", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 2
|
|
||||||
if n > self._max_map_len:
|
if n > self._max_map_len:
|
||||||
raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len)
|
raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len)
|
||||||
typ = TYPE_MAP
|
|
||||||
elif b == 0xDF:
|
|
||||||
self._reserve(4)
|
|
||||||
(n,) = _unpack_from(">I", self._buffer, self._buff_i)
|
|
||||||
self._buff_i += 4
|
|
||||||
if n > self._max_map_len:
|
|
||||||
raise ValueError("%s exceeds max_map_len(%s)", n, self._max_map_len)
|
|
||||||
typ = TYPE_MAP
|
|
||||||
else:
|
else:
|
||||||
raise FormatError("Unknown header: 0x%x" % b)
|
raise FormatError("Unknown header: 0x%x" % b)
|
||||||
return typ, n, obj
|
return typ, n, obj
|
||||||
|
|
||||||
def _unpack(self, execute=EX_CONSTRUCT):
|
def _unpack(self, execute=EX_CONSTRUCT):
|
||||||
typ, n, obj = self._read_header(execute)
|
typ, n, obj = self._read_header()
|
||||||
|
|
||||||
if execute == EX_READ_ARRAY_HEADER:
|
if execute == EX_READ_ARRAY_HEADER:
|
||||||
if typ != TYPE_ARRAY:
|
if typ != TYPE_ARRAY:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue