summaryrefslogtreecommitdiff
path: root/atspi
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@gnome.org>2021-11-23 19:27:45 -0600
committerFederico Mena Quintero <federico@gnome.org>2022-07-12 21:46:28 -0500
commitf596bcf46ee00e00f01e6487d5627b589eea7cca (patch)
tree733df3a789903f1ec3fdba23f50bed4286f65bda /atspi
parent0688a04dd906633219c62e0295612ed125aeae33 (diff)
downloadat-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.c98
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);
}