mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
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.
This commit is contained in:
parent
48b1fe948c
commit
e6b5546cf5
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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 *
|
||||
|
Loading…
Reference in New Issue
Block a user