feat: speed up marshalling headers (#142)
This commit is contained in:
@@ -15,19 +15,28 @@ cdef class Marshaller:
|
|||||||
cdef bytearray _buf
|
cdef bytearray _buf
|
||||||
cdef object body
|
cdef object body
|
||||||
|
|
||||||
cpdef unsigned int align(self, unsigned int n)
|
cpdef align(self, unsigned int n)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
offset=cython.ulong,
|
offset=cython.ulong,
|
||||||
)
|
)
|
||||||
cdef unsigned int _align(self, unsigned int n)
|
cdef unsigned int _align(self, unsigned int n)
|
||||||
|
|
||||||
|
cpdef write_boolean(self, object boolean, object _type)
|
||||||
|
|
||||||
|
@cython.locals(
|
||||||
|
written=cython.uint,
|
||||||
|
)
|
||||||
|
cdef unsigned int _write_boolean(self, object boolean)
|
||||||
|
|
||||||
|
cpdef write_string(self, str value, object _type)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
value_len=cython.uint,
|
value_len=cython.uint,
|
||||||
signature_len=cython.uint,
|
signature_len=cython.uint,
|
||||||
written=cython.uint,
|
written=cython.uint,
|
||||||
)
|
)
|
||||||
cpdef write_string(self, str value, object _type)
|
cdef unsigned int _write_string(self, str value)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
signature_len=cython.uint,
|
signature_len=cython.uint,
|
||||||
@@ -57,12 +66,14 @@ cdef class Marshaller:
|
|||||||
)
|
)
|
||||||
cdef unsigned int _write_struct(self, object array, object type)
|
cdef unsigned int _write_struct(self, object array, object type)
|
||||||
|
|
||||||
|
cpdef write_variant(self, object variant, object type)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
written=cython.uint,
|
written=cython.uint,
|
||||||
signature=cython.str,
|
signature=cython.str,
|
||||||
signature_bytes=cython.bytes,
|
signature_bytes=cython.bytes,
|
||||||
)
|
)
|
||||||
cpdef write_variant(self, object variant, object type)
|
cdef unsigned int _write_variant(self, object variant, object type)
|
||||||
|
|
||||||
@cython.locals(
|
@cython.locals(
|
||||||
written=cython.uint,
|
written=cython.uint,
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ class Marshaller:
|
|||||||
return offset
|
return offset
|
||||||
|
|
||||||
def write_boolean(self, boolean: bool, type_: SignatureType) -> int:
|
def write_boolean(self, boolean: bool, type_: SignatureType) -> int:
|
||||||
|
return self._write_boolean(boolean)
|
||||||
|
|
||||||
|
def _write_boolean(self, boolean: bool) -> int:
|
||||||
written = self._align(4)
|
written = self._align(4)
|
||||||
self._buf += PACKED_BOOL_TRUE if boolean else PACKED_BOOL_FALSE
|
self._buf += PACKED_BOOL_TRUE if boolean else PACKED_BOOL_FALSE
|
||||||
return written + 4
|
return written + 4
|
||||||
@@ -47,23 +50,29 @@ class Marshaller:
|
|||||||
signature_len = len(signature_bytes)
|
signature_len = len(signature_bytes)
|
||||||
buf = self._buf
|
buf = self._buf
|
||||||
buf.append(signature_len)
|
buf.append(signature_len)
|
||||||
buf.extend(signature_bytes)
|
buf += signature_bytes
|
||||||
buf.append(0)
|
buf.append(0)
|
||||||
return signature_len + 2
|
return signature_len + 2
|
||||||
|
|
||||||
def write_string(self, value, type_: SignatureType) -> int:
|
def write_string(self, value, type_: SignatureType) -> int:
|
||||||
|
return self._write_string(value)
|
||||||
|
|
||||||
|
def _write_string(self, value) -> int:
|
||||||
value_bytes = value.encode()
|
value_bytes = value.encode()
|
||||||
value_len = len(value)
|
value_len = len(value)
|
||||||
written = self._align(4) + 4
|
written = self._align(4) + 4
|
||||||
buf = self._buf
|
buf = self._buf
|
||||||
buf.extend(PACK_UINT32(value_len))
|
buf += PACK_UINT32(value_len)
|
||||||
buf.extend(value_bytes)
|
buf += value_bytes
|
||||||
written += value_len
|
written += value_len
|
||||||
buf.append(0)
|
buf.append(0)
|
||||||
written += 1
|
written += 1
|
||||||
return written
|
return written
|
||||||
|
|
||||||
def write_variant(self, variant: Variant, type_: SignatureType) -> int:
|
def write_variant(self, variant: Variant, type_: SignatureType) -> int:
|
||||||
|
return self._write_variant(variant, type_)
|
||||||
|
|
||||||
|
def _write_variant(self, variant: Variant, type_: SignatureType) -> int:
|
||||||
signature = variant.signature
|
signature = variant.signature
|
||||||
signature_bytes = signature.encode()
|
signature_bytes = signature.encode()
|
||||||
written = self._write_signature(signature_bytes)
|
written = self._write_signature(signature_bytes)
|
||||||
@@ -84,7 +93,7 @@ class Marshaller:
|
|||||||
buf = self._buf
|
buf = self._buf
|
||||||
offset = len(buf)
|
offset = len(buf)
|
||||||
written += self._align(4) + 4
|
written += self._align(4) + 4
|
||||||
buf.extend(PACKED_UINT32_ZERO)
|
buf += PACKED_UINT32_ZERO
|
||||||
child_type = type_.children[0]
|
child_type = type_.children[0]
|
||||||
token = child_type.token
|
token = child_type.token
|
||||||
|
|
||||||
@@ -98,7 +107,7 @@ class Marshaller:
|
|||||||
array_len += self.write_dict_entry([key, value], child_type)
|
array_len += self.write_dict_entry([key, value], child_type)
|
||||||
elif token == "y":
|
elif token == "y":
|
||||||
array_len = len(array)
|
array_len = len(array)
|
||||||
buf.extend(array)
|
buf += array
|
||||||
elif token == "(":
|
elif token == "(":
|
||||||
for value in array:
|
for value in array:
|
||||||
array_len += self._write_struct(value, child_type)
|
array_len += self._write_struct(value, child_type)
|
||||||
@@ -107,7 +116,7 @@ class Marshaller:
|
|||||||
if not writer:
|
if not writer:
|
||||||
for value in array:
|
for value in array:
|
||||||
array_len += self._align(size) + size
|
array_len += self._align(size) + size
|
||||||
buf.extend(packer(value)) # type: ignore[misc]
|
buf += packer(value) # type: ignore[misc]
|
||||||
else:
|
else:
|
||||||
for value in array:
|
for value in array:
|
||||||
array_len += writer(self, value, child_type)
|
array_len += writer(self, value, child_type)
|
||||||
@@ -135,12 +144,28 @@ class Marshaller:
|
|||||||
|
|
||||||
def _write_single(self, type_: SignatureType, body: Any) -> int:
|
def _write_single(self, type_: SignatureType, body: Any) -> int:
|
||||||
t = type_.token
|
t = type_.token
|
||||||
writer, packer, size = self._writers[t]
|
if t == "y":
|
||||||
if not writer:
|
self._buf.append(body)
|
||||||
written = self._align(size)
|
return 1
|
||||||
self._buf.extend(packer(body)) # type: ignore[misc]
|
elif t == "u":
|
||||||
return written + size
|
written = self._align(4)
|
||||||
return writer(self, body, type_)
|
self._buf += PACK_UINT32(body)
|
||||||
|
return written + 4
|
||||||
|
elif t == "a":
|
||||||
|
return self._write_array(body, type_)
|
||||||
|
elif t == "s" or t == "o":
|
||||||
|
return self._write_string(body)
|
||||||
|
elif t == "v":
|
||||||
|
return self._write_variant(body, type_)
|
||||||
|
elif t == "b":
|
||||||
|
return self._write_boolean(body)
|
||||||
|
else:
|
||||||
|
writer, packer, size = self._writers[t]
|
||||||
|
if not writer:
|
||||||
|
written = self._align(size)
|
||||||
|
self._buf += packer(body) # type: ignore[misc]
|
||||||
|
return written + size
|
||||||
|
return writer(self, body, type_)
|
||||||
|
|
||||||
def marshall(self) -> bytearray:
|
def marshall(self) -> bytearray:
|
||||||
"""Marshalls the body into a byte array"""
|
"""Marshalls the body into a byte array"""
|
||||||
@@ -154,26 +179,9 @@ class Marshaller:
|
|||||||
|
|
||||||
def _construct_buffer(self) -> None:
|
def _construct_buffer(self) -> None:
|
||||||
self._buf.clear()
|
self._buf.clear()
|
||||||
writers = self._writers
|
|
||||||
body = self.body
|
body = self.body
|
||||||
buf = self._buf
|
|
||||||
for i, type_ in enumerate(self.signature_tree.types):
|
for i, type_ in enumerate(self.signature_tree.types):
|
||||||
t = type_.token
|
self._write_single(type_, body[i])
|
||||||
if t == "y":
|
|
||||||
buf.append(body[i])
|
|
||||||
elif t == "u":
|
|
||||||
self._align(4)
|
|
||||||
buf.extend(PACK_UINT32(body[i]))
|
|
||||||
elif t == "a":
|
|
||||||
self._write_array(body[i], type_)
|
|
||||||
else:
|
|
||||||
writer, packer, size = writers[t]
|
|
||||||
if not writer:
|
|
||||||
if size != 1:
|
|
||||||
self._align(size)
|
|
||||||
buf.extend(packer(body[i])) # type: ignore[misc]
|
|
||||||
else:
|
|
||||||
writer(self, body[i], type_)
|
|
||||||
|
|
||||||
_writers: Dict[
|
_writers: Dict[
|
||||||
str,
|
str,
|
||||||
|
|||||||
Reference in New Issue
Block a user