From 3aaf08b49d8d38bfa580987a5219796629c815f3 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Wed, 4 Jan 2012 14:46:51 -0500 Subject: [PATCH] giobjectinfo: Add g_object_info_find_vfunc_using_interfaces As an analogue to g_object_info_find_method_using_interfaces, add a new API so that we can find a vfunc using the same strategy. --- giobjectinfo.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ giobjectinfo.h | 3 +++ 2 files changed, 63 insertions(+) diff --git a/giobjectinfo.c b/giobjectinfo.c index 4aca8bd45..32a5b0c51 100644 --- a/giobjectinfo.c +++ b/giobjectinfo.c @@ -659,6 +659,66 @@ g_object_info_find_vfunc (GIObjectInfo *info, return _g_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name); } +/** + * g_object_info_find_vfunc_using_interfaces: + * @info: a #GIObjectInfo + * @name: name of method to obtain + * @implementor: (out) (transfer full): The implementor of the interface + * + * Locate a virtual function slot with name @name, searching both the object + * @info and any interfaces it implements. Note that the namespace for + * virtuals is distinct from that of methods; there may or may not be a + * concrete method associated for a virtual. If there is one, it may be + * retrieved using g_vfunc_info_get_invoker(), otherwise %NULL will be + * returned. + * + * Note that this function does *not* search parent classes; you will have + * to chain up if that's desired. + * + * Returns: (transfer full): the #GIFunctionInfo. Free the struct by calling + * g_base_info_unref() when done. + */ +GIVFuncInfo * +g_object_info_find_vfunc_using_interfaces (GIObjectInfo *info, + const gchar *name, + GIObjectInfo **implementor) +{ + GIVFuncInfo *result = NULL; + GIObjectInfo *implementor_result = NULL; + + result = g_object_info_find_vfunc (info, name); + if (result) + implementor_result = g_base_info_ref ((GIBaseInfo*) info); + + if (result == NULL) + { + int n_interfaces; + int i; + + n_interfaces = g_object_info_get_n_interfaces (info); + for (i = 0; i < n_interfaces; ++i) + { + GIInterfaceInfo *iface_info; + + iface_info = g_object_info_get_interface (info, i); + + result = g_interface_info_find_vfunc (iface_info, name); + + if (result != NULL) + { + implementor_result = iface_info; + break; + } + g_base_info_unref ((GIBaseInfo*) iface_info); + } + } + if (implementor) + *implementor = implementor_result; + else if (implementor_result != NULL) + g_base_info_unref ((GIBaseInfo*) implementor_result); + return result; +} + /** * g_object_info_get_n_constants: * @info: a #GIObjectInfo diff --git a/giobjectinfo.h b/giobjectinfo.h index fd35ef8f0..569c08390 100644 --- a/giobjectinfo.h +++ b/giobjectinfo.h @@ -108,6 +108,9 @@ GIVFuncInfo * g_object_info_get_vfunc (GIObjectInfo *info, gint n); GIVFuncInfo * g_object_info_find_vfunc (GIObjectInfo *info, const gchar *name); +GIVFuncInfo * g_object_info_find_vfunc_using_interfaces (GIObjectInfo *info, + const gchar *name, + GIObjectInfo **implementor); gint g_object_info_get_n_constants (GIObjectInfo *info); GIConstantInfo * g_object_info_get_constant (GIObjectInfo *info, gint n);