[at-spi2-core: 3/47] _atspi_dbus_set_interfaces: split internals into a demarshaler and a translator




commit f596bcf46ee00e00f01e6487d5627b589eea7cca
Author: Federico Mena Quintero <federico gnome org>
Date:   Tue Nov 23 19:27:45 2021 -0600

    _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(-)
---
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);
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]