mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-06-13 16:13:47 +02: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 *sender;
|
||||||
const gchar *requested_object_path;
|
const gchar *requested_object_path;
|
||||||
const gchar *requested_node;
|
const gchar *requested_node;
|
||||||
GPtrArray *interfaces;
|
GDBusInterfaceInfo **interfaces;
|
||||||
guint n;
|
guint n;
|
||||||
gchar **subnode_paths;
|
gchar **subnode_paths;
|
||||||
|
|
||||||
@ -5209,18 +5209,14 @@ handle_subtree_introspect (GDBusConnection *connection,
|
|||||||
es->user_data);
|
es->user_data);
|
||||||
if (interfaces != NULL)
|
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++)
|
for (n = 0; interfaces[n] != NULL; n++)
|
||||||
{
|
{
|
||||||
const GDBusInterfaceInfo *interface_info = interfaces->pdata[n];
|
g_dbus_interface_info_generate_xml (interfaces[n], 2, s);
|
||||||
g_dbus_interface_info_generate_xml (interface_info, 2, s);
|
g_dbus_interface_info_unref (interfaces[n]);
|
||||||
}
|
}
|
||||||
}
|
g_free (interfaces);
|
||||||
g_ptr_array_unref (interfaces);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* then include <node> entries from the Subtree for the root */
|
/* 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_object_path;
|
||||||
const gchar *requested_node;
|
const gchar *requested_node;
|
||||||
gboolean is_root;
|
gboolean is_root;
|
||||||
gchar **children;
|
|
||||||
const GDBusInterfaceInfo *interface_info;
|
const GDBusInterfaceInfo *interface_info;
|
||||||
const GDBusInterfaceVTable *interface_vtable;
|
const GDBusInterfaceVTable *interface_vtable;
|
||||||
gpointer interface_user_data;
|
gpointer interface_user_data;
|
||||||
guint n;
|
guint n;
|
||||||
GPtrArray *interfaces;
|
GDBusInterfaceInfo **interfaces;
|
||||||
gboolean is_property_get;
|
gboolean is_property_get;
|
||||||
gboolean is_property_set;
|
gboolean is_property_set;
|
||||||
gboolean is_property_get_all;
|
gboolean is_property_get_all;
|
||||||
@ -5298,20 +5293,30 @@ handle_subtree_method_invocation (GDBusConnection *connection,
|
|||||||
is_property_get_all = TRUE;
|
is_property_get_all = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_root)
|
||||||
|
{
|
||||||
|
requested_node = strrchr (requested_object_path, '/') + 1;
|
||||||
|
|
||||||
|
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,
|
children = es->vtable->enumerate (es->connection,
|
||||||
sender,
|
sender,
|
||||||
es->object_path,
|
es->object_path,
|
||||||
es->user_data);
|
es->user_data);
|
||||||
|
|
||||||
if (!is_root)
|
exists = _g_strv_has_string ((const gchar * const *) children, requested_node);
|
||||||
{
|
g_strfreev (children);
|
||||||
requested_node = strrchr (requested_object_path, '/') + 1;
|
|
||||||
|
|
||||||
/* If not dynamic, skip if requested node is not part of children */
|
if (!exists)
|
||||||
if (!(es->flags & G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES) &&
|
|
||||||
!_g_strv_has_string ((const gchar * const *) children, requested_node))
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
requested_node = "/";
|
requested_node = "/";
|
||||||
@ -5323,13 +5328,15 @@ handle_subtree_method_invocation (GDBusConnection *connection,
|
|||||||
requested_object_path,
|
requested_object_path,
|
||||||
requested_node,
|
requested_node,
|
||||||
es->user_data);
|
es->user_data);
|
||||||
g_assert (interfaces != NULL);
|
|
||||||
|
if (interfaces == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
interface_info = NULL;
|
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 (interfaces[n]->name, interface_name) == 0)
|
||||||
if (g_strcmp0 (id_n->name, interface_name) == 0)
|
interface_info = interfaces[n];
|
||||||
interface_info = id_n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dispatch the call if the user wants to handle it */
|
/* dispatch the call if the user wants to handle it */
|
||||||
@ -5371,11 +5378,10 @@ handle_subtree_method_invocation (GDBusConnection *connection,
|
|||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
|
|
||||||
/* see if the object supports this interface at all */
|
/* 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 (interfaces[n]->name, interface_name) == 0)
|
||||||
if (g_strcmp0 (id_n->name, interface_name) == 0)
|
interface_info = interfaces[n];
|
||||||
interface_info = id_n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fail with org.freedesktop.DBus.Error.InvalidArgs if the user-code
|
/* Fail with org.freedesktop.DBus.Error.InvalidArgs if the user-code
|
||||||
@ -5437,8 +5443,12 @@ handle_subtree_method_invocation (GDBusConnection *connection,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
if (interfaces != NULL)
|
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;
|
return handled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,12 +325,25 @@ typedef gchar** (*GDBusSubtreeEnumerateFunc) (GDBusConnection *connection,
|
|||||||
*
|
*
|
||||||
* The type of the @introspect function in #GDBusSubtreeVTable.
|
* The type of the @introspect function in #GDBusSubtreeVTable.
|
||||||
*
|
*
|
||||||
* Returns: A newly-allocated #GPtrArray with pointers to #GDBusInterfaceInfo describing
|
* This function should return %NULL to indicate that there is no object
|
||||||
* the interfaces implemented by @node.
|
* 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
|
* Since: 2.26
|
||||||
*/
|
*/
|
||||||
typedef GPtrArray *(*GDBusSubtreeIntrospectFunc) (GDBusConnection *connection,
|
typedef GDBusInterfaceInfo ** (*GDBusSubtreeIntrospectFunc) (GDBusConnection *connection,
|
||||||
const gchar *sender,
|
const gchar *sender,
|
||||||
const gchar *object_path,
|
const gchar *object_path,
|
||||||
const gchar *node,
|
const gchar *node,
|
||||||
|
@ -614,37 +614,38 @@ subtree_enumerate (GDBusConnection *connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Only allows certain objects, and aborts on unknowns */
|
/* Only allows certain objects, and aborts on unknowns */
|
||||||
static GPtrArray *
|
static GDBusInterfaceInfo **
|
||||||
subtree_introspect (GDBusConnection *connection,
|
subtree_introspect (GDBusConnection *connection,
|
||||||
const gchar *sender,
|
const gchar *sender,
|
||||||
const gchar *object_path,
|
const gchar *object_path,
|
||||||
const gchar *node,
|
const gchar *node,
|
||||||
gpointer user_data)
|
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
|
/* VPs implement the Foo interface, EVPs implement the Bar interface. The root
|
||||||
* does not implement any interfaces
|
* does not implement any interfaces
|
||||||
*/
|
*/
|
||||||
interfaces = g_ptr_array_new ();
|
|
||||||
if (g_str_has_prefix (node, "vp"))
|
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"))
|
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)
|
else if (g_strcmp0 (node, "/") == 0)
|
||||||
{
|
{
|
||||||
/* do nothing */
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return interfaces;
|
return g_memdup (interfaces, 2 * sizeof (void *));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GDBusInterfaceVTable *
|
static const GDBusInterfaceVTable *
|
||||||
@ -691,20 +692,16 @@ dynamic_subtree_enumerate (GDBusConnection *connection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Allow all objects to be introspected */
|
/* Allow all objects to be introspected */
|
||||||
static GPtrArray *
|
static GDBusInterfaceInfo **
|
||||||
dynamic_subtree_introspect (GDBusConnection *connection,
|
dynamic_subtree_introspect (GDBusConnection *connection,
|
||||||
const gchar *sender,
|
const gchar *sender,
|
||||||
const gchar *object_path,
|
const gchar *object_path,
|
||||||
const gchar *node,
|
const gchar *node,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GPtrArray *interfaces;
|
const GDBusInterfaceInfo *interfaces[2] = { &dyna_interface_info, NULL };
|
||||||
|
|
||||||
/* All nodes (including the root node) implements the Dyna interface */
|
return g_memdup (interfaces, 2 * sizeof (void *));
|
||||||
interfaces = g_ptr_array_new ();
|
|
||||||
g_ptr_array_add (interfaces, (gpointer) &dyna_interface_info);
|
|
||||||
|
|
||||||
return interfaces;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GDBusInterfaceVTable *
|
static const GDBusInterfaceVTable *
|
||||||
|
Loading…
x
Reference in New Issue
Block a user