feat: speed up unmarshalling int16 types (#81)

This commit is contained in:
J. Nick Koston
2022-10-06 21:55:11 -10:00
committed by GitHub
parent 0b814ce47f
commit 18213c0a00
2 changed files with 17 additions and 5 deletions

View File

@@ -16,11 +16,14 @@ cdef str HEADER_SIGNATURE
cdef unsigned int UINT32_SIZE cdef unsigned int UINT32_SIZE
cdef unsigned int INT16_SIZE
cdef unsigned int HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION cdef unsigned int HEADER_ARRAY_OF_STRUCT_SIGNATURE_POSITION
cdef unsigned int HEADER_SIGNATURE_SIZE cdef unsigned int HEADER_SIGNATURE_SIZE
cdef unsigned int LITTLE_ENDIAN cdef unsigned int LITTLE_ENDIAN
cdef unsigned int BIG_ENDIAN cdef unsigned int BIG_ENDIAN
cdef str UINT32_CAST cdef str UINT32_CAST
cdef str INT16_CAST
cdef object UINT32_SIGNATURE cdef object UINT32_SIGNATURE
cdef class MarshallerStreamEndError(Exception): cdef class MarshallerStreamEndError(Exception):

View File

@@ -3,7 +3,7 @@ import io
import socket import socket
import sys import sys
from struct import Struct from struct import Struct
from typing import Any, Callable, Dict, List, Tuple from typing import Any, Callable, Dict, List, Optional, Tuple
from ..constants import MESSAGE_FLAG_MAP, MESSAGE_TYPE_MAP from ..constants import MESSAGE_FLAG_MAP, MESSAGE_TYPE_MAP
from ..errors import InvalidMessageError from ..errors import InvalidMessageError
@@ -30,16 +30,20 @@ UINT32_SIZE = 4
UINT32_DBUS_TYPE = "u" UINT32_DBUS_TYPE = "u"
UINT32_SIGNATURE = get_signature_tree(UINT32_DBUS_TYPE).types[0] UINT32_SIGNATURE = get_signature_tree(UINT32_DBUS_TYPE).types[0]
INT16_CAST = "h"
INT16_SIZE = 2
INT16_DBUS_TYPE = "n"
DBUS_TO_CTYPE = { DBUS_TO_CTYPE = {
"y": ("B", 1), # byte "y": ("B", 1), # byte
"n": ("h", 2), # int16 INT16_DBUS_TYPE: (INT16_CAST, INT16_SIZE), # int16
"q": ("H", 2), # uint16 "q": ("H", 2), # uint16
"i": ("i", 4), # int32 "i": ("i", 4), # int32
UINT32_DBUS_TYPE: (UINT32_CAST, UINT32_SIZE), # uint32 UINT32_DBUS_TYPE: (UINT32_CAST, UINT32_SIZE), # uint32
"x": ("q", 8), # int64 "x": ("q", 8), # int64
"t": ("Q", 8), # uint64 "t": ("Q", 8), # uint64
"d": ("d", 8), # double "d": ("d", 8), # double
"h": ("I", 4), # uint32 "h": (UINT32_CAST, UINT32_SIZE), # uint32
} }
UINT32_UNPACK_BY_ENDIAN = { UINT32_UNPACK_BY_ENDIAN = {
@@ -237,10 +241,14 @@ class Unmarshaller:
if len(data) + start_len != pos: if len(data) + start_len != pos:
raise MarshallerStreamEndError() raise MarshallerStreamEndError()
def read_uint32_cast(self, type_: SignatureType) -> Any: def read_uint32_cast(self, type_: SignatureType) -> int:
self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align self._pos += UINT32_SIZE + (-self._pos & (UINT32_SIZE - 1)) # align
return self._view[self._pos - UINT32_SIZE : self._pos].cast(UINT32_CAST)[0] return self._view[self._pos - UINT32_SIZE : self._pos].cast(UINT32_CAST)[0]
def read_int16_cast(self, type_: SignatureType) -> int:
self._pos += INT16_SIZE + (-self._pos & (INT16_SIZE - 1)) # align
return self._view[self._pos - INT16_SIZE : self._pos].cast(INT16_CAST)[0]
def read_boolean(self, type_: SignatureType) -> bool: def read_boolean(self, type_: SignatureType) -> bool:
return bool(self._readers[UINT32_SIGNATURE.token](self, UINT32_SIGNATURE)) return bool(self._readers[UINT32_SIGNATURE.token](self, UINT32_SIGNATURE))
@@ -414,7 +422,7 @@ class Unmarshaller:
validate=False, validate=False,
) )
def unmarshall(self): def unmarshall(self) -> Optional[Message]:
"""Unmarshall the message. """Unmarshall the message.
The underlying read function will raise MarshallerStreamEndError The underlying read function will raise MarshallerStreamEndError
@@ -453,6 +461,7 @@ class Unmarshaller:
"v": read_variant, "v": read_variant,
"h": read_uint32_cast, "h": read_uint32_cast,
UINT32_DBUS_TYPE: read_uint32_cast, UINT32_DBUS_TYPE: read_uint32_cast,
INT16_DBUS_TYPE: read_int16_cast,
} }
_ctype_by_endian: Dict[ _ctype_by_endian: Dict[