diff --git a/bench/unmarshall_servicedata.py b/bench/unmarshall_servicedata.py new file mode 100644 index 00000000..16eb6d7d --- /dev/null +++ b/bench/unmarshall_servicedata.py @@ -0,0 +1,32 @@ +import io +import timeit + +from dbus_fast._private.unmarshaller import Unmarshaller + +# cythonize -X language_level=3 -a -i src/dbus_fast/_private/unmarshaller.py + + +bluez_properties_changed_message = ( + b"l\4\1\1\334\0\0\0@\236.\0\226\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_58_2D_34_60_DA_1F" + b"\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged" + b"\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0\21\0\0\0org.bluez.Devi" + b"ce1\0\0\0\270\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\301\377\0\0\v\0\0\0ServiceData\0\5a{sv}" + b"\0\0\210\0\0\0\0\0\0\0$\0\0\0000000fdcd-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\24\0" + b"\0\0\10\22\37\332`4-X\2\1U\17\1\315\t\4\5\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f" + b"9b34fb\0\2ay\0\0\0\0\f\0\0\0000X\203\n\2\37\332`4-X\10\0\0\0\0" +) + + +stream = io.BytesIO(bluez_properties_changed_message) +unmarshaller = Unmarshaller(stream) + + +def unmarshall_properties_changed_message(): + stream.seek(0) + unmarshaller.reset() + unmarshaller.unmarshall() + + +count = 3000000 +time = timeit.Timer(unmarshall_properties_changed_message).timeit(count) +print(f"Unmarshalling {count} bluetooth PropertiesChanged messages took {time} seconds") diff --git a/src/dbus_fast/_private/unmarshaller.pxd b/src/dbus_fast/_private/unmarshaller.pxd index 93dc5fe7..e5572c99 100644 --- a/src/dbus_fast/_private/unmarshaller.pxd +++ b/src/dbus_fast/_private/unmarshaller.pxd @@ -113,7 +113,7 @@ cdef class Unmarshaller: cpdef read_boolean(self, object type_) - cdef bint _read_boolean(self) + cdef _read_boolean(self) cpdef read_uint32_unpack(self, object type_) diff --git a/tests/test_marshaller.py b/tests/test_marshaller.py index 58fa3111..1cf106c2 100644 --- a/tests/test_marshaller.py +++ b/tests/test_marshaller.py @@ -364,6 +364,75 @@ def test_unmarshall_bluez_interfaces_removed_message(): ] +def test_unmarshall_bluez_properties_changed_with_service_data(): + bluez_properties_changed_message = ( + b"l\4\1\1\334\0\0\0@\236.\0\226\0\0\0\1\1o\0%\0\0\0/org/bluez/hci0/dev_58_2D_34_60_DA_1F" + b"\0\0\0\2\1s\0\37\0\0\0org.freedesktop.DBus.Properties\0\3\1s\0\21\0\0\0PropertiesChanged" + b"\0\0\0\0\0\0\0\10\1g\0\10sa{sv}as\0\0\0\7\1s\0\5\0\0\0:1.12\0\0\0\21\0\0\0org.bluez.Devi" + b"ce1\0\0\0\270\0\0\0\0\0\0\0\4\0\0\0RSSI\0\1n\0\301\377\0\0\v\0\0\0ServiceData\0\5a{sv}" + b"\0\0\210\0\0\0\0\0\0\0$\0\0\0000000fdcd-0000-1000-8000-00805f9b34fb\0\2ay\0\0\0\0\24\0" + b"\0\0\10\22\37\332`4-X\2\1U\17\1\315\t\4\5\0\0\0$\0\0\0000000fe95-0000-1000-8000-00805f" + b"9b34fb\0\2ay\0\0\0\0\f\0\0\0000X\203\n\2\37\332`4-X\10\0\0\0\0" + ) + + stream = io.BytesIO(bluez_properties_changed_message) + unmarshaller = Unmarshaller(stream) + assert unmarshaller.unmarshall() + message = unmarshaller.message + assert message is not None + assert message is not None + assert message.body == [ + "org.bluez.Device1", + { + "RSSI": Variant("n", -63), + "ServiceData": Variant( + "a{sv}", + { + "0000fdcd-0000-1000-8000-00805f9b34fb": Variant( + "ay", + bytearray( + b"\x08\x12\x1f\xda`4-X\x02\x01U\x0f\x01\xcd\t\x04\x05\x00\x00\x00" + ), + ), + "0000fe95-0000-1000-8000-00805f9b34fb": Variant( + "ay", bytearray(b"0X\x83\n\x02\x1f\xda`4-X\x08") + ), + }, + ), + }, + [], + ] + assert message.sender == ":1.12" + assert message.path == "/org/bluez/hci0/dev_58_2D_34_60_DA_1F" + assert message.interface == "org.freedesktop.DBus.Properties" + assert message.member == "PropertiesChanged" + assert message.signature == "sa{sv}as" + assert message.message_type == MessageType.SIGNAL + assert message.flags == MessageFlag.NO_REPLY_EXPECTED + assert message.serial == 3055168 + assert message.destination is None + unpacked = unpack_variants(message.body) + assert unpacked == [ + "org.bluez.Device1", + { + "RSSI": -63, + "ServiceData": { + "0000fdcd-0000-1000-8000-00805f9b34fb": bytearray( + b"\x08\x12\x1f\xda" + b"`4-X" + b"\x02\x01U\x0f" + b"\x01\xcd\t\x04" + b"\x05\x00\x00\x00" + ), + "0000fe95-0000-1000-8000-00805f9b34fb": bytearray( + b"0X\x83\n" b"\x02\x1f\xda`" b"4-X\x08" + ), + }, + }, + [], + ] + + def test_ay_buffer(): body = [bytes(10000)] msg = Message(path="/test", member="test", signature="ay", body=body)