1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2  * GObject introspection: Argument implementation
3  *
4  * Copyright (C) 2005 Matthias Clasen
5  * Copyright (C) 2008,2009 Red Hat, Inc.
6  *
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.
11  *
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.
16  *
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.
21  */
22 
23 #include "config.h"
24 
25 #include <glib.h>
26 
27 #include "gitypelib-internal.h"
28 #include "girepository-private.h"
29 
30 
31 /* GIArgInfo functions */
32 
33 /**
34  * SECTION:giarginfo
35  * @title: GIArgInfo
36  * @short_description: Struct representing an argument
37  *
38  * GIArgInfo represents an argument. An argument is always
39  * part of a #GICallableInfo.
40  *
41  * <refsect1 id="gi-giarginfo.struct-hierarchy" role="struct_hierarchy">
42  * <title role="struct_hierarchy.title">Struct hierarchy</title>
43  * <synopsis>
44  *   <link linkend="GIBaseInfo">GIBaseInfo</link>
45  *    +----GIArgInfo
46  * </synopsis>
47  * </refsect1>
48  */
49 
50 /**
51  * g_arg_info_get_direction:
52  * @info: a #GIArgInfo
53  *
54  * Obtain the direction of the argument. Check #GIDirection for possible
55  * direction values.
56  *
57  * Returns: the direction
58  */
59 GIDirection
g_arg_info_get_direction(GIArgInfo * info)60 g_arg_info_get_direction (GIArgInfo *info)
61 {
62   GIRealInfo *rinfo = (GIRealInfo *)info;
63   ArgBlob *blob;
64 
65   g_return_val_if_fail (info != NULL, -1);
66   g_return_val_if_fail (GI_IS_ARG_INFO (info), -1);
67 
68   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
69 
70   if (blob->in && blob->out)
71     return GI_DIRECTION_INOUT;
72   else if (blob->out)
73     return GI_DIRECTION_OUT;
74   else
75     return GI_DIRECTION_IN;
76 }
77 
78 /**
79  * g_arg_info_is_return_value:
80  * @info: a #GIArgInfo
81  *
82  * Obtain if the argument is a return value. It can either be a
83  * parameter or a return value.
84  *
85  * Returns: %TRUE if it is a return value
86  */
87 gboolean
g_arg_info_is_return_value(GIArgInfo * info)88 g_arg_info_is_return_value (GIArgInfo *info)
89 {
90   GIRealInfo *rinfo = (GIRealInfo *)info;
91   ArgBlob *blob;
92 
93   g_return_val_if_fail (info != NULL, FALSE);
94   g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
95 
96   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
97 
98   return blob->return_value;
99 }
100 
101 /**
102  * g_arg_info_is_caller_allocates:
103  * @info: a #GIArgInfo
104  *
105  * Obtain if the argument is a pointer to a struct or object that will
106  * receive an output of a function.  The default assumption for
107  * %GI_DIRECTION_OUT arguments which have allocation is that the
108  * callee allocates; if this is %TRUE, then the caller must allocate.
109  *
110  * Returns: %TRUE if caller is required to have allocated the argument
111  */
112 gboolean
g_arg_info_is_caller_allocates(GIArgInfo * info)113 g_arg_info_is_caller_allocates (GIArgInfo *info)
114 {
115   GIRealInfo *rinfo = (GIRealInfo *)info;
116   ArgBlob *blob;
117 
118   g_return_val_if_fail (info != NULL, FALSE);
119   g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
120 
121   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
122 
123   return blob->caller_allocates;
124 }
125 
126 /**
127  * g_arg_info_is_optional:
128  * @info: a #GIArgInfo
129  *
130  * Obtain if the argument is optional.  For 'out' arguments this means
131  * that you can pass %NULL in order to ignore the result.
132  *
133  * Returns: %TRUE if it is an optional argument
134  */
135 gboolean
g_arg_info_is_optional(GIArgInfo * info)136 g_arg_info_is_optional (GIArgInfo *info)
137 {
138   GIRealInfo *rinfo = (GIRealInfo *)info;
139   ArgBlob *blob;
140 
141   g_return_val_if_fail (info != NULL, FALSE);
142   g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
143 
144   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
145 
146   return blob->optional;
147 }
148 
149 /**
150  * g_arg_info_may_be_null:
151  * @info: a #GIArgInfo
152  *
153  * Obtain if the type of the argument includes the possibility of %NULL.
154  * For 'in' values this means that %NULL is a valid value.  For 'out'
155  * values, this means that %NULL may be returned.
156  *
157  * See also g_arg_info_is_optional().
158  *
159  * Returns: %TRUE if the value may be %NULL
160  */
161 gboolean
g_arg_info_may_be_null(GIArgInfo * info)162 g_arg_info_may_be_null (GIArgInfo *info)
163 {
164   GIRealInfo *rinfo = (GIRealInfo *)info;
165   ArgBlob *blob;
166 
167   g_return_val_if_fail (info != NULL, FALSE);
168   g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
169 
170   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
171 
172   return blob->nullable;
173 }
174 
175 /**
176  * g_arg_info_is_skip:
177  * @info: a #GIArgInfo
178  *
179  * Obtain if an argument is only useful in C.
180  *
181  * Returns: %TRUE if argument is only useful in C.
182  * Since: 1.30
183  */
184 gboolean
g_arg_info_is_skip(GIArgInfo * info)185 g_arg_info_is_skip (GIArgInfo *info)
186 {
187   GIRealInfo *rinfo = (GIRealInfo *)info;
188   ArgBlob *blob;
189 
190   g_return_val_if_fail (info != NULL, FALSE);
191   g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
192 
193   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
194 
195   return blob->skip;
196 }
197 
198 /**
199  * g_arg_info_get_ownership_transfer:
200  * @info: a #GIArgInfo
201  *
202  * Obtain the ownership transfer for this argument.
203  * #GITransfer contains a list of possible values.
204  *
205  * Returns: the transfer
206  */
207 GITransfer
g_arg_info_get_ownership_transfer(GIArgInfo * info)208 g_arg_info_get_ownership_transfer (GIArgInfo *info)
209 {
210   GIRealInfo *rinfo = (GIRealInfo *)info;
211   ArgBlob *blob;
212 
213   g_return_val_if_fail (info != NULL, -1);
214   g_return_val_if_fail (GI_IS_ARG_INFO (info), -1);
215 
216   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
217 
218   if (blob->transfer_ownership)
219     return GI_TRANSFER_EVERYTHING;
220   else if (blob->transfer_container_ownership)
221     return GI_TRANSFER_CONTAINER;
222   else
223     return GI_TRANSFER_NOTHING;
224 }
225 
226 /**
227  * g_arg_info_get_scope:
228  * @info: a #GIArgInfo
229  *
230  * Obtain the scope type for this argument. The scope type explains
231  * how a callback is going to be invoked, most importantly when
232  * the resources required to invoke it can be freed.
233  * #GIScopeType contains a list of possible values.
234  *
235  * Returns: the scope type
236  */
237 GIScopeType
g_arg_info_get_scope(GIArgInfo * info)238 g_arg_info_get_scope (GIArgInfo *info)
239 {
240   GIRealInfo *rinfo = (GIRealInfo *)info;
241   ArgBlob *blob;
242 
243   g_return_val_if_fail (info != NULL, -1);
244   g_return_val_if_fail (GI_IS_ARG_INFO (info), -1);
245 
246   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
247 
248   return blob->scope;
249 }
250 
251 /**
252  * g_arg_info_get_closure:
253  * @info: a #GIArgInfo
254  *
255  * Obtain the index of the user data argument. This is only valid
256  * for arguments which are callbacks.
257  *
258  * Returns: index of the user data argument or -1 if there is none
259  */
260 gint
g_arg_info_get_closure(GIArgInfo * info)261 g_arg_info_get_closure (GIArgInfo *info)
262 {
263   GIRealInfo *rinfo = (GIRealInfo *)info;
264   ArgBlob *blob;
265 
266   g_return_val_if_fail (info != NULL, -1);
267   g_return_val_if_fail (GI_IS_ARG_INFO (info), -1);
268 
269   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
270 
271   return blob->closure;
272 }
273 
274 /**
275  * g_arg_info_get_destroy:
276  * @info: a #GIArgInfo
277  *
278  * Obtains the index of the #GDestroyNotify argument. This is only valid
279  * for arguments which are callbacks.
280  *
281  * Returns: index of the #GDestroyNotify argument or -1 if there is none
282  */
283 gint
g_arg_info_get_destroy(GIArgInfo * info)284 g_arg_info_get_destroy (GIArgInfo *info)
285 {
286   GIRealInfo *rinfo = (GIRealInfo *)info;
287   ArgBlob *blob;
288 
289   g_return_val_if_fail (info != NULL, -1);
290   g_return_val_if_fail (GI_IS_ARG_INFO (info), -1);
291 
292   blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
293 
294   return blob->destroy;
295 }
296 
297 /**
298  * g_arg_info_get_type:
299  * @info: a #GIArgInfo
300  *
301  * Obtain the type information for @info.
302  *
303  * Returns: (transfer full): the #GITypeInfo holding the type
304  *   information for @info, free it with g_base_info_unref()
305  *   when done.
306  */
307 GITypeInfo *
g_arg_info_get_type(GIArgInfo * info)308 g_arg_info_get_type (GIArgInfo *info)
309 {
310   GIRealInfo *rinfo = (GIRealInfo *)info;
311 
312   g_return_val_if_fail (info != NULL, NULL);
313   g_return_val_if_fail (GI_IS_ARG_INFO (info), NULL);
314 
315   return _g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type));
316 }
317 
318 /**
319  * g_arg_info_load_type:
320  * @info: a #GIArgInfo
321  * @type: (out caller-allocates): Initialized with information about type of @info
322  *
323  * Obtain information about a the type of given argument @info; this
324  * function is a variant of g_arg_info_get_type() designed for stack
325  * allocation.
326  *
327  * The initialized @type must not be referenced after @info is deallocated.
328  */
329 void
g_arg_info_load_type(GIArgInfo * info,GITypeInfo * type)330 g_arg_info_load_type (GIArgInfo  *info,
331                       GITypeInfo *type)
332 {
333   GIRealInfo *rinfo = (GIRealInfo*) info;
334 
335   g_return_if_fail (info != NULL);
336   g_return_if_fail (GI_IS_ARG_INFO (info));
337 
338   _g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type));
339 }
340