diff --git a/src/dbus_fast/_private/marshaller.pxd b/src/dbus_fast/_private/marshaller.pxd index 958b8920..3a8f2642 100644 --- a/src/dbus_fast/_private/marshaller.pxd +++ b/src/dbus_fast/_private/marshaller.pxd @@ -15,19 +15,28 @@ cdef class Marshaller: cdef bytearray _buf cdef object body - cpdef unsigned int align(self, unsigned int n) + cpdef align(self, unsigned int n) @cython.locals( offset=cython.ulong, ) 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( value_len=cython.uint, signature_len=cython.uint, written=cython.uint, ) - cpdef write_string(self, str value, object _type) + cdef unsigned int _write_string(self, str value) @cython.locals( signature_len=cython.uint, @@ -57,12 +66,14 @@ cdef class Marshaller: ) cdef unsigned int _write_struct(self, object array, object type) + cpdef write_variant(self, object variant, object type) + @cython.locals( written=cython.uint, signature=cython.str, signature_bytes=cython.bytes, ) - cpdef write_variant(self, object variant, object type) + cdef unsigned int _write_variant(self, object variant, object type) @cython.locals( written=cython.uint, diff --git a/src/dbus_fast/_private/marshaller.py b/src/dbus_fast/_private/marshaller.py index abd886d1..42dfa89c 100644 --- a/src/dbus_fast/_private/marshaller.py +++ b/src/dbus_fast/_private/marshaller.py @@ -36,6 +36,9 @@ def _align(self, n): return offset 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) self._buf += PACKED_BOOL_TRUE if boolean else PACKED_BOOL_FALSE return written + 4 @@ -47,23 +50,29 @@ def _write_signature(self, signature_bytes) -> int: signature_len = len(signature_bytes) buf = self._buf buf.append(signature_len) - buf.extend(signature_bytes) + buf += signature_bytes buf.append(0) return signature_len + 2 def write_string(self, value, type_: SignatureType) -> int: + return self._write_string(value) + + def _write_string(self, value) -> int: value_bytes = value.encode() value_len = len(value) written = self._align(4) + 4 buf = self._buf - buf.extend(PACK_UINT32(value_len)) - buf.extend(value_bytes) + buf += PACK_UINT32(value_len) + buf += value_bytes written += value_len buf.append(0) written += 1 return written 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_bytes = signature.encode() written = self._write_signature(signature_bytes) @@ -84,7 +93,7 @@ def _write_array( buf = self._buf offset = len(buf) written += self._align(4) + 4 - buf.extend(PACKED_UINT32_ZERO) + buf += PACKED_UINT32_ZERO child_type = type_.children[0] token = child_type.token @@ -98,7 +107,7 @@ def _write_array( array_len += self.write_dict_entry([key, value], child_type) elif token == "y": array_len = len(array) - buf.extend(array) + buf += array elif token == "(": for value in array: array_len += self._write_struct(value, child_type) @@ -107,7 +116,7 @@ def _write_array( if not writer: for value in array: array_len += self._align(size) + size - buf.extend(packer(value)) # type: ignore[misc] + buf += packer(value) # type: ignore[misc] else: for value in array: array_len += writer(self, value, child_type) @@ -135,12 +144,28 @@ def write_dict_entry(self, dict_entry: List[Any], type_: SignatureType) -> int: def _write_single(self, type_: SignatureType, body: Any) -> int: t = type_.token - writer, packer, size = self._writers[t] - if not writer: - written = self._align(size) - self._buf.extend(packer(body)) # type: ignore[misc] - return written + size - return writer(self, body, type_) + if t == "y": + self._buf.append(body) + return 1 + elif t == "u": + written = self._align(4) + 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: """Marshalls the body into a byte array""" @@ -154,26 +179,9 @@ def marshall(self) -> bytearray: def _construct_buffer(self) -> None: self._buf.clear() - writers = self._writers body = self.body - buf = self._buf for i, type_ in enumerate(self.signature_tree.types): - t = type_.token - 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_) + self._write_single(type_, body[i]) _writers: Dict[ str,