Skip to content

Commit

Permalink
feat: speed up unmarshalling message body (#255)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco authored Sep 20, 2023
1 parent 50b283a commit 5aed075
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 70 deletions.
4 changes: 3 additions & 1 deletion src/dbus_fast/_private/unmarshaller.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,9 @@ cdef class Unmarshaller:

@cython.locals(
body=cython.list,
header_fields=cython.dict
header_fields=cython.dict,
token_as_int=cython.uint,
signature=cython.str,
)
cdef _read_body(self)

Expand Down
146 changes: 77 additions & 69 deletions src/dbus_fast/_private/unmarshaller.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
TOKEN_B_AS_INT = ord("b")
TOKEN_U_AS_INT = ord("u")
TOKEN_Y_AS_INT = ord("y")
TOKEN_A_AS_INT = ord("o")
TOKEN_A_AS_INT = ord("a")
TOKEN_O_AS_INT = ord("o")
TOKEN_S_AS_INT = ord("s")
TOKEN_G_AS_INT = ord("g")
Expand Down Expand Up @@ -437,45 +437,47 @@ def read_variant(self, type_: _SignatureType) -> Variant:

def _read_variant(self) -> Variant:
signature = self._read_signature()
token_as_int = signature[0]
token_as_int = ord(signature[0])
# verify in Variant is only useful on construction not unmarshalling
if token_as_int == TOKEN_N_AS_INT:
return Variant(SIGNATURE_TREE_N, self._read_int16_unpack(), False)
elif token_as_int == TOKEN_A_AS_INT and signature == "ay":
return Variant(
SIGNATURE_TREE_AY, self.read_array(SIGNATURE_TREE_AY_TYPES_0), False
)
elif token_as_int == TOKEN_A_AS_INT and signature == "a{qv}":
return Variant(
SIGNATURE_TREE_A_QV,
self.read_array(SIGNATURE_TREE_A_QV_TYPES_0),
False,
)
elif token_as_int == TOKEN_S_AS_INT:
return Variant(SIGNATURE_TREE_S, self._read_string_unpack(), False)
elif token_as_int == TOKEN_B_AS_INT:
return Variant(SIGNATURE_TREE_B, self._read_boolean(), False)
elif token_as_int == TOKEN_O_AS_INT:
return Variant(SIGNATURE_TREE_O, self._read_string_unpack(), False)
elif token_as_int == TOKEN_A_AS_INT and signature == "as":
return Variant(
SIGNATURE_TREE_AS, self.read_array(SIGNATURE_TREE_AS_TYPES_0), False
)
elif token_as_int == TOKEN_A_AS_INT and signature == "a{sv}":
return Variant(
SIGNATURE_TREE_A_SV,
self.read_array(SIGNATURE_TREE_A_SV_TYPES_0),
False,
)
elif token_as_int == TOKEN_A_AS_INT and signature == "ao":
return Variant(
SIGNATURE_TREE_AO, self.read_array(SIGNATURE_TREE_AO_TYPES_0), False
)
elif token_as_int == TOKEN_U_AS_INT:
return Variant(SIGNATURE_TREE_U, self._read_uint32_unpack(), False)
elif token_as_int == TOKEN_Y_AS_INT:
self._pos += 1
return Variant(SIGNATURE_TREE_Y, self._buf[self._pos - 1], False)
if len(signature) == 1:
if token_as_int == TOKEN_N_AS_INT:
return Variant(SIGNATURE_TREE_N, self._read_int16_unpack(), False)
if token_as_int == TOKEN_S_AS_INT:
return Variant(SIGNATURE_TREE_S, self._read_string_unpack(), False)
if token_as_int == TOKEN_B_AS_INT:
return Variant(SIGNATURE_TREE_B, self._read_boolean(), False)
if token_as_int == TOKEN_O_AS_INT:
return Variant(SIGNATURE_TREE_O, self._read_string_unpack(), False)
if token_as_int == TOKEN_U_AS_INT:
return Variant(SIGNATURE_TREE_U, self._read_uint32_unpack(), False)
if token_as_int == TOKEN_Y_AS_INT:
self._pos += 1
return Variant(SIGNATURE_TREE_Y, self._buf[self._pos - 1], False)
elif token_as_int == TOKEN_A_AS_INT:
if signature == "ay":
return Variant(
SIGNATURE_TREE_AY, self.read_array(SIGNATURE_TREE_AY_TYPES_0), False
)
if signature == "a{qv}":
return Variant(
SIGNATURE_TREE_A_QV,
self.read_array(SIGNATURE_TREE_A_QV_TYPES_0),
False,
)
if signature == "as":
return Variant(
SIGNATURE_TREE_AS, self.read_array(SIGNATURE_TREE_AS_TYPES_0), False
)
if signature == "a{sv}":
return Variant(
SIGNATURE_TREE_A_SV,
self.read_array(SIGNATURE_TREE_A_SV_TYPES_0),
False,
)
if signature == "ao":
return Variant(
SIGNATURE_TREE_AO, self.read_array(SIGNATURE_TREE_AO_TYPES_0), False
)
tree = get_signature_tree(signature)
signature_type = tree.types[0]
return Variant(
Expand Down Expand Up @@ -674,37 +676,43 @@ def _read_body(self) -> None:
if not self._body_len:
tree = SIGNATURE_TREE_EMPTY
body: List[Any] = []
elif signature == "s":
tree = SIGNATURE_TREE_S
body = [self._read_string_unpack()]
elif signature == "sa{sv}as":
tree = SIGNATURE_TREE_SA_SV_AS
body = [
self._read_string_unpack(),
self.read_array(SIGNATURE_TREE_SA_SV_AS_TYPES_1),
self.read_array(SIGNATURE_TREE_SA_SV_AS_TYPES_2),
]
elif signature == "oa{sa{sv}}":
tree = SIGNATURE_TREE_OA_SA_SV
body = [
self._read_string_unpack(),
self.read_array(SIGNATURE_TREE_OA_SA_SV_TYPES_1),
]
elif signature == "oas":
tree = SIGNATURE_TREE_OAS
body = [
self._read_string_unpack(),
self.read_array(SIGNATURE_TREE_OAS_TYPES_1),
]
elif signature == "a{oa{sa{sv}}}":
tree = SIGNATURE_TREE_A_OA_SA_SV
body = [self.read_array(SIGNATURE_TREE_A_OA_SA_SV_TYPES_0)]
elif signature == "o":
tree = SIGNATURE_TREE_O
body = [self._read_string_unpack()]
else:
tree = get_signature_tree(signature)
body = [self._readers[t.token](self, t) for t in tree.types]
token_as_int = ord(signature[0])
if len(signature) == 1:
if token_as_int == TOKEN_O_AS_INT:
tree = SIGNATURE_TREE_O
body = [self._read_string_unpack()]
elif token_as_int == TOKEN_S_AS_INT:
tree = SIGNATURE_TREE_S
body = [self._read_string_unpack()]
else:
tree = get_signature_tree(signature)
body = [self._readers[t.token](self, t) for t in tree.types]
elif token_as_int == TOKEN_S_AS_INT and signature == "sa{sv}as":
tree = SIGNATURE_TREE_SA_SV_AS
body = [
self._read_string_unpack(),
self.read_array(SIGNATURE_TREE_SA_SV_AS_TYPES_1),
self.read_array(SIGNATURE_TREE_SA_SV_AS_TYPES_2),
]
elif token_as_int == TOKEN_O_AS_INT and signature == "oa{sa{sv}}":
tree = SIGNATURE_TREE_OA_SA_SV
body = [
self._read_string_unpack(),
self.read_array(SIGNATURE_TREE_OA_SA_SV_TYPES_1),
]
elif token_as_int == TOKEN_O_AS_INT and signature == "oas":
tree = SIGNATURE_TREE_OAS
body = [
self._read_string_unpack(),
self.read_array(SIGNATURE_TREE_OAS_TYPES_1),
]
elif token_as_int == TOKEN_A_AS_INT and signature == "a{oa{sa{sv}}}":
tree = SIGNATURE_TREE_A_OA_SA_SV
body = [self.read_array(SIGNATURE_TREE_A_OA_SA_SV_TYPES_0)]
else:
tree = get_signature_tree(signature)
body = [self._readers[t.token](self, t) for t in tree.types]

flags = MESSAGE_FLAG_MAP.get(self._flag)
if flags is None:
Expand Down

0 comments on commit 5aed075

Please sign in to comment.