diff options
author | Federico Mena Quintero <federico@gnome.org> | 2021-11-23 19:27:45 -0600 |
---|---|---|
committer | Federico Mena Quintero <federico@gnome.org> | 2022-07-12 21:46:28 -0500 |
commit | f596bcf46ee00e00f01e6487d5627b589eea7cca (patch) | |
tree | 733df3a789903f1ec3fdba23f50bed4286f65bda /atspi | |
parent | 0688a04dd906633219c62e0295612ed125aeae33 (diff) | |
download | at-spi2-core-f596bcf46ee00e00f01e6487d5627b589eea7cca.tar.gz |
_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.
Diffstat (limited to 'atspi')
-rw-r--r-- | atspi/atspi-misc.c | 98 |
1 files changed, 80 insertions, 18 deletions
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); } |