1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 * GObject introspection: Virtual Function implementation
4 * Copyright (C) 2005 Matthias Clasen
5 * Copyright (C) 2008,2009 Red Hat, Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
27 #include <girepository.h>
28 #include "girepository-private.h"
29 #include "gitypelib-internal.h"
33 * @Short_description: Struct representing a virtual function
36 * GIVfuncInfo represents a virtual function. A property belongs to
37 * either a #GIObjectInfo or a #GIInterfaceInfo.
39 * <refsect1 id="gi-givfuncinfo.struct-hierarchy" role="struct_hierarchy">
40 * <title role="struct_hierarchy.title">Struct hierarchy</title>
42 * <link linkend="gi-GIBaseInfo">GIBaseInfo</link>
43 * +----<link linkend="gi-GICallableInfo">GICallableInfo</link>
44 * +----<link linkend="gi-GIFunctionInfo">GIFunctionInfo</link>
45 * +----<link linkend="gi-GISignalInfo">GISignalInfo</link>
52 _g_base_info_find_vfunc (GIRealInfo *rinfo,
58 Header *header = (Header *)rinfo->typelib->data;
61 for (i = 0; i < n_vfuncs; i++)
63 VFuncBlob *fblob = (VFuncBlob *)&rinfo->typelib->data[offset];
64 const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name];
66 if (strcmp (name, fname) == 0)
67 return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*) rinfo,
68 rinfo->typelib, offset);
70 offset += header->vfunc_blob_size;
77 * g_vfunc_info_get_flags:
78 * @info: a #GIVFuncInfo
80 * Obtain the flags for this virtual function info. See #GIVFuncInfoFlags for
81 * more information about possible flag values.
86 g_vfunc_info_get_flags (GIVFuncInfo *info)
88 GIVFuncInfoFlags flags;
89 GIRealInfo *rinfo = (GIRealInfo *)info;
92 g_return_val_if_fail (info != NULL, 0);
93 g_return_val_if_fail (GI_IS_VFUNC_INFO (info), 0);
95 blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
99 if (blob->must_chain_up)
100 flags = flags | GI_VFUNC_MUST_CHAIN_UP;
102 if (blob->must_be_implemented)
103 flags = flags | GI_VFUNC_MUST_OVERRIDE;
105 if (blob->must_not_be_implemented)
106 flags = flags | GI_VFUNC_MUST_NOT_OVERRIDE;
109 flags = flags | GI_VFUNC_THROWS;
115 * g_vfunc_info_get_offset:
116 * @info: a #GIVFuncInfo
118 * Obtain the offset of the function pointer in the class struct. The value
119 * 0xFFFF indicates that the struct offset is unknown.
121 * Returns: the struct offset or 0xFFFF if it's unknown
124 g_vfunc_info_get_offset (GIVFuncInfo *info)
126 GIRealInfo *rinfo = (GIRealInfo *)info;
129 g_return_val_if_fail (info != NULL, 0);
130 g_return_val_if_fail (GI_IS_VFUNC_INFO (info), 0);
132 blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
134 return blob->struct_offset;
138 * g_vfunc_info_get_signal:
139 * @info: a #GIVFuncInfo
141 * Obtain the signal for the virtual function if one is set.
142 * The signal comes from the object or interface to which
143 * this virtual function belongs.
145 * Returns: (transfer full): the signal or %NULL if none set
148 g_vfunc_info_get_signal (GIVFuncInfo *info)
150 GIRealInfo *rinfo = (GIRealInfo *)info;
153 g_return_val_if_fail (info != NULL, 0);
154 g_return_val_if_fail (GI_IS_VFUNC_INFO (info), 0);
156 blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
158 if (blob->class_closure)
159 return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal);
165 * g_vfunc_info_get_invoker:
166 * @info: a #GIVFuncInfo
168 * If this virtual function has an associated invoker method, this
169 * method will return it. An invoker method is a C entry point.
171 * Not all virtuals will have invokers.
173 * Returns: (transfer full): the #GIVFuncInfo or %NULL. Free it with
174 * g_base_info_unref() when done.
177 g_vfunc_info_get_invoker (GIVFuncInfo *info)
179 GIRealInfo *rinfo = (GIRealInfo *)info;
181 GIBaseInfo *container;
182 GIInfoType parent_type;
184 g_return_val_if_fail (info != NULL, 0);
185 g_return_val_if_fail (GI_IS_VFUNC_INFO (info), 0);
187 blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
189 /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */
190 if (blob->invoker == 1023)
193 container = rinfo->container;
194 parent_type = g_base_info_get_type (container);
195 if (parent_type == GI_INFO_TYPE_OBJECT)
196 return g_object_info_get_method ((GIObjectInfo*)container, blob->invoker);
197 else if (parent_type == GI_INFO_TYPE_INTERFACE)
198 return g_interface_info_get_method ((GIInterfaceInfo*)container, blob->invoker);
200 g_assert_not_reached ();
204 * g_vfunc_info_get_address:
205 * @info: a #GIVFuncInfo
206 * @implementor_gtype: #GType implementing this virtual function
207 * @error: return location for a #GError
209 * This method will look up where inside the type struct of @implementor_gtype
210 * is the implementation for @info.
212 * Returns: address to a function or %NULL if an error happened
215 g_vfunc_info_get_address (GIVFuncInfo *vfunc_info,
216 GType implementor_gtype,
219 GIObjectInfo *object_info;
220 GIStructInfo *struct_info;
221 GIFieldInfo *field_info = NULL;
222 int length, i, offset;
223 gpointer implementor_vtable, func;
225 object_info = (GIObjectInfo *) g_base_info_get_container (vfunc_info);
226 struct_info = g_object_info_get_class_struct (object_info);
228 length = g_struct_info_get_n_fields (struct_info);
229 for (i = 0; i < length; i++)
231 field_info = g_struct_info_get_field (struct_info, i);
233 if (strcmp (g_base_info_get_name ( (GIBaseInfo*) field_info),
234 g_base_info_get_name ( (GIBaseInfo*) vfunc_info)) != 0) {
235 g_base_info_unref (field_info);
243 if (field_info == NULL)
247 G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
248 "Couldn't find struct field for this vfunc");
252 implementor_vtable = g_type_class_ref (implementor_gtype);
253 offset = g_field_info_get_offset (field_info);
254 func = *(gpointer*) G_STRUCT_MEMBER_P (implementor_vtable, offset);
255 g_type_class_unref (implementor_vtable);
261 G_INVOKE_ERROR_SYMBOL_NOT_FOUND,
262 "Class %s doesn't implement %s",
263 g_type_name (implementor_gtype),
264 g_base_info_get_name ( (GIBaseInfo*) vfunc_info));
272 * g_vfunc_info_invoke: (skip)
273 * @info: a #GIVFuncInfo describing the virtual function to invoke
274 * @implementor: #GType of the type that implements this virtual function
275 * @in_args: an array of #GIArgument<!-- -->s, one for each in
276 * parameter of @info. If there are no in parameter, @in_args
278 * @n_in_args: the length of the @in_args array
279 * @out_args: an array of #GIArgument<!-- -->s, one for each out
280 * parameter of @info. If there are no out parameters, @out_args
282 * @n_out_args: the length of the @out_args array
283 * @return_value: return location for the return value of the
284 * function. If the function returns void, @return_value may be
286 * @error: return location for detailed error information, or %NULL
288 * Invokes the function described in @info with the given
289 * arguments. Note that inout parameters must appear in both
292 * Returns: %TRUE if the function has been invoked, %FALSE if an
296 g_vfunc_info_invoke (GIVFuncInfo *info,
298 const GIArgument *in_args,
300 const GIArgument *out_args,
302 GIArgument *return_value,
307 func = g_vfunc_info_get_address (info, implementor, error);
311 return g_callable_info_invoke ((GICallableInfo*) info,