Branch data Line data Source code
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 : : * SPDX-License-Identifier: LGPL-2.1-or-later
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2 of the License, or (at your option) any later version.
13 : : *
14 : : * This library is distributed in the hope that it will be useful,
15 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : * Lesser General Public License for more details.
18 : : *
19 : : * You should have received a copy of the GNU Lesser General Public
20 : : * License along with this library; if not, write to the
21 : : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 : : * Boston, MA 02111-1307, USA.
23 : : */
24 : :
25 : : #include "config.h"
26 : :
27 : : #include <glib.h>
28 : :
29 : : #include "gibaseinfo-private.h"
30 : : #include "gitypelib-internal.h"
31 : : #include "girepository-private.h"
32 : : #include "giarginfo.h"
33 : :
34 : :
35 : : /* GIArgInfo functions */
36 : :
37 : : /**
38 : : * GIArgInfo:
39 : : *
40 : : * `GIArgInfo` represents an argument of a callable.
41 : : *
42 : : * An argument is always part of a [class@GIRepository.CallableInfo].
43 : : *
44 : : * Since: 2.80
45 : : */
46 : :
47 : : /**
48 : : * gi_arg_info_get_direction:
49 : : * @info: a #GIArgInfo
50 : : *
51 : : * Obtain the direction of the argument. Check [type@GIRepository.Direction]
52 : : * for possible direction values.
53 : : *
54 : : * Returns: The direction
55 : : * Since: 2.80
56 : : */
57 : : GIDirection
58 : 8 : gi_arg_info_get_direction (GIArgInfo *info)
59 : : {
60 : 8 : GIRealInfo *rinfo = (GIRealInfo *)info;
61 : : ArgBlob *blob;
62 : :
63 : 8 : g_return_val_if_fail (info != NULL, -1);
64 : 8 : g_return_val_if_fail (GI_IS_ARG_INFO (info), -1);
65 : :
66 : 8 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
67 : :
68 : 8 : if (blob->in && blob->out)
69 : 0 : return GI_DIRECTION_INOUT;
70 : 8 : else if (blob->out)
71 : 1 : return GI_DIRECTION_OUT;
72 : : else
73 : 7 : return GI_DIRECTION_IN;
74 : : }
75 : :
76 : : /**
77 : : * gi_arg_info_is_return_value:
78 : : * @info: a #GIArgInfo
79 : : *
80 : : * Obtain if the argument is a return value. It can either be a
81 : : * parameter or a return value.
82 : : *
83 : : * Returns: `TRUE` if it is a return value
84 : : * Since: 2.80
85 : : */
86 : : gboolean
87 : 1 : gi_arg_info_is_return_value (GIArgInfo *info)
88 : : {
89 : 1 : GIRealInfo *rinfo = (GIRealInfo *)info;
90 : : ArgBlob *blob;
91 : :
92 : 1 : g_return_val_if_fail (info != NULL, FALSE);
93 : 1 : g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
94 : :
95 : 1 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
96 : :
97 : 1 : return blob->return_value;
98 : : }
99 : :
100 : : /**
101 : : * gi_arg_info_is_caller_allocates:
102 : : * @info: a #GIArgInfo
103 : : *
104 : : * Obtain if the argument is a pointer to a struct or object that will
105 : : * receive an output of a function.
106 : : *
107 : : * The default assumption for `GI_DIRECTION_OUT` arguments which have allocation
108 : : * is that the callee allocates; if this is `TRUE`, then the caller must
109 : : * allocate.
110 : : *
111 : : * Returns: `TRUE` if caller is required to have allocated the argument
112 : : * Since: 2.80
113 : : */
114 : : gboolean
115 : 2 : gi_arg_info_is_caller_allocates (GIArgInfo *info)
116 : : {
117 : 2 : GIRealInfo *rinfo = (GIRealInfo *)info;
118 : : ArgBlob *blob;
119 : :
120 : 2 : g_return_val_if_fail (info != NULL, FALSE);
121 : 2 : g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
122 : :
123 : 2 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
124 : :
125 : 2 : return blob->caller_allocates;
126 : : }
127 : :
128 : : /**
129 : : * gi_arg_info_is_optional:
130 : : * @info: a #GIArgInfo
131 : : *
132 : : * Obtain if the argument is optional.
133 : : *
134 : : * For ‘out’ arguments this means that you can pass `NULL` in order to ignore
135 : : * the result.
136 : : *
137 : : * Returns: `TRUE` if it is an optional argument
138 : : * Since: 2.80
139 : : */
140 : : gboolean
141 : 2 : gi_arg_info_is_optional (GIArgInfo *info)
142 : : {
143 : 2 : GIRealInfo *rinfo = (GIRealInfo *)info;
144 : : ArgBlob *blob;
145 : :
146 : 2 : g_return_val_if_fail (info != NULL, FALSE);
147 : 2 : g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
148 : :
149 : 2 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
150 : :
151 : 2 : return blob->optional;
152 : : }
153 : :
154 : : /**
155 : : * gi_arg_info_may_be_null:
156 : : * @info: a #GIArgInfo
157 : : *
158 : : * Obtain if the type of the argument includes the possibility of `NULL`.
159 : : *
160 : : * For ‘in’ values this means that `NULL` is a valid value. For ‘out’
161 : : * values, this means that `NULL` may be returned.
162 : : *
163 : : * See also [method@GIRepository.ArgInfo.is_optional].
164 : : *
165 : : * Returns: `TRUE` if the value may be `NULL`
166 : : * Since: 2.80
167 : : */
168 : : gboolean
169 : 3 : gi_arg_info_may_be_null (GIArgInfo *info)
170 : : {
171 : 3 : GIRealInfo *rinfo = (GIRealInfo *)info;
172 : : ArgBlob *blob;
173 : :
174 : 3 : g_return_val_if_fail (info != NULL, FALSE);
175 : 3 : g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
176 : :
177 : 3 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
178 : :
179 : 3 : return blob->nullable;
180 : : }
181 : :
182 : : /**
183 : : * gi_arg_info_is_skip:
184 : : * @info: a #GIArgInfo
185 : : *
186 : : * Obtain if an argument is only useful in C.
187 : : *
188 : : * Returns: `TRUE` if argument is only useful in C.
189 : : * Since: 2.80
190 : : */
191 : : gboolean
192 : 1 : gi_arg_info_is_skip (GIArgInfo *info)
193 : : {
194 : 1 : GIRealInfo *rinfo = (GIRealInfo *)info;
195 : : ArgBlob *blob;
196 : :
197 : 1 : g_return_val_if_fail (info != NULL, FALSE);
198 : 1 : g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
199 : :
200 : 1 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
201 : :
202 : 1 : return blob->skip;
203 : : }
204 : :
205 : : /**
206 : : * gi_arg_info_get_ownership_transfer:
207 : : * @info: a #GIArgInfo
208 : : *
209 : : * Obtain the ownership transfer for this argument.
210 : : * [type@GIRepository.Transfer] contains a list of possible values.
211 : : *
212 : : * Returns: The transfer
213 : : * Since: 2.80
214 : : */
215 : : GITransfer
216 : 2 : gi_arg_info_get_ownership_transfer (GIArgInfo *info)
217 : : {
218 : 2 : GIRealInfo *rinfo = (GIRealInfo *)info;
219 : : ArgBlob *blob;
220 : :
221 : 2 : g_return_val_if_fail (info != NULL, -1);
222 : 2 : g_return_val_if_fail (GI_IS_ARG_INFO (info), -1);
223 : :
224 : 2 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
225 : :
226 : 2 : if (blob->transfer_ownership)
227 : 1 : return GI_TRANSFER_EVERYTHING;
228 : 1 : else if (blob->transfer_container_ownership)
229 : 0 : return GI_TRANSFER_CONTAINER;
230 : : else
231 : 1 : return GI_TRANSFER_NOTHING;
232 : : }
233 : :
234 : : /**
235 : : * gi_arg_info_get_scope:
236 : : * @info: a #GIArgInfo
237 : : *
238 : : * Obtain the scope type for this argument.
239 : : *
240 : : * The scope type explains how a callback is going to be invoked, most
241 : : * importantly when the resources required to invoke it can be freed.
242 : : *
243 : : * [type@GIRepository.ScopeType] contains a list of possible values.
244 : : *
245 : : * Returns: The scope type
246 : : * Since: 2.80
247 : : */
248 : : GIScopeType
249 : 1 : gi_arg_info_get_scope (GIArgInfo *info)
250 : : {
251 : 1 : GIRealInfo *rinfo = (GIRealInfo *)info;
252 : : ArgBlob *blob;
253 : :
254 : 1 : g_return_val_if_fail (info != NULL, -1);
255 : 1 : g_return_val_if_fail (GI_IS_ARG_INFO (info), -1);
256 : :
257 : 1 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
258 : :
259 : 1 : return blob->scope;
260 : : }
261 : :
262 : : /**
263 : : * gi_arg_info_get_closure_index:
264 : : * @info: a #GIArgInfo
265 : : * @out_closure_index: (out) (optional): return location for the closure index
266 : : *
267 : : * Obtain the index of the user data argument. This is only valid
268 : : * for arguments which are callbacks.
269 : : *
270 : : * Returns: `TRUE` if the argument has a user data argument
271 : : * Since: 2.80
272 : : */
273 : : gboolean
274 : 2 : gi_arg_info_get_closure_index (GIArgInfo *info,
275 : : unsigned int *out_closure_index)
276 : : {
277 : 2 : GIRealInfo *rinfo = (GIRealInfo *)info;
278 : : ArgBlob *blob;
279 : : gboolean has_closure_index;
280 : :
281 : 2 : g_return_val_if_fail (info != NULL, FALSE);
282 : 2 : g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
283 : :
284 : 2 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
285 : :
286 : 2 : has_closure_index = (blob->closure >= 0);
287 : :
288 : 2 : if (out_closure_index != NULL)
289 : 1 : *out_closure_index = has_closure_index ? blob->closure : 0;
290 : 2 : return has_closure_index;
291 : : }
292 : :
293 : : /**
294 : : * gi_arg_info_get_destroy_index:
295 : : * @info: a #GIArgInfo
296 : : * @out_destroy_index: (out) (optional): return location for the destroy index
297 : : *
298 : : * Obtains the index of the [type@GLib.DestroyNotify] argument. This is only
299 : : * valid for arguments which are callbacks.
300 : : *
301 : : * Returns: `TRUE` if the argument has a [type@GLib.DestroyNotify] argument
302 : : * Since: 2.80
303 : : */
304 : : gboolean
305 : 2 : gi_arg_info_get_destroy_index (GIArgInfo *info,
306 : : unsigned int *out_destroy_index)
307 : : {
308 : 2 : GIRealInfo *rinfo = (GIRealInfo *)info;
309 : : ArgBlob *blob;
310 : : gboolean has_destroy_index;
311 : :
312 : 2 : g_return_val_if_fail (info != NULL, FALSE);
313 : 2 : g_return_val_if_fail (GI_IS_ARG_INFO (info), FALSE);
314 : :
315 : 2 : blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
316 : :
317 : 2 : has_destroy_index = (blob->destroy >= 0);
318 : :
319 : 2 : if (out_destroy_index != NULL)
320 : 1 : *out_destroy_index = has_destroy_index ? blob->destroy : 0;
321 : 2 : return has_destroy_index;
322 : : }
323 : :
324 : : /**
325 : : * gi_arg_info_get_type_info:
326 : : * @info: a #GIArgInfo
327 : : *
328 : : * Obtain the type information for @info.
329 : : *
330 : : * Returns: (transfer full): The [class@GIRepository.TypeInfo] holding the type
331 : : * information for @info, free it with [method@GIRepository.BaseInfo.unref]
332 : : * when done
333 : : * Since: 2.80
334 : : */
335 : : GITypeInfo *
336 : 4 : gi_arg_info_get_type_info (GIArgInfo *info)
337 : : {
338 : 4 : GIRealInfo *rinfo = (GIRealInfo *)info;
339 : :
340 : 4 : g_return_val_if_fail (info != NULL, NULL);
341 : 4 : g_return_val_if_fail (GI_IS_ARG_INFO (info), NULL);
342 : :
343 : 4 : return gi_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type));
344 : : }
345 : :
346 : : /**
347 : : * gi_arg_info_load_type_info:
348 : : * @info: a #GIArgInfo
349 : : * @type: (out caller-allocates): Initialized with information about type of @info
350 : : *
351 : : * Obtain information about a the type of given argument @info; this
352 : : * function is a variant of [method@GIRepository.ArgInfo.get_type_info] designed
353 : : * for stack allocation.
354 : : *
355 : : * The initialized @type must not be referenced after @info is deallocated.
356 : : *
357 : : * Once you are done with @type, it must be cleared using
358 : : * [method@GIRepository.BaseInfo.clear].
359 : : *
360 : : * Since: 2.80
361 : : */
362 : : void
363 : 6 : gi_arg_info_load_type_info (GIArgInfo *info,
364 : : GITypeInfo *type)
365 : : {
366 : 6 : GIRealInfo *rinfo = (GIRealInfo*) info;
367 : :
368 : 6 : g_return_if_fail (info != NULL);
369 : 6 : g_return_if_fail (GI_IS_ARG_INFO (info));
370 : :
371 : 6 : gi_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type));
372 : : }
373 : :
374 : : void
375 : 5 : gi_arg_info_class_init (gpointer g_class,
376 : : gpointer class_data)
377 : : {
378 : 5 : GIBaseInfoClass *info_class = g_class;
379 : :
380 : 5 : info_class->info_type = GI_INFO_TYPE_ARG;
381 : 5 : }
|