diff --git a/src/dbus_fast/_private/unmarshaller.py b/src/dbus_fast/_private/unmarshaller.py index d5181f5f..e6199b0a 100644 --- a/src/dbus_fast/_private/unmarshaller.py +++ b/src/dbus_fast/_private/unmarshaller.py @@ -750,24 +750,26 @@ def _read_body(self) -> None: flags = MESSAGE_FLAG_MAP.get(self._flag) if flags is None: flags = MESSAGE_FLAG_INTENUM(self._flag) - self._message = Message( - message_type=MESSAGE_TYPE_MAP[self._message_type], - flags=flags, - unix_fds=self._unix_fds, - signature=tree, - body=body, - serial=self._serial, + message = Message.__new__(Message) + message._fast_init( + header_fields[HEADER_DESTINATION_IDX], + header_fields[HEADER_PATH_IDX], + header_fields[HEADER_INTERFACE_IDX], + header_fields[HEADER_MEMBER_IDX], + MESSAGE_TYPE_MAP[self._message_type], + flags, + header_fields[HEADER_ERROR_NAME_IDX], + header_fields[HEADER_REPLY_SERIAL_IDX] or 0, + header_fields[HEADER_SENDER_IDX], + self._unix_fds, + tree, + body, + self._serial, # The D-Bus implementation already validates the message, # so we don't need to do it again. - validate=False, - destination=header_fields[HEADER_DESTINATION_IDX], - path=header_fields[HEADER_PATH_IDX], - interface=header_fields[HEADER_INTERFACE_IDX], - member=header_fields[HEADER_MEMBER_IDX], - reply_serial=header_fields[HEADER_REPLY_SERIAL_IDX], - error_name=header_fields[HEADER_ERROR_NAME_IDX], - sender=header_fields[HEADER_SENDER_IDX], + False, ) + self._message = message self._read_complete = True def unmarshall(self) -> Optional[Message]: diff --git a/src/dbus_fast/message.pxd b/src/dbus_fast/message.pxd index 891c8ceb..e7a9e2f7 100644 --- a/src/dbus_fast/message.pxd +++ b/src/dbus_fast/message.pxd @@ -41,16 +41,34 @@ cdef class Message: cdef public object message_type cdef public object flags cdef public object error_name - cdef public object reply_serial + cdef public unsigned int reply_serial cdef public object sender - cdef public cython.list unix_fds + cdef public list unix_fds cdef public object signature cdef public object signature_tree cdef public object body - cdef public object serial + cdef public unsigned int serial @cython.locals( body_buffer=cython.bytearray, header_buffer=cython.bytearray ) cpdef _marshall(self, object negotiate_unix_fd) + + cdef _fast_init( + self, + object destination, + object path, + object interface, + object member, + object message_type, + object flags, + object error_name, + unsigned int reply_serial, + object sender, + list unix_fds, + object signature_tree, + object body, + unsigned int serial, + bint validate + ) diff --git a/src/dbus_fast/message.py b/src/dbus_fast/message.py index bbc5276c..fb5cd042 100644 --- a/src/dbus_fast/message.py +++ b/src/dbus_fast/message.py @@ -34,6 +34,14 @@ MESSAGE_TYPE_METHOD_CALL = MessageType.METHOD_CALL +_int = int +_str = str +_bool = bool +_MessageType = MessageType +_MessageFlag = MessageFlag +_list = list + + class Message: """A class for sending and receiving messages through the :class:`MessageBus ` with the @@ -114,27 +122,57 @@ def __init__( body: list[Any] = [], serial: Optional[int] = None, validate: bool = True, + ) -> None: + self._fast_init( + destination, + path, + interface, + member, + message_type, + flags if type(flags) is MESSAGE_FLAG else MESSAGE_FLAG(flags), + str(error_name.value) if type(error_name) is ErrorType else error_name, + reply_serial or 0, + sender, + unix_fds, + signature + if type(signature) is SignatureTree + else get_signature_tree(signature or ""), + body, + serial or 0, + validate, + ) + + def _fast_init( + self, + destination: Optional[_str], + path: Optional[_str], + interface: Optional[_str], + member: Optional[_str], + message_type: _MessageType, + flags: _MessageFlag, + error_name: Optional[_str], + reply_serial: _int, + sender: _str, + unix_fds: _list[int], + signature_tree: SignatureTree, + body: _list[Any], + serial: _int, + validate: _bool, ) -> None: self.destination = destination self.path = path self.interface = interface self.member = member self.message_type = message_type - self.flags = flags if type(flags) is MESSAGE_FLAG else MESSAGE_FLAG(flags) - self.error_name = ( - str(error_name.value) if type(error_name) is ErrorType else error_name - ) - self.reply_serial = reply_serial or 0 + self.flags = flags + self.error_name = error_name + self.reply_serial = reply_serial self.sender = sender self.unix_fds = unix_fds - if type(signature) is SignatureTree: - self.signature = signature.signature - self.signature_tree = signature - else: - self.signature = signature or "" # type: ignore[assignment] - self.signature_tree = get_signature_tree(signature or "") + self.signature = signature_tree.signature + self.signature_tree = signature_tree self.body = body - self.serial = serial or 0 + self.serial = serial if not validate: return