From f596bcf46ee00e00f01e6487d5627b589eea7cca Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Tue, 23 Nov 2021 19:27:45 -0600 Subject: _atspi_dbus_set_interfaces: split internals into a demarshaler and a translator First we demarshal the DBusMessageIter into an InterfaceNames struct. Then we convert the InterfaceNames to a bitmask suitable for the field AtspiAccessible.interfaces. This will make it easier to replace libdbus with gdbus. --- atspi/atspi-misc.c | 98 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 80 insertions(+), 18 deletions(-) (limited to 'atspi') diff --git a/atspi/atspi-misc.c b/atspi/atspi-misc.c index 710ac34c..4c3451cb 100644 --- a/atspi/atspi-misc.c +++ b/atspi/atspi-misc.c @@ -1379,36 +1379,98 @@ _atspi_dbus_attribute_array_from_iter (DBusMessageIter *iter) return array; } -void -_atspi_dbus_set_interfaces (AtspiAccessible *accessible, DBusMessageIter *iter) +typedef enum { + DEMARSHAL_STATUS_SUCCESS, + DEMARSHAL_STATUS_INVALID_SIGNATURE, + DEMARSHAL_STATUS_INVALID_VALUE, +} DemarshalStatus; + +typedef struct { + /* array of (char *) */ + GPtrArray *names; +} InterfaceNames; + +static DemarshalStatus +interface_names_demarshal (DBusMessageIter *iter, InterfaceNames **out_interfaces) { - DBusMessageIter iter_array; - char *iter_sig = dbus_message_iter_get_signature (iter); + char *sig = dbus_message_iter_get_signature (iter); + gboolean matches = strcmp (sig, "as") == 0; + dbus_free (sig); - accessible->interfaces = 0; - if (strcmp (iter_sig, "as") != 0) + *out_interfaces = NULL; + + GPtrArray *names = g_ptr_array_new_with_free_func (g_free); + + if (!matches) { - g_warning ("_atspi_dbus_set_interfaces: Passed iterator with invalid signature %s", iter_sig); - dbus_free (iter_sig); - return; + return DEMARSHAL_STATUS_INVALID_SIGNATURE; } - dbus_free (iter_sig); + + DBusMessageIter iter_array; dbus_message_iter_recurse (iter, &iter_array); while (dbus_message_iter_get_arg_type (&iter_array) != DBUS_TYPE_INVALID) { const char *iface; - gint n; dbus_message_iter_get_basic (&iter_array, &iface); - if (!strcmp (iface, "org.freedesktop.DBus.Introspectable")) continue; - n = _atspi_get_iface_num (iface); - if (n == -1) + g_ptr_array_add (names, g_strdup (iface)); + dbus_message_iter_next (&iter_array); + } + + InterfaceNames *ifaces = g_new0 (InterfaceNames, 1); + ifaces->names = names; + *out_interfaces = ifaces; + return DEMARSHAL_STATUS_SUCCESS; +} + +/* Converts an array of interface names to a value suitable for AtspiAccessible.interfaces */ +static gint +interface_names_to_bitmask (const InterfaceNames *ifaces) +{ + gint val = 0; + guint i; + + g_assert (ifaces->names != NULL); + + for (i = 0; i < ifaces->names->len; i++) { - g_warning ("AT-SPI: Unknown interface %s", iface); + const char *name = g_ptr_array_index (ifaces->names, i); + gint iface_num = _atspi_get_iface_num (name); + if (iface_num == -1) + { + g_warning ("AT-SPI: Unknown interface %s", name); + } + else + { + val |= (1 << iface_num); + } } - else - accessible->interfaces |= (1 << n); - dbus_message_iter_next (&iter_array); + + return val; +} + +static void +interface_names_free (InterfaceNames *ifaces) +{ + g_ptr_array_free (ifaces->names, TRUE); + g_free (ifaces); +} + +void +_atspi_dbus_set_interfaces (AtspiAccessible *accessible, DBusMessageIter *iter) +{ + InterfaceNames *ifaces; + + accessible->interfaces = 0; + + if (interface_names_demarshal (iter, &ifaces) != DEMARSHAL_STATUS_SUCCESS) + { + g_warning ("Passed iterator with invalid signature"); + return; } + + accessible->interfaces = interface_names_to_bitmask (ifaces); + interface_names_free (ifaces); + _atspi_accessible_add_cache (accessible, ATSPI_CACHE_INTERFACES); } -- cgit v1.2.1