Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : * GObject introspection: Type 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 <girepository/girepository.h>
30 : : #include "gibaseinfo-private.h"
31 : : #include "girepository-private.h"
32 : : #include "gitypelib-internal.h"
33 : : #include "gitypeinfo.h"
34 : :
35 : : /**
36 : : * GITypeInfo:
37 : : *
38 : : * `GITypeInfo` represents a type, including information about direction and
39 : : * transfer.
40 : : *
41 : : * You can retrieve a type info from an argument (see
42 : : * [class@GIRepository.ArgInfo]), a function’s return value (see
43 : : * [class@GIRepository.FunctionInfo]), a field (see
44 : : * [class@GIRepository.FieldInfo]), a property (see
45 : : * [class@GIRepository.PropertyInfo]), a constant (see
46 : : * [class@GIRepository.ConstantInfo]) or for a union discriminator (see
47 : : * [class@GIRepository.UnionInfo]).
48 : : *
49 : : * A type can either be a of a basic type which is a standard C primitive
50 : : * type or an interface type. For interface types you need to call
51 : : * [method@GIRepository.TypeInfo.get_interface] to get a reference to the base
52 : : * info for that interface.
53 : : *
54 : : * Since: 2.80
55 : : */
56 : :
57 : : /**
58 : : * gi_type_info_is_pointer:
59 : : * @info: a #GITypeInfo
60 : : *
61 : : * Obtain if the type is passed as a reference.
62 : : *
63 : : * Note that the types of `GI_DIRECTION_OUT` and `GI_DIRECTION_INOUT` parameters
64 : : * will only be pointers if the underlying type being transferred is a pointer
65 : : * (i.e. only if the type of the C function’s formal parameter is a pointer to a
66 : : * pointer).
67 : : *
68 : : * Returns: `TRUE` if it is a pointer
69 : : * Since: 2.80
70 : : */
71 : : gboolean
72 : 14 : gi_type_info_is_pointer (GITypeInfo *info)
73 : : {
74 : 14 : GIRealInfo *rinfo = (GIRealInfo *)info;
75 : : SimpleTypeBlob *type;
76 : :
77 : 14 : g_return_val_if_fail (info != NULL, FALSE);
78 : 14 : g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE);
79 : :
80 : 14 : type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
81 : :
82 : 14 : if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
83 : 9 : return type->flags.pointer;
84 : : else
85 : : {
86 : 5 : InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
87 : :
88 : 5 : return iface->pointer;
89 : : }
90 : : }
91 : :
92 : : /**
93 : : * gi_type_info_get_tag:
94 : : * @info: a #GITypeInfo
95 : : *
96 : : * Obtain the type tag for the type.
97 : : *
98 : : * See [type@GIRepository.TypeTag] for a list of type tags.
99 : : *
100 : : * Returns: the type tag
101 : : * Since: 2.80
102 : : */
103 : : GITypeTag
104 : 26 : gi_type_info_get_tag (GITypeInfo *info)
105 : : {
106 : 26 : GIRealInfo *rinfo = (GIRealInfo *)info;
107 : : SimpleTypeBlob *type;
108 : :
109 : 26 : g_return_val_if_fail (info != NULL, GI_TYPE_TAG_BOOLEAN);
110 : 26 : g_return_val_if_fail (GI_IS_TYPE_INFO (info), GI_TYPE_TAG_BOOLEAN);
111 : :
112 : 26 : type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
113 : :
114 : 26 : if (rinfo->type_is_embedded)
115 : 1 : return GI_TYPE_TAG_INTERFACE;
116 : 25 : else if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
117 : 15 : return type->flags.tag;
118 : : else
119 : : {
120 : 10 : InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
121 : :
122 : 10 : return iface->tag;
123 : : }
124 : : }
125 : :
126 : : /**
127 : : * gi_type_info_get_param_type:
128 : : * @info: a #GITypeInfo
129 : : * @n: index of the parameter
130 : : *
131 : : * Obtain the parameter type @n, or `NULL` if the type is not an array.
132 : : *
133 : : * Returns: (transfer full) (nullable): the param type info, or `NULL` if the
134 : : * type is not an array
135 : : * Since: 2.80
136 : : */
137 : : GITypeInfo *
138 : 0 : gi_type_info_get_param_type (GITypeInfo *info,
139 : : unsigned int n)
140 : : {
141 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
142 : : SimpleTypeBlob *type;
143 : :
144 : 0 : g_return_val_if_fail (info != NULL, NULL);
145 : 0 : g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL);
146 : :
147 : 0 : type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
148 : :
149 : 0 : if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
150 : : {
151 : 0 : ParamTypeBlob *param = (ParamTypeBlob *)&rinfo->typelib->data[rinfo->offset];
152 : :
153 : 0 : switch (param->tag)
154 : : {
155 : 0 : case GI_TYPE_TAG_ARRAY:
156 : : case GI_TYPE_TAG_GLIST:
157 : : case GI_TYPE_TAG_GSLIST:
158 : : case GI_TYPE_TAG_GHASH:
159 : 0 : return gi_type_info_new ((GIBaseInfo*)info, rinfo->typelib,
160 : 0 : rinfo->offset + sizeof (ParamTypeBlob)
161 : 0 : + sizeof (SimpleTypeBlob) * n);
162 : : break;
163 : 0 : default:
164 : 0 : break;
165 : : }
166 : : }
167 : :
168 : 0 : return NULL;
169 : : }
170 : :
171 : : /**
172 : : * gi_type_info_get_interface:
173 : : * @info: a #GITypeInfo
174 : : *
175 : : * For types which have `GI_TYPE_TAG_INTERFACE` such as [class@GObject.Object]s
176 : : * and boxed values, this function returns full information about the referenced
177 : : * type.
178 : : *
179 : : * You can then inspect the type of the returned [class@GIRepository.BaseInfo]
180 : : * to further query whether it is a concrete [class@GObject.Object], an
181 : : * interface, a structure, etc., using the type checking macros like
182 : : * [func@GIRepository.IS_OBJECT_INFO], or raw [type@GObject.Type]s with
183 : : * [func@GObject.TYPE_FROM_INSTANCE].
184 : : *
185 : : * Returns: (transfer full) (nullable): The [class@GIRepository.BaseInfo], or
186 : : * `NULL`. Free it with gi_base_info_unref() when done.
187 : : * Since: 2.80
188 : : */
189 : : GIBaseInfo *
190 : 5 : gi_type_info_get_interface (GITypeInfo *info)
191 : : {
192 : 5 : GIRealInfo *rinfo = (GIRealInfo *)info;
193 : :
194 : 5 : g_return_val_if_fail (info != NULL, NULL);
195 : 5 : g_return_val_if_fail (GI_IS_TYPE_INFO (info), NULL);
196 : :
197 : : /* For embedded types, the given offset is a pointer to the actual blob,
198 : : * after the end of the field. In that case we know it's a "subclass" of
199 : : * CommonBlob, so use that to determine the info type.
200 : : */
201 : 5 : if (rinfo->type_is_embedded)
202 : : {
203 : 1 : CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
204 : : GIInfoType info_type;
205 : :
206 : 1 : switch (common->blob_type)
207 : : {
208 : 1 : case BLOB_TYPE_CALLBACK:
209 : 1 : info_type = GI_INFO_TYPE_CALLBACK;
210 : 1 : break;
211 : 0 : default:
212 : : g_assert_not_reached ();
213 : : return NULL;
214 : : }
215 : 1 : return (GIBaseInfo *) gi_base_info_new (info_type, (GIBaseInfo*)info, rinfo->typelib,
216 : 1 : rinfo->offset);
217 : : }
218 : : else
219 : : {
220 : 4 : SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
221 : 4 : if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
222 : : {
223 : 4 : InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
224 : :
225 : 4 : if (blob->tag == GI_TYPE_TAG_INTERFACE)
226 : 4 : return gi_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
227 : : }
228 : : }
229 : :
230 : 0 : return NULL;
231 : : }
232 : :
233 : : /**
234 : : * gi_type_info_get_array_length_index:
235 : : * @info: a #GITypeInfo
236 : : * @out_length_index: (out) (optional): return location for the length argument
237 : : *
238 : : * Obtain the position of the argument which gives the array length of the type.
239 : : *
240 : : * The type tag must be a `GI_TYPE_TAG_ARRAY` with a length argument, or `FALSE`
241 : : * will be returned.
242 : : *
243 : : * Returns: `TRUE` if the type is an array and has a length argument
244 : : * Since: 2.80
245 : : */
246 : : gboolean
247 : 1 : gi_type_info_get_array_length_index (GITypeInfo *info,
248 : : unsigned int *out_length_index)
249 : : {
250 : 1 : GIRealInfo *rinfo = (GIRealInfo *)info;
251 : : SimpleTypeBlob *type;
252 : :
253 : 1 : g_return_val_if_fail (info != NULL, FALSE);
254 : 1 : g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE);
255 : :
256 : 1 : type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
257 : :
258 : 1 : if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
259 : : {
260 : 1 : ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
261 : :
262 : 1 : if (blob->tag == GI_TYPE_TAG_ARRAY)
263 : : {
264 : 1 : if (blob->has_length)
265 : : {
266 : 1 : if (out_length_index != NULL)
267 : 1 : *out_length_index = blob->dimensions.length;
268 : 1 : return TRUE;
269 : : }
270 : : }
271 : : }
272 : :
273 : 0 : if (out_length_index != NULL)
274 : 0 : *out_length_index = 0;
275 : 0 : return FALSE;
276 : : }
277 : :
278 : : /**
279 : : * gi_type_info_get_array_fixed_size:
280 : : * @info: a #GITypeInfo
281 : : * @out_size: (out) (optional): return location for the array size
282 : : *
283 : : * Obtain the fixed array size of the type, in number of elements (not bytes).
284 : : *
285 : : * The type tag must be a `GI_TYPE_TAG_ARRAY` with a fixed size, or `FALSE` will
286 : : * be returned.
287 : : *
288 : : * Returns: `TRUE` if the type is an array and has a fixed size
289 : : * Since: 2.80
290 : : */
291 : : gboolean
292 : 0 : gi_type_info_get_array_fixed_size (GITypeInfo *info,
293 : : size_t *out_size)
294 : : {
295 : 0 : GIRealInfo *rinfo = (GIRealInfo *)info;
296 : : SimpleTypeBlob *type;
297 : :
298 : 0 : g_return_val_if_fail (info != NULL, FALSE);
299 : 0 : g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE);
300 : :
301 : 0 : type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
302 : :
303 : 0 : if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
304 : : {
305 : 0 : ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
306 : :
307 : 0 : if (blob->tag == GI_TYPE_TAG_ARRAY)
308 : : {
309 : 0 : if (blob->has_size)
310 : : {
311 : 0 : if (out_size != NULL)
312 : 0 : *out_size = blob->dimensions.size;
313 : 0 : return TRUE;
314 : : }
315 : : }
316 : : }
317 : :
318 : 0 : if (out_size != NULL)
319 : 0 : *out_size = 0;
320 : 0 : return FALSE;
321 : : }
322 : :
323 : : /**
324 : : * gi_type_info_is_zero_terminated:
325 : : * @info: a #GITypeInfo
326 : : *
327 : : * Obtain if the last element of the array is `NULL`.
328 : : *
329 : : * The type tag must be a `GI_TYPE_TAG_ARRAY` or `FALSE` will be returned.
330 : : *
331 : : * Returns: `TRUE` if zero terminated
332 : : * Since: 2.80
333 : : */
334 : : gboolean
335 : 1 : gi_type_info_is_zero_terminated (GITypeInfo *info)
336 : : {
337 : 1 : GIRealInfo *rinfo = (GIRealInfo *)info;
338 : : SimpleTypeBlob *type;
339 : :
340 : 1 : g_return_val_if_fail (info != NULL, FALSE);
341 : 1 : g_return_val_if_fail (GI_IS_TYPE_INFO (info), FALSE);
342 : :
343 : 1 : type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
344 : :
345 : 1 : if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
346 : : {
347 : 1 : ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
348 : :
349 : 1 : if (blob->tag == GI_TYPE_TAG_ARRAY)
350 : 1 : return blob->zero_terminated;
351 : : }
352 : :
353 : 0 : return FALSE;
354 : : }
355 : :
356 : : /**
357 : : * gi_type_info_get_array_type:
358 : : * @info: a #GITypeInfo
359 : : *
360 : : * Obtain the array type for this type.
361 : : *
362 : : * See [enum@GIRepository.ArrayType] for a list of possible values.
363 : : *
364 : : * It is an error to call this on an @info which is not an array type. Use
365 : : * [method@GIRepository.TypeInfo.get_tag] to check.
366 : : *
367 : : * Returns: the array type
368 : : * Since: 2.80
369 : : */
370 : : GIArrayType
371 : 1 : gi_type_info_get_array_type (GITypeInfo *info)
372 : : {
373 : 1 : GIRealInfo *rinfo = (GIRealInfo *)info;
374 : : SimpleTypeBlob *type;
375 : :
376 : 1 : g_return_val_if_fail (info != NULL, -1);
377 : 1 : g_return_val_if_fail (GI_IS_TYPE_INFO (info), -1);
378 : :
379 : 1 : type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
380 : :
381 : 1 : if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
382 : : {
383 : 1 : ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
384 : 1 : g_return_val_if_fail (blob->tag == GI_TYPE_TAG_ARRAY, -1);
385 : :
386 : 1 : return blob->array_type;
387 : : }
388 : :
389 : : /* Not an array type */
390 : : g_assert_not_reached ();
391 : : }
392 : :
393 : : /**
394 : : * gi_type_info_get_storage_type:
395 : : * @info: a #GITypeInfo
396 : : *
397 : : * Obtain the type tag corresponding to the underlying storage type in C for
398 : : * the type.
399 : : *
400 : : * See [type@GIRepository.TypeTag] for a list of type tags.
401 : : *
402 : : * Returns: the type tag
403 : : * Since: 2.80
404 : : */
405 : : GITypeTag
406 : 0 : gi_type_info_get_storage_type (GITypeInfo *info)
407 : : {
408 : 0 : GITypeTag type_tag = gi_type_info_get_tag (info);
409 : :
410 : 0 : if (type_tag == GI_TYPE_TAG_INTERFACE)
411 : : {
412 : 0 : GIBaseInfo *interface = gi_type_info_get_interface (info);
413 : 0 : GIInfoType info_type = gi_base_info_get_info_type (interface);
414 : 0 : if (info_type == GI_INFO_TYPE_ENUM || info_type == GI_INFO_TYPE_FLAGS)
415 : 0 : type_tag = gi_enum_info_get_storage_type ((GIEnumInfo *) interface);
416 : 0 : gi_base_info_unref (interface);
417 : : }
418 : :
419 : 0 : return type_tag;
420 : : }
421 : :
422 : : /**
423 : : * gi_type_tag_argument_from_hash_pointer:
424 : : * @storage_type: a [type@GIRepository.TypeTag] obtained from
425 : : * [method@GIRepository.TypeInfo.get_storage_type]
426 : : * @hash_pointer: a pointer, such as a [struct@GLib.HashTable] data pointer
427 : : * @arg: (out caller-allocates) (not nullable): a [type@GIRepository.Argument]
428 : : * to fill in
429 : : *
430 : : * Convert a data pointer from a GLib data structure to a
431 : : * [type@GIRepository.Argument].
432 : : *
433 : : * GLib data structures, such as [type@GLib.List], [type@GLib.SList], and
434 : : * [type@GLib.HashTable], all store data pointers.
435 : : *
436 : : * In the case where the list or hash table is storing single types rather than
437 : : * structs, these data pointers may have values stuffed into them via macros
438 : : * such as `GPOINTER_TO_INT`.
439 : : *
440 : : * Use this function to ensure that all values are correctly extracted from
441 : : * stuffed pointers, regardless of the machine’s architecture or endianness.
442 : : *
443 : : * This function fills in the appropriate field of @arg with the value extracted
444 : : * from @hash_pointer, depending on @storage_type.
445 : : *
446 : : * Since: 2.80
447 : : */
448 : : void
449 : 0 : gi_type_tag_argument_from_hash_pointer (GITypeTag storage_type,
450 : : void *hash_pointer,
451 : : GIArgument *arg)
452 : : {
453 : 0 : switch (storage_type)
454 : : {
455 : 0 : case GI_TYPE_TAG_BOOLEAN:
456 : 0 : arg->v_boolean = !!GPOINTER_TO_INT (hash_pointer);
457 : 0 : break;
458 : 0 : case GI_TYPE_TAG_INT8:
459 : 0 : arg->v_int8 = (int8_t) GPOINTER_TO_INT (hash_pointer);
460 : 0 : break;
461 : 0 : case GI_TYPE_TAG_UINT8:
462 : 0 : arg->v_uint8 = (uint8_t) GPOINTER_TO_UINT (hash_pointer);
463 : 0 : break;
464 : 0 : case GI_TYPE_TAG_INT16:
465 : 0 : arg->v_int16 = (int16_t) GPOINTER_TO_INT (hash_pointer);
466 : 0 : break;
467 : 0 : case GI_TYPE_TAG_UINT16:
468 : 0 : arg->v_uint16 = (uint16_t) GPOINTER_TO_UINT (hash_pointer);
469 : 0 : break;
470 : 0 : case GI_TYPE_TAG_INT32:
471 : 0 : arg->v_int32 = (int32_t) GPOINTER_TO_INT (hash_pointer);
472 : 0 : break;
473 : 0 : case GI_TYPE_TAG_UINT32:
474 : : case GI_TYPE_TAG_UNICHAR:
475 : 0 : arg->v_uint32 = (uint32_t) GPOINTER_TO_UINT (hash_pointer);
476 : 0 : break;
477 : 0 : case GI_TYPE_TAG_GTYPE:
478 : 0 : arg->v_size = GPOINTER_TO_SIZE (hash_pointer);
479 : 0 : break;
480 : 0 : case GI_TYPE_TAG_UTF8:
481 : : case GI_TYPE_TAG_FILENAME:
482 : : case GI_TYPE_TAG_INTERFACE:
483 : : case GI_TYPE_TAG_ARRAY:
484 : : case GI_TYPE_TAG_GLIST:
485 : : case GI_TYPE_TAG_GSLIST:
486 : : case GI_TYPE_TAG_GHASH:
487 : : case GI_TYPE_TAG_ERROR:
488 : 0 : arg->v_pointer = hash_pointer;
489 : 0 : break;
490 : 0 : case GI_TYPE_TAG_INT64:
491 : : case GI_TYPE_TAG_UINT64:
492 : : case GI_TYPE_TAG_FLOAT:
493 : : case GI_TYPE_TAG_DOUBLE:
494 : : default:
495 : 0 : g_critical ("Unsupported storage type for pointer-stuffing: %s",
496 : : gi_type_tag_to_string (storage_type));
497 : 0 : arg->v_pointer = hash_pointer;
498 : : }
499 : 0 : }
500 : :
501 : : /**
502 : : * gi_type_info_argument_from_hash_pointer:
503 : : * @info: a #GITypeInfo
504 : : * @hash_pointer: a pointer, such as a [struct@GLib.HashTable] data pointer
505 : : * @arg: (out caller-allocates): a [type@GIRepository.Argument] to fill in
506 : : *
507 : : * Convert a data pointer from a GLib data structure to a
508 : : * [type@GIRepository.Argument].
509 : : *
510 : : * GLib data structures, such as [type@GLib.List], [type@GLib.SList], and
511 : : * [type@GLib.HashTable], all store data pointers.
512 : : *
513 : : * In the case where the list or hash table is storing single types rather than
514 : : * structs, these data pointers may have values stuffed into them via macros
515 : : * such as `GPOINTER_TO_INT`.
516 : : *
517 : : * Use this function to ensure that all values are correctly extracted from
518 : : * stuffed pointers, regardless of the machine’s architecture or endianness.
519 : : *
520 : : * This function fills in the appropriate field of @arg with the value extracted
521 : : * from @hash_pointer, depending on the storage type of @info.
522 : : *
523 : : * Since: 2.80
524 : : */
525 : : void
526 : 0 : gi_type_info_argument_from_hash_pointer (GITypeInfo *info,
527 : : void *hash_pointer,
528 : : GIArgument *arg)
529 : : {
530 : 0 : GITypeTag storage_type = gi_type_info_get_storage_type (info);
531 : 0 : gi_type_tag_argument_from_hash_pointer (storage_type, hash_pointer,
532 : : arg);
533 : 0 : }
534 : :
535 : : /**
536 : : * gi_type_tag_hash_pointer_from_argument:
537 : : * @storage_type: a [type@GIRepository.TypeTag] obtained from
538 : : * [method@GIRepository.TypeInfo.get_storage_type]
539 : : * @arg: a [type@GIRepository.Argument] with the value to stuff into a pointer
540 : : *
541 : : * Convert a [type@GIRepository.Argument] to data pointer for use in a GLib
542 : : * data structure.
543 : : *
544 : : * GLib data structures, such as [type@GLib.List], [type@GLib.SList], and
545 : : * [type@GLib.HashTable], all store data pointers.
546 : : *
547 : : * In the case where the list or hash table is storing single types rather than
548 : : * structs, these data pointers may have values stuffed into them via macros
549 : : * such as `GPOINTER_TO_INT`.
550 : : *
551 : : * Use this function to ensure that all values are correctly stuffed into
552 : : * pointers, regardless of the machine’s architecture or endianness.
553 : : *
554 : : * This function returns a pointer stuffed with the appropriate field of @arg,
555 : : * depending on @storage_type.
556 : : *
557 : : * Returns: A stuffed pointer, that can be stored in a [struct@GLib.HashTable],
558 : : * for example
559 : : * Since: 2.80
560 : : */
561 : : void *
562 : 0 : gi_type_tag_hash_pointer_from_argument (GITypeTag storage_type,
563 : : GIArgument *arg)
564 : : {
565 : 0 : switch (storage_type)
566 : : {
567 : 0 : case GI_TYPE_TAG_BOOLEAN:
568 : 0 : return GINT_TO_POINTER (arg->v_boolean);
569 : 0 : case GI_TYPE_TAG_INT8:
570 : 0 : return GINT_TO_POINTER (arg->v_int8);
571 : 0 : case GI_TYPE_TAG_UINT8:
572 : 0 : return GUINT_TO_POINTER (arg->v_uint8);
573 : 0 : case GI_TYPE_TAG_INT16:
574 : 0 : return GINT_TO_POINTER (arg->v_int16);
575 : 0 : case GI_TYPE_TAG_UINT16:
576 : 0 : return GUINT_TO_POINTER (arg->v_uint16);
577 : 0 : case GI_TYPE_TAG_INT32:
578 : 0 : return GINT_TO_POINTER (arg->v_int32);
579 : 0 : case GI_TYPE_TAG_UINT32:
580 : : case GI_TYPE_TAG_UNICHAR:
581 : 0 : return GUINT_TO_POINTER (arg->v_uint32);
582 : 0 : case GI_TYPE_TAG_GTYPE:
583 : 0 : return GSIZE_TO_POINTER (arg->v_size);
584 : 0 : case GI_TYPE_TAG_UTF8:
585 : : case GI_TYPE_TAG_FILENAME:
586 : : case GI_TYPE_TAG_INTERFACE:
587 : : case GI_TYPE_TAG_ARRAY:
588 : : case GI_TYPE_TAG_GLIST:
589 : : case GI_TYPE_TAG_GSLIST:
590 : : case GI_TYPE_TAG_GHASH:
591 : : case GI_TYPE_TAG_ERROR:
592 : 0 : return arg->v_pointer;
593 : 0 : case GI_TYPE_TAG_INT64:
594 : : case GI_TYPE_TAG_UINT64:
595 : : case GI_TYPE_TAG_FLOAT:
596 : : case GI_TYPE_TAG_DOUBLE:
597 : : default:
598 : 0 : g_critical ("Unsupported storage type for pointer-stuffing: %s",
599 : : gi_type_tag_to_string (storage_type));
600 : 0 : return arg->v_pointer;
601 : : }
602 : : }
603 : :
604 : : /**
605 : : * gi_type_info_hash_pointer_from_argument:
606 : : * @info: a #GITypeInfo
607 : : * @arg: a [struct@GIRepository.Argument] with the value to stuff into a pointer
608 : : *
609 : : * Convert a [type@GIRepository.Argument] to data pointer for use in a GLib
610 : : * data structure.
611 : : *
612 : : * GLib data structures, such as [type@GLib.List], [type@GLib.SList], and
613 : : * [type@GLib.HashTable], all store data pointers.
614 : : *
615 : : * In the case where the list or hash table is storing single types rather than
616 : : * structs, these data pointers may have values stuffed into them via macros
617 : : * such as `GPOINTER_TO_INT`.
618 : : *
619 : : * Use this function to ensure that all values are correctly stuffed into
620 : : * pointers, regardless of the machine’s architecture or endianness.
621 : : *
622 : : * This function returns a pointer stuffed with the appropriate field of @arg,
623 : : * depending on the storage type of @info.
624 : : *
625 : : * Returns: A stuffed pointer, that can be stored in a [struct@GLib.HashTable],
626 : : * for example
627 : : * Since: 2.80
628 : : */
629 : : void *
630 : 0 : gi_type_info_hash_pointer_from_argument (GITypeInfo *info,
631 : : GIArgument *arg)
632 : : {
633 : 0 : GITypeTag storage_type = gi_type_info_get_storage_type (info);
634 : 0 : return gi_type_tag_hash_pointer_from_argument (storage_type, arg);
635 : : }
636 : :
637 : : void
638 : 5 : gi_type_info_class_init (gpointer g_class,
639 : : gpointer class_data)
640 : : {
641 : 5 : GIBaseInfoClass *info_class = g_class;
642 : :
643 : 5 : info_class->info_type = GI_INFO_TYPE_TYPE;
644 : 5 : }
|