const gchar *sender;
const gchar *requested_object_path;
const gchar *requested_node;
- GPtrArray *interfaces;
+ GDBusInterfaceInfo **interfaces;
guint n;
gchar **subnode_paths;
es->user_data);
if (interfaces != NULL)
{
- if (interfaces->len > 0)
- {
- /* we're in business */
- introspect_append_standard_interfaces (s);
+ introspect_append_standard_interfaces (s);
- for (n = 0; n < interfaces->len; n++)
- {
- const GDBusInterfaceInfo *interface_info = interfaces->pdata[n];
- g_dbus_interface_info_generate_xml (interface_info, 2, s);
- }
+ for (n = 0; interfaces[n] != NULL; n++)
+ {
+ g_dbus_interface_info_generate_xml (interfaces[n], 2, s);
+ g_dbus_interface_info_unref (interfaces[n]);
}
- g_ptr_array_unref (interfaces);
+ g_free (interfaces);
}
/* then include <node> entries from the Subtree for the root */
const gchar *requested_object_path;
const gchar *requested_node;
gboolean is_root;
- gchar **children;
const GDBusInterfaceInfo *interface_info;
const GDBusInterfaceVTable *interface_vtable;
gpointer interface_user_data;
guint n;
- GPtrArray *interfaces;
+ GDBusInterfaceInfo **interfaces;
gboolean is_property_get;
gboolean is_property_set;
gboolean is_property_get_all;
is_property_get_all = TRUE;
}
- children = es->vtable->enumerate (es->connection,
- sender,
- es->object_path,
- es->user_data);
-
if (!is_root)
{
requested_node = strrchr (requested_object_path, '/') + 1;
- /* If not dynamic, skip if requested node is not part of children */
- if (!(es->flags & G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES) &&
- !_g_strv_has_string ((const gchar * const *) children, requested_node))
- goto out;
+ if (~es->flags & G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES)
+ {
+ /* We don't want to dispatch to unenumerated
+ * nodes, so ensure that the child exists.
+ */
+ gchar **children;
+ gboolean exists;
+
+ children = es->vtable->enumerate (es->connection,
+ sender,
+ es->object_path,
+ es->user_data);
+
+ exists = _g_strv_has_string ((const gchar * const *) children, requested_node);
+ g_strfreev (children);
+
+ if (!exists)
+ goto out;
+ }
}
else
{
requested_object_path,
requested_node,
es->user_data);
- g_assert (interfaces != NULL);
+
+ if (interfaces == NULL)
+ goto out;
+
interface_info = NULL;
- for (n = 0; n < interfaces->len; n++)
+ for (n = 0; interfaces[n] != NULL; n++)
{
- const GDBusInterfaceInfo *id_n = (const GDBusInterfaceInfo *) interfaces->pdata[n];
- if (g_strcmp0 (id_n->name, interface_name) == 0)
- interface_info = id_n;
+ if (g_strcmp0 (interfaces[n]->name, interface_name) == 0)
+ interface_info = interfaces[n];
}
/* dispatch the call if the user wants to handle it */
g_assert_not_reached ();
/* see if the object supports this interface at all */
- for (n = 0; n < interfaces->len; n++)
+ for (n = 0; interfaces[n] != NULL; n++)
{
- const GDBusInterfaceInfo *id_n = (const GDBusInterfaceInfo *) interfaces->pdata[n];
- if (g_strcmp0 (id_n->name, interface_name) == 0)
- interface_info = id_n;
+ if (g_strcmp0 (interfaces[n]->name, interface_name) == 0)
+ interface_info = interfaces[n];
}
/* Fail with org.freedesktop.DBus.Error.InvalidArgs if the user-code
out:
if (interfaces != NULL)
- g_ptr_array_unref (interfaces);
- g_strfreev (children);
+ {
+ for (n = 0; interfaces[n] != NULL; n++)
+ g_dbus_interface_info_unref (interfaces[n]);
+ g_free (interfaces);
+ }
+
return handled;
}
*
* The type of the @introspect function in #GDBusSubtreeVTable.
*
- * Returns: A newly-allocated #GPtrArray with pointers to #GDBusInterfaceInfo describing
- * the interfaces implemented by @node.
+ * This function should return %NULL to indicate that there is no object
+ * at this node.
+ *
+ * If this function returns non-%NULL, the return value is expected to
+ * be a %NULL-terminated array of pointers to #GDBusInterfaceInfo
+ * structures describing the interfaces implemented by @node. This
+ * array will have g_dbus_interface_info_unref() called on each item
+ * before being freed with g_free().
+ *
+ * The difference between returning %NULL and an array containing zero
+ * items is that the standard DBus interfaces will returned to the
+ * remote introspector in the empty array case, but not in the %NULL
+ * case.
+ *
+ * Returns: A %NULL-terminated array of pointers to #GDBusInterfaceInfo, or %NULL.
*
* Since: 2.26
*/
-typedef GPtrArray *(*GDBusSubtreeIntrospectFunc) (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *node,
- gpointer user_data);
+typedef GDBusInterfaceInfo ** (*GDBusSubtreeIntrospectFunc) (GDBusConnection *connection,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *node,
+ gpointer user_data);
/**
* GDBusSubtreeDispatchFunc:
}
/* Only allows certain objects, and aborts on unknowns */
-static GPtrArray *
+static GDBusInterfaceInfo **
subtree_introspect (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *node,
gpointer user_data)
{
- GPtrArray *interfaces;
+ const GDBusInterfaceInfo *interfaces[2] = {
+ NULL /* filled in below */, NULL
+ };
/* VPs implement the Foo interface, EVPs implement the Bar interface. The root
* does not implement any interfaces
*/
- interfaces = g_ptr_array_new ();
if (g_str_has_prefix (node, "vp"))
{
- g_ptr_array_add (interfaces, (gpointer) &foo_interface_info);
+ interfaces[0] = &foo_interface_info;
}
else if (g_str_has_prefix (node, "evp"))
{
- g_ptr_array_add (interfaces, (gpointer) &bar_interface_info);
+ interfaces[0] = &bar_interface_info;
}
else if (g_strcmp0 (node, "/") == 0)
{
- /* do nothing */
+ return NULL;
}
else
{
g_assert_not_reached ();
}
- return interfaces;
+ return g_memdup (interfaces, 2 * sizeof (void *));
}
static const GDBusInterfaceVTable *
}
/* Allow all objects to be introspected */
-static GPtrArray *
+static GDBusInterfaceInfo **
dynamic_subtree_introspect (GDBusConnection *connection,
const gchar *sender,
const gchar *object_path,
const gchar *node,
gpointer user_data)
{
- GPtrArray *interfaces;
+ const GDBusInterfaceInfo *interfaces[2] = { &dyna_interface_info, NULL };
- /* All nodes (including the root node) implements the Dyna interface */
- interfaces = g_ptr_array_new ();
- g_ptr_array_add (interfaces, (gpointer) &dyna_interface_info);
-
- return interfaces;
+ return g_memdup (interfaces, 2 * sizeof (void *));
}
static const GDBusInterfaceVTable *