[glib] Bug 624473: GDBusSubtreeIntrospectFunc return type
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] Bug 624473: GDBusSubtreeIntrospectFunc return type
- Date: Thu, 15 Jul 2010 21:33:34 +0000 (UTC)
commit e6b5546cf573e6594b33b2ce19ad839c1c694909
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Jul 15 16:26:42 2010 -0400
Bug 624473: GDBusSubtreeIntrospectFunc return type
Return a NULL terminated C array instead of a GPtrArray
Also, document that %NULL is a permitted return value and clarify its
meaning.
Finally, avoid calling the enumeration function during dispatch when the
G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES flag was given.
gio/gdbusconnection.c | 76 ++++++++++++++++++++++++++--------------------
gio/gdbusconnection.h | 27 ++++++++++++----
gio/tests/gdbus-export.c | 25 +++++++--------
3 files changed, 74 insertions(+), 54 deletions(-)
---
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 389dc29..b7dd83a 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -5167,7 +5167,7 @@ handle_subtree_introspect (GDBusConnection *connection,
const gchar *sender;
const gchar *requested_object_path;
const gchar *requested_node;
- GPtrArray *interfaces;
+ GDBusInterfaceInfo **interfaces;
guint n;
gchar **subnode_paths;
@@ -5209,18 +5209,14 @@ handle_subtree_introspect (GDBusConnection *connection,
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 */
@@ -5265,12 +5261,11 @@ handle_subtree_method_invocation (GDBusConnection *connection,
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;
@@ -5298,19 +5293,29 @@ handle_subtree_method_invocation (GDBusConnection *connection,
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
{
@@ -5323,13 +5328,15 @@ handle_subtree_method_invocation (GDBusConnection *connection,
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 */
@@ -5371,11 +5378,10 @@ handle_subtree_method_invocation (GDBusConnection *connection,
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
@@ -5437,8 +5443,12 @@ handle_subtree_method_invocation (GDBusConnection *connection,
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;
}
diff --git a/gio/gdbusconnection.h b/gio/gdbusconnection.h
index 3a1ff46..b94e1ab 100644
--- a/gio/gdbusconnection.h
+++ b/gio/gdbusconnection.h
@@ -325,16 +325,29 @@ typedef gchar** (*GDBusSubtreeEnumerateFunc) (GDBusConnection *connection,
*
* 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:
diff --git a/gio/tests/gdbus-export.c b/gio/tests/gdbus-export.c
index 63c871e..cfefe71 100644
--- a/gio/tests/gdbus-export.c
+++ b/gio/tests/gdbus-export.c
@@ -614,37 +614,38 @@ subtree_enumerate (GDBusConnection *connection,
}
/* 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 *
@@ -691,20 +692,16 @@ dynamic_subtree_enumerate (GDBusConnection *connection,
}
/* 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 *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]