1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 * GObject introspection: Object 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 "giobjectinfo.h"
34
35 /**
36 * GIObjectInfo:
37 *
38 * `GIObjectInfo` represents a classed type.
39 *
40 * Classed types in [type@GObject.Type] inherit from
41 * [type@GObject.TypeInstance]; the most common type is [class@GObject.Object].
42 *
43 * A `GIObjectInfo` doesn’t represent a specific instance of a classed type,
44 * instead this represent the object type (i.e. the class).
45 *
46 * A `GIObjectInfo` has methods, fields, properties, signals, interfaces,
47 * constants and virtual functions.
48 *
49 * Since: 2.80
50 */
51
52 /**
53 * gi_object_info_get_field_offset:
54 * @info: a #GIObjectInfo
55 * @n: index of queried field
56 *
57 * Obtain the offset of the specified field.
58 *
59 * Returns: field offset, in bytes
60 * Since: 2.80
61 */
62 static gint32
63 gi_object_info_get_field_offset (GIObjectInfo *info,
64 guint n)
65 {
66 GIRealInfo *rinfo = (GIRealInfo *)info;
67 Header *header = (Header *)rinfo->typelib->data;
68 ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
69 guint32 offset;
70 FieldBlob *field_blob;
71
72 offset = rinfo->offset + header->object_blob_size
73 + (blob->n_interfaces + blob->n_interfaces % 2) * 2;
74
75 for (guint i = 0; i < n; i++)
76 {
77 field_blob = (FieldBlob *)&rinfo->typelib->data[offset];
78 offset += header->field_blob_size;
79 if (field_blob->has_embedded_type)
80 offset += header->callback_blob_size;
81 }
82
83 return offset;
84 }
85
86 /**
87 * gi_object_info_get_parent:
88 * @info: a #GIObjectInfo
89 *
90 * Obtain the parent of the object type.
91 *
92 * Returns: (transfer full) (nullable): The `GIObjectInfo`. Free the struct by
93 * calling [method@GIRepository.BaseInfo.unref] when done.
94 * Since: 2.80
95 */
96 GIObjectInfo *
97 gi_object_info_get_parent (GIObjectInfo *info)
98 {
99 GIRealInfo *rinfo = (GIRealInfo *)info;
100 ObjectBlob *blob;
101
102 g_return_val_if_fail (info != NULL, NULL);
103 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
104
105 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
106
107 if (blob->parent)
108 return (GIObjectInfo *) gi_info_from_entry (rinfo->repository,
109 rinfo->typelib, blob->parent);
110 else
111 return NULL;
112 }
113
114 /**
115 * gi_object_info_get_abstract:
116 * @info: a #GIObjectInfo
117 *
118 * Obtain if the object type is an abstract type, i.e. if it cannot be
119 * instantiated.
120 *
121 * Returns: `TRUE` if the object type is abstract
122 * Since: 2.80
123 */
124 gboolean
125 gi_object_info_get_abstract (GIObjectInfo *info)
126 {
127 GIRealInfo *rinfo = (GIRealInfo *)info;
128 ObjectBlob *blob;
129
130 g_return_val_if_fail (info != NULL, FALSE);
131 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
132
133 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
134
135 return blob->abstract != 0;
136 }
137
138 /**
139 * gi_object_info_get_final:
140 * @info: a #GIObjectInfo
141 *
142 * Checks whether the object type is a final type, i.e. if it cannot
143 * be derived.
144 *
145 * Returns: `TRUE` if the object type is final
146 * Since: 2.80
147 */
148 gboolean
149 gi_object_info_get_final (GIObjectInfo *info)
150 {
151 GIRealInfo *rinfo = (GIRealInfo *) info;
152 ObjectBlob *blob;
153
154 g_return_val_if_fail (info != NULL, FALSE);
155 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
156
157 blob = (ObjectBlob *) &rinfo->typelib->data[rinfo->offset];
158
159 return blob->final_ != 0;
160 }
161
162 /**
163 * gi_object_info_get_fundamental:
164 * @info: a #GIObjectInfo
165 *
166 * Obtain if the object type is of a fundamental type which is not
167 * `G_TYPE_OBJECT`.
168 *
169 * This is mostly for supporting `GstMiniObject`.
170 *
171 * Returns: `TRUE` if the object type is a fundamental type
172 * Since: 2.80
173 */
174 gboolean
175 gi_object_info_get_fundamental (GIObjectInfo *info)
176 {
177 GIRealInfo *rinfo = (GIRealInfo *)info;
178 ObjectBlob *blob;
179
180 g_return_val_if_fail (info != NULL, FALSE);
181 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), FALSE);
182
183 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
184
185 return blob->fundamental != 0;
186 }
187
188 /**
189 * gi_object_info_get_type_name:
190 * @info: a #GIObjectInfo
191 *
192 * Obtain the name of the object’s class/type.
193 *
194 * Returns: name of the object’s type
195 * Since: 2.80
196 */
197 const gchar *
198 gi_object_info_get_type_name (GIObjectInfo *info)
199 {
200 GIRealInfo *rinfo = (GIRealInfo *)info;
201 ObjectBlob *blob;
202
203 g_return_val_if_fail (info != NULL, NULL);
204 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
205
206 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
207
208 return gi_typelib_get_string (rinfo->typelib, blob->gtype_name);
209 }
210
211 /**
212 * gi_object_info_get_type_init_function_name:
213 * @info: a #GIObjectInfo
214 *
215 * Obtain the name of the function which, when called, will return the
216 * [type@GObject.Type] for this object type.
217 *
218 * Returns: the type init function name
219 * Since: 2.80
220 */
221 const gchar *
222 gi_object_info_get_type_init_function_name (GIObjectInfo *info)
223 {
224 GIRealInfo *rinfo = (GIRealInfo *)info;
225 ObjectBlob *blob;
226
227 g_return_val_if_fail (info != NULL, NULL);
228 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
229
230 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
231
232 return gi_typelib_get_string (rinfo->typelib, blob->gtype_init);
233 }
234
235 /**
236 * gi_object_info_get_n_interfaces:
237 * @info: a #GIObjectInfo
238 *
239 * Obtain the number of interfaces that this object type has.
240 *
241 * Returns: number of interfaces
242 * Since: 2.80
243 */
244 guint
245 gi_object_info_get_n_interfaces (GIObjectInfo *info)
246 {
247 GIRealInfo *rinfo = (GIRealInfo *)info;
248 ObjectBlob *blob;
249
250 g_return_val_if_fail (info != NULL, 0);
251 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
252
253 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
254
255 return blob->n_interfaces;
256 }
257
258 /**
259 * gi_object_info_get_interface:
260 * @info: a #GIObjectInfo
261 * @n: index of interface to get
262 *
263 * Obtain an object type interface at index @n.
264 *
265 * Returns: (transfer full): The [class@GIRepository.InterfaceInfo]. Free the
266 * struct by calling [method@GIRepository.BaseInfo.unref] when done.
267 * Since: 2.80
268 */
269 GIInterfaceInfo *
270 gi_object_info_get_interface (GIObjectInfo *info,
271 guint n)
272 {
273 GIRealInfo *rinfo = (GIRealInfo *)info;
274 ObjectBlob *blob;
275
276 g_return_val_if_fail (info != NULL, NULL);
277 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
278
279 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
280
281 return (GIInterfaceInfo *) gi_info_from_entry (rinfo->repository,
282 rinfo->typelib, blob->interfaces[n]);
283 }
284
285 /**
286 * gi_object_info_get_n_fields:
287 * @info: a #GIObjectInfo
288 *
289 * Obtain the number of fields that this object type has.
290 *
291 * Returns: number of fields
292 * Since: 2.80
293 */
294 guint
295 gi_object_info_get_n_fields (GIObjectInfo *info)
296 {
297 GIRealInfo *rinfo = (GIRealInfo *)info;
298 ObjectBlob *blob;
299
300 g_return_val_if_fail (info != NULL, 0);
301 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
302
303 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
304
305 return blob->n_fields;
306 }
307
308 /**
309 * gi_object_info_get_field:
310 * @info: a #GIObjectInfo
311 * @n: index of field to get
312 *
313 * Obtain an object type field at index @n.
314 *
315 * Returns: (transfer full): The [class@GIRepository.FieldInfo]. Free the struct
316 * by calling [method@GIRepository.BaseInfo.unref] when done.
317 * Since: 2.80
318 */
319 GIFieldInfo *
320 gi_object_info_get_field (GIObjectInfo *info,
321 guint n)
322 {
323 gint offset;
324 GIRealInfo *rinfo = (GIRealInfo *)info;
325
326 g_return_val_if_fail (info != NULL, NULL);
327 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
328
329 offset = gi_object_info_get_field_offset(info, n);
330
331 return (GIFieldInfo *) gi_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset);
332 }
333
334 /**
335 * gi_object_info_get_n_properties:
336 * @info: a #GIObjectInfo
337 *
338 * Obtain the number of properties that this object type has.
339 *
340 * Returns: number of properties
341 * Since: 2.80
342 */
343 guint
344 gi_object_info_get_n_properties (GIObjectInfo *info)
345 {
346 GIRealInfo *rinfo = (GIRealInfo *)info;
347 ObjectBlob *blob;
348
349 g_return_val_if_fail (info != NULL, 0);
350 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
351
352 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
353 return blob->n_properties;
354 }
355
356 /**
357 * gi_object_info_get_property:
358 * @info: a #GIObjectInfo
359 * @n: index of property to get
360 *
361 * Obtain an object type property at index @n.
362 *
363 * Returns: (transfer full): The [class@GIRepository.PropertyInfo]. Free the
364 * struct by calling [method@GIRepository.BaseInfo.unref] when done.
365 * Since: 2.80
366 */
367 GIPropertyInfo *
368 gi_object_info_get_property (GIObjectInfo *info,
369 guint n)
370 {
371 gint offset;
372 GIRealInfo *rinfo = (GIRealInfo *)info;
373 Header *header;
374 ObjectBlob *blob;
375
376 g_return_val_if_fail (info != NULL, NULL);
377 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
378
379 header = (Header *)rinfo->typelib->data;
380 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
381
382 offset = rinfo->offset + header->object_blob_size
383 + (blob->n_interfaces + blob->n_interfaces % 2) * 2
384 + blob->n_fields * header->field_blob_size
385 + blob->n_field_callbacks * header->callback_blob_size
386 + n * header->property_blob_size;
387
388 return (GIPropertyInfo *) gi_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
389 rinfo->typelib, offset);
390 }
391
392 /**
393 * gi_object_info_get_n_methods:
394 * @info: a #GIObjectInfo
395 *
396 * Obtain the number of methods that this object type has.
397 *
398 * Returns: number of methods
399 * Since: 2.80
400 */
401 guint
402 gi_object_info_get_n_methods (GIObjectInfo *info)
403 {
404 GIRealInfo *rinfo = (GIRealInfo *)info;
405 ObjectBlob *blob;
406
407 g_return_val_if_fail (info != NULL, 0);
408 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
409
410 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
411
412 return blob->n_methods;
413 }
414
415 /**
416 * gi_object_info_get_method:
417 * @info: a #GIObjectInfo
418 * @n: index of method to get
419 *
420 * Obtain an object type method at index @n.
421 *
422 * Returns: (transfer full): The [class@GIRepository.FunctionInfo]. Free the
423 * struct by calling [method@GIRepository.BaseInfo.unref] when done.
424 * Since: 2.80
425 */
426 GIFunctionInfo *
427 gi_object_info_get_method (GIObjectInfo *info,
428 guint n)
429 {
430 gint offset;
431 GIRealInfo *rinfo = (GIRealInfo *)info;
432 Header *header;
433 ObjectBlob *blob;
434
435 g_return_val_if_fail (info != NULL, NULL);
436 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
437
438 header = (Header *)rinfo->typelib->data;
439 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
440
441
442 offset = rinfo->offset + header->object_blob_size
443 + (blob->n_interfaces + blob->n_interfaces % 2) * 2
444 + blob->n_fields * header->field_blob_size
445 + blob->n_field_callbacks * header->callback_blob_size
446 + blob->n_properties * header->property_blob_size
447 + n * header->function_blob_size;
448
449 return (GIFunctionInfo *) gi_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
450 rinfo->typelib, offset);
451 }
452
453 /**
454 * gi_object_info_find_method:
455 * @info: a #GIObjectInfo
456 * @name: name of method to obtain
457 *
458 * Obtain a method of the object type given a @name.
459 *
460 * `NULL` will be returned if there’s no method available with that name.
461 *
462 * Returns: (transfer full) (nullable): The [class@GIRepository.FunctionInfo],
463 * or `NULL` if no method could be found. Free the struct by calling
464 * [method@GIRepository.BaseInfo.unref] when done.
465 * Since: 2.80
466 */
467 GIFunctionInfo *
468 gi_object_info_find_method (GIObjectInfo *info,
469 const gchar *name)
470 {
471 gint offset;
472 GIRealInfo *rinfo = (GIRealInfo *)info;
473 Header *header;
474 ObjectBlob *blob;
475
476 g_return_val_if_fail (info != NULL, 0);
477 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
478
479 header = (Header *)rinfo->typelib->data;
480 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
481
482 offset = rinfo->offset + header->object_blob_size
483 + (blob->n_interfaces + blob->n_interfaces % 2) * 2
484 + blob->n_fields * header->field_blob_size +
485 + blob->n_field_callbacks * header->callback_blob_size
486 + blob->n_properties * header->property_blob_size;
487
488 return gi_base_info_find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
489 }
490
491 /**
492 * gi_object_info_find_method_using_interfaces:
493 * @info: a #GIObjectInfo
494 * @name: name of method to obtain
495 * @implementor: (out) (transfer full) (optional) (nullable): The implementor of
496 * the interface, or `NULL` to ignore. If no method is found, this will return
497 * `NULL`.
498 *
499 * Obtain a method of the object given a @name, searching both the
500 * object @info and any interfaces it implements.
501 *
502 * `NULL` will be returned if there’s no method available with that name.
503 *
504 * Note that this function does *not* search parent classes; you will have
505 * to chain up if that’s desired.
506 *
507 * Returns: (transfer full) (nullable): The [class@GIRepository.FunctionInfo],
508 * or `NULL` if none was found. Free the struct by calling
509 * [method@GIRepository.BaseInfo.unref] when done.
510 * Since: 2.80
511 */
512 GIFunctionInfo *
513 gi_object_info_find_method_using_interfaces (GIObjectInfo *info,
514 const gchar *name,
515 GIObjectInfo **implementor)
516 {
517 GIFunctionInfo *result = NULL;
518 GIObjectInfo *implementor_result = NULL;
519
520 result = gi_object_info_find_method (info, name);
521 if (result)
522 implementor_result = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo*) info);
523
524 if (result == NULL)
525 {
526 int n_interfaces;
527 int i;
528
529 n_interfaces = gi_object_info_get_n_interfaces (info);
530 for (i = 0; i < n_interfaces; ++i)
531 {
532 GIInterfaceInfo *iface_info;
533
534 iface_info = gi_object_info_get_interface (info, i);
535
536 result = gi_interface_info_find_method (iface_info, name);
537
538 if (result != NULL)
539 {
540 implementor_result = (GIObjectInfo *) iface_info;
541 break;
542 }
543 gi_base_info_unref ((GIBaseInfo*) iface_info);
544 }
545 }
546 if (implementor)
547 *implementor = implementor_result;
548 else if (implementor_result != NULL)
549 gi_base_info_unref ((GIBaseInfo*) implementor_result);
550 return result;
551 }
552
553 /**
554 * gi_object_info_get_n_signals:
555 * @info: a #GIObjectInfo
556 *
557 * Obtain the number of signals that this object type has.
558 *
559 * Returns: number of signals
560 * Since: 2.80
561 */
562 guint
563 gi_object_info_get_n_signals (GIObjectInfo *info)
564 {
565 GIRealInfo *rinfo = (GIRealInfo *)info;
566 ObjectBlob *blob;
567
568 g_return_val_if_fail (info != NULL, 0);
569 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
570
571 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
572
573 return blob->n_signals;
574 }
575
576 /**
577 * gi_object_info_get_signal:
578 * @info: a #GIObjectInfo
579 * @n: index of signal to get
580 *
581 * Obtain an object type signal at index @n.
582 *
583 * Returns: (transfer full): The [class@GIRepository.SignalInfo]. Free the
584 * struct by calling [method@GIRepository.BaseInfo.unref] when done.
585 * Since: 2.80
586 */
587 GISignalInfo *
588 gi_object_info_get_signal (GIObjectInfo *info,
589 guint n)
590 {
591 gint offset;
592 GIRealInfo *rinfo = (GIRealInfo *)info;
593 Header *header;
594 ObjectBlob *blob;
595
596 g_return_val_if_fail (info != NULL, NULL);
597 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
598
599 header = (Header *)rinfo->typelib->data;
600 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
601
602 offset = rinfo->offset + header->object_blob_size
603 + (blob->n_interfaces + blob->n_interfaces % 2) * 2
604 + blob->n_fields * header->field_blob_size
605 + blob->n_field_callbacks * header->callback_blob_size
606 + blob->n_properties * header->property_blob_size
607 + blob->n_methods * header->function_blob_size
608 + n * header->signal_blob_size;
609
610 return (GISignalInfo *) gi_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
611 rinfo->typelib, offset);
612 }
613
614 /**
615 * gi_object_info_find_signal:
616 * @info: a #GIObjectInfo
617 * @name: name of signal
618 *
619 * Obtain a signal of the object type given a @name.
620 *
621 * `NULL` will be returned if there’s no signal available with that name.
622 *
623 * Returns: (transfer full) (nullable): The [class@GIRepository.SignalInfo],
624 * or `NULL` if no signal could be found. Free the struct by calling
625 * [method@GIRepository.BaseInfo.unref] when done.
626 * Since: 2.80
627 */
628 GISignalInfo *
629 gi_object_info_find_signal (GIObjectInfo *info,
630 const gchar *name)
631 {
632 guint n_signals;
633
634 n_signals = gi_object_info_get_n_signals (info);
635 for (guint i = 0; i < n_signals; i++)
636 {
637 GISignalInfo *siginfo = gi_object_info_get_signal (info, i);
638
639 if (g_strcmp0 (gi_base_info_get_name ((GIBaseInfo *) siginfo), name) != 0)
640 {
641 gi_base_info_unref ((GIBaseInfo*)siginfo);
642 continue;
643 }
644
645 return siginfo;
646 }
647 return NULL;
648 }
649
650
651 /**
652 * gi_object_info_get_n_vfuncs:
653 * @info: a #GIObjectInfo
654 *
655 * Obtain the number of virtual functions that this object type has.
656 *
657 * Returns: number of virtual functions
658 * Since: 2.80
659 */
660 guint
661 gi_object_info_get_n_vfuncs (GIObjectInfo *info)
662 {
663 GIRealInfo *rinfo = (GIRealInfo *)info;
664 ObjectBlob *blob;
665
666 g_return_val_if_fail (info != NULL, 0);
667 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
668
669 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
670
671 return blob->n_vfuncs;
672 }
673
674 /**
675 * gi_object_info_get_vfunc:
676 * @info: a #GIObjectInfo
677 * @n: index of virtual function to get
678 *
679 * Obtain an object type virtual function at index @n.
680 *
681 * Returns: (transfer full): The [class@GIRepository.VFuncInfo]. Free the struct
682 * by calling [method@GIRepository.BaseInfo.unref] when done.
683 * Since: 2.80
684 */
685 GIVFuncInfo *
686 gi_object_info_get_vfunc (GIObjectInfo *info,
687 guint n)
688 {
689 gint offset;
690 GIRealInfo *rinfo = (GIRealInfo *)info;
691 Header *header;
692 ObjectBlob *blob;
693
694 g_return_val_if_fail (info != NULL, NULL);
695 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
696
697 header = (Header *)rinfo->typelib->data;
698 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
699
700 offset = rinfo->offset + header->object_blob_size
701 + (blob->n_interfaces + blob->n_interfaces % 2) * 2
702 + blob->n_fields * header->field_blob_size
703 + blob->n_field_callbacks * header->callback_blob_size
704 + blob->n_properties * header->property_blob_size
705 + blob->n_methods * header->function_blob_size
706 + blob->n_signals * header->signal_blob_size
707 + n * header->vfunc_blob_size;
708
709 return (GIVFuncInfo *) gi_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
710 rinfo->typelib, offset);
711 }
712
713 /**
714 * gi_object_info_find_vfunc:
715 * @info: a #GIObjectInfo
716 * @name: the name of a virtual function to find.
717 *
718 * Locate a virtual function slot with name @name.
719 *
720 * Note that the namespace for virtuals is distinct from that of methods; there
721 * may or may not be a concrete method associated for a virtual. If there is
722 * one, it may be retrieved using [method@GIRepository.VFuncInfo.get_invoker],
723 * otherwise that method will return `NULL`.
724 *
725 * See the documentation for [method@GIRepository.VFuncInfo.get_invoker] for
726 * more information on invoking virtuals.
727 *
728 * Returns: (transfer full) (nullable): The [class@GIRepository.VFuncInfo], or
729 * `NULL` if none is found. Free it with [method@GIRepository.BaseInfo.unref]
730 * when done.
731 * Since: 2.80
732 */
733 GIVFuncInfo *
734 gi_object_info_find_vfunc (GIObjectInfo *info,
735 const gchar *name)
736 {
737 gint offset;
738 GIRealInfo *rinfo = (GIRealInfo *)info;
739 Header *header;
740 ObjectBlob *blob;
741
742 g_return_val_if_fail (info != NULL, NULL);
743 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
744
745 header = (Header *)rinfo->typelib->data;
746 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
747
748 offset = rinfo->offset + header->object_blob_size
749 + (blob->n_interfaces + blob->n_interfaces % 2) * 2
750 + blob->n_fields * header->field_blob_size
751 + blob->n_field_callbacks * header->callback_blob_size
752 + blob->n_properties * header->property_blob_size
753 + blob->n_methods * header->function_blob_size
754 + blob->n_signals * header->signal_blob_size;
755
756 return gi_base_info_find_vfunc (rinfo, offset, blob->n_vfuncs, name);
757 }
758
759 /**
760 * gi_object_info_find_vfunc_using_interfaces:
761 * @info: a #GIObjectInfo
762 * @name: name of vfunc to obtain
763 * @implementor: (out) (transfer full) (optional) (nullable): The implementor of
764 * the interface, or `NULL` to ignore. If no vfunc is found, this will return
765 * `NULL`.
766 *
767 * Locate a virtual function slot with name @name, searching both the object
768 * @info and any interfaces it implements.
769 *
770 * `NULL` will be returned if there’s no vfunc available with that name.
771 *
772 * Note that the namespace for virtuals is distinct from that of methods; there
773 * may or may not be a concrete method associated for a virtual. If there is
774 * one, it may be retrieved using [method@GIRepository.VFuncInfo.get_invoker],
775 * otherwise that method will return `NULL`.
776 *
777 * Note that this function does *not* search parent classes; you will have
778 * to chain up if that’s desired.
779 *
780 * Returns: (transfer full) (nullable): The [class@GIRepository.VFuncInfo],
781 * or `NULL` if none was found. Free the struct by calling
782 * [method@GIRepository.BaseInfo.unref] when done.
783 * Since: 2.80
784 */
785 GIVFuncInfo *
786 gi_object_info_find_vfunc_using_interfaces (GIObjectInfo *info,
787 const gchar *name,
788 GIObjectInfo **implementor)
789 {
790 GIVFuncInfo *result = NULL;
791 GIObjectInfo *implementor_result = NULL;
792
793 result = gi_object_info_find_vfunc (info, name);
794 if (result)
795 implementor_result = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo*) info);
796
797 if (result == NULL)
798 {
799 int n_interfaces;
800 int i;
801
802 n_interfaces = gi_object_info_get_n_interfaces (info);
803 for (i = 0; i < n_interfaces; ++i)
804 {
805 GIInterfaceInfo *iface_info;
806
807 iface_info = gi_object_info_get_interface (info, i);
808
809 result = gi_interface_info_find_vfunc (iface_info, name);
810
811 if (result != NULL)
812 {
813 implementor_result = (GIObjectInfo *) iface_info;
814 break;
815 }
816 gi_base_info_unref ((GIBaseInfo*) iface_info);
817 }
818 }
819 if (implementor)
820 *implementor = implementor_result;
821 else if (implementor_result != NULL)
822 gi_base_info_unref ((GIBaseInfo*) implementor_result);
823 return result;
824 }
825
826 /**
827 * gi_object_info_get_n_constants:
828 * @info: a #GIObjectInfo
829 *
830 * Obtain the number of constants that this object type has.
831 *
832 * Returns: number of constants
833 * Since: 2.80
834 */
835 guint
836 gi_object_info_get_n_constants (GIObjectInfo *info)
837 {
838 GIRealInfo *rinfo = (GIRealInfo *)info;
839 ObjectBlob *blob;
840
841 g_return_val_if_fail (info != NULL, 0);
842 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), 0);
843
844 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
845
846 return blob->n_constants;
847 }
848
849 /**
850 * gi_object_info_get_constant:
851 * @info: a #GIObjectInfo
852 * @n: index of constant to get
853 *
854 * Obtain an object type constant at index @n.
855 *
856 * Returns: (transfer full): The [class@GIRepository.ConstantInfo]. Free the
857 * struct by calling [method@GIRepository.BaseInfo.unref] when done.
858 * Since: 2.80
859 */
860 GIConstantInfo *
861 gi_object_info_get_constant (GIObjectInfo *info,
862 guint n)
863 {
864 gint offset;
865 GIRealInfo *rinfo = (GIRealInfo *)info;
866 Header *header;
867 ObjectBlob *blob;
868
869 g_return_val_if_fail (info != NULL, NULL);
870 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
871
872 header = (Header *)rinfo->typelib->data;
873 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
874
875 offset = rinfo->offset + header->object_blob_size
876 + (blob->n_interfaces + blob->n_interfaces % 2) * 2
877 + blob->n_fields * header->field_blob_size
878 + blob->n_field_callbacks * header->callback_blob_size
879 + blob->n_properties * header->property_blob_size
880 + blob->n_methods * header->function_blob_size
881 + blob->n_signals * header->signal_blob_size
882 + blob->n_vfuncs * header->vfunc_blob_size
883 + n * header->constant_blob_size;
884
885 return (GIConstantInfo *) gi_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
886 rinfo->typelib, offset);
887 }
888
889 /**
890 * gi_object_info_get_class_struct:
891 * @info: a #GIObjectInfo
892 *
893 * Every [class@GObject.Object] has two structures; an instance structure and a
894 * class structure. This function returns the metadata for the class structure.
895 *
896 * Returns: (transfer full) (nullable): The [class@GIRepository.StructInfo] or
897 * `NULL` if it’s unknown. Free with [method@GIRepository.BaseInfo.unref] when
898 * done.
899 * Since: 2.80
900 */
901 GIStructInfo *
902 gi_object_info_get_class_struct (GIObjectInfo *info)
903 {
904 GIRealInfo *rinfo = (GIRealInfo *)info;
905 ObjectBlob *blob;
906
907 g_return_val_if_fail (info != NULL, NULL);
908 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
909
910 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
911
912 if (blob->gtype_struct)
913 return (GIStructInfo *) gi_info_from_entry (rinfo->repository,
914 rinfo->typelib, blob->gtype_struct);
915 else
916 return NULL;
917 }
918
919 typedef const char* (*SymbolGetter) (GIObjectInfo *info);
920
921 static void *
922 _get_func(GIObjectInfo *info,
923 SymbolGetter getter)
924 {
925 const char* symbol;
926 GSList *parents = NULL, *l;
927 GIObjectInfo *parent_info;
928 gpointer func = NULL;
929
930 parent_info = (GIObjectInfo *) gi_base_info_ref ((GIBaseInfo *) info);
931 while (parent_info != NULL)
932 {
933 parents = g_slist_prepend (parents, parent_info);
934 parent_info = gi_object_info_get_parent (parent_info);
935 }
936
937 for (l = parents; l; l = l->next)
938 {
939 parent_info = l->data;
940 symbol = getter (parent_info);
941 if (symbol == NULL)
942 continue;
943
944 gi_typelib_symbol (((GIRealInfo *)parent_info)->typelib, symbol, (gpointer*) &func);
945 if (func)
946 break;
947 }
948
949 g_slist_free_full (parents, (GDestroyNotify) gi_base_info_unref);
950 return func;
951 }
952
953 /**
954 * gi_object_info_get_ref_function_name:
955 * @info: a #GIObjectInfo
956 *
957 * Obtain the symbol name of the function that should be called to ref this
958 * object type.
959 *
960 * It’s mainly used for fundamental types. The type signature for
961 * the symbol is [type@GIRepository.ObjectInfoRefFunction]. To fetch the
962 * function pointer see
963 * [method@GIRepository.ObjectInfo.get_ref_function_pointer].
964 *
965 * Returns: (nullable): the symbol, or `NULL` if the object type has no ref
966 * function
967 * Since: 2.80
968 */
969 const char *
970 gi_object_info_get_ref_function_name (GIObjectInfo *info)
971 {
972 GIRealInfo *rinfo = (GIRealInfo *)info;
973 ObjectBlob *blob;
974
975 g_return_val_if_fail (info != NULL, NULL);
976 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
977
978 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
979
980 if (blob->ref_func)
981 return gi_typelib_get_string (rinfo->typelib, blob->ref_func);
982
983 return NULL;
984 }
985
986 /**
987 * gi_object_info_get_ref_function_pointer: (skip)
988 * @info: a #GIObjectInfo
989 *
990 * Obtain a pointer to a function which can be used to
991 * increase the reference count an instance of this object type.
992 *
993 * This takes derivation into account and will reversely traverse
994 * the base classes of this type, starting at the top type.
995 *
996 * Returns: (nullable): the function pointer, or `NULL` if the object type has
997 * no ref function
998 * Since: 2.80
999 */
1000 GIObjectInfoRefFunction
1001 gi_object_info_get_ref_function_pointer (GIObjectInfo *info)
1002 {
1003 g_return_val_if_fail (info != NULL, NULL);
1004 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
1005
1006 return (GIObjectInfoRefFunction)_get_func(info, (SymbolGetter)gi_object_info_get_ref_function_name);
1007 }
1008
1009 /**
1010 * gi_object_info_get_unref_function_name:
1011 * @info: a #GIObjectInfo
1012 *
1013 * Obtain the symbol name of the function that should be called to unref this
1014 * object type.
1015 *
1016 * It’s mainly used for fundamental types. The type signature for the symbol is
1017 * [type@GIRepository.ObjectInfoUnrefFunction]. To fetch the function pointer
1018 * see [method@GIRepository.ObjectInfo.get_unref_function_pointer].
1019 *
1020 * Returns: (nullable): the symbol, or `NULL` if the object type has no unref
1021 * function
1022 * Since: 2.80
1023 */
1024 const char *
1025 gi_object_info_get_unref_function_name (GIObjectInfo *info)
1026 {
1027 GIRealInfo *rinfo = (GIRealInfo *)info;
1028 ObjectBlob *blob;
1029
1030 g_return_val_if_fail (info != NULL, NULL);
1031 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
1032
1033 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1034
1035 if (blob->unref_func)
1036 return gi_typelib_get_string (rinfo->typelib, blob->unref_func);
1037
1038 return NULL;
1039 }
1040
1041 /**
1042 * gi_object_info_get_unref_function_pointer: (skip)
1043 * @info: a #GIObjectInfo
1044 *
1045 * Obtain a pointer to a function which can be used to
1046 * decrease the reference count an instance of this object type.
1047 *
1048 * This takes derivation into account and will reversely traverse
1049 * the base classes of this type, starting at the top type.
1050 *
1051 * Returns: (nullable): the function pointer, or `NULL` if the object type has
1052 * no unref function
1053 * Since: 2.80
1054 */
1055 GIObjectInfoUnrefFunction
1056 gi_object_info_get_unref_function_pointer (GIObjectInfo *info)
1057 {
1058 g_return_val_if_fail (info != NULL, NULL);
1059 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
1060
1061 return (GIObjectInfoUnrefFunction)_get_func(info, (SymbolGetter)gi_object_info_get_unref_function_name);
1062 }
1063
1064 /**
1065 * gi_object_info_get_set_value_function_name:
1066 * @info: a #GIObjectInfo
1067 *
1068 * Obtain the symbol name of the function that should be called to set a
1069 * [type@GObject.Value], given an object instance pointer of this object type.
1070 *
1071 * It’s mainly used for fundamental types. The type signature for the symbol
1072 * is [type@GIRepository.ObjectInfoSetValueFunction]. To fetch the function
1073 * pointer see [method@GIRepository.ObjectInfo.get_set_value_function_pointer].
1074 *
1075 * Returns: (nullable): the symbol, or `NULL` if the object type has no
1076 * set-value function
1077 * Since: 2.80
1078 */
1079 const char *
1080 gi_object_info_get_set_value_function_name (GIObjectInfo *info)
1081 {
1082 GIRealInfo *rinfo = (GIRealInfo *)info;
1083 ObjectBlob *blob;
1084
1085 g_return_val_if_fail (info != NULL, NULL);
1086 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
1087
1088 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1089
1090 if (blob->set_value_func)
1091 return gi_typelib_get_string (rinfo->typelib, blob->set_value_func);
1092
1093 return NULL;
1094 }
1095
1096 /**
1097 * gi_object_info_get_set_value_function_pointer: (skip)
1098 * @info: a #GIObjectInfo
1099 *
1100 * Obtain a pointer to a function which can be used to set a
1101 * [type@GObject.Value], given an instance of this object type.
1102 *
1103 * This takes derivation into account and will reversely traverse
1104 * the base classes of this type, starting at the top type.
1105 *
1106 * Returns: (nullable): the function pointer, or `NULL` if the object type has
1107 * no set-value function
1108 * Since: 2.80
1109 */
1110 GIObjectInfoSetValueFunction
1111 gi_object_info_get_set_value_function_pointer (GIObjectInfo *info)
1112 {
1113 g_return_val_if_fail (info != NULL, NULL);
1114 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
1115
1116 return (GIObjectInfoSetValueFunction)_get_func(info, (SymbolGetter)gi_object_info_get_set_value_function_name);
1117 }
1118
1119 /**
1120 * gi_object_info_get_get_value_function_name:
1121 * @info: a #GIObjectInfo
1122 *
1123 * Obtain the symbol name of the function that should be called to convert
1124 * an object instance pointer of this object type to a [type@GObject.Value].
1125 *
1126 * It’s mainly used for fundamental types. The type signature for the symbol
1127 * is [type@GIRepository.ObjectInfoGetValueFunction]. To fetch the function
1128 * pointer see [method@GIRepository.ObjectInfo.get_get_value_function_pointer].
1129 *
1130 * Returns: (nullable): the symbol, or `NULL` if the object type has no
1131 * get-value function
1132 * Since: 2.80
1133 */
1134 const char *
1135 gi_object_info_get_get_value_function_name (GIObjectInfo *info)
1136 {
1137 GIRealInfo *rinfo = (GIRealInfo *)info;
1138 ObjectBlob *blob;
1139
1140 g_return_val_if_fail (info != NULL, NULL);
1141 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
1142
1143 blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1144
1145 if (blob->get_value_func)
1146 return gi_typelib_get_string (rinfo->typelib, blob->get_value_func);
1147
1148 return NULL;
1149 }
1150
1151 /**
1152 * gi_object_info_get_get_value_function_pointer: (skip)
1153 * @info: a #GIObjectInfo
1154 *
1155 * Obtain a pointer to a function which can be used to extract an instance of
1156 * this object type out of a [type@GObject.Value].
1157 *
1158 * This takes derivation into account and will reversely traverse
1159 * the base classes of this type, starting at the top type.
1160 *
1161 * Returns: (nullable): the function pointer, or `NULL` if the object type has
1162 * no get-value function
1163 * Since: 2.80
1164 */
1165 GIObjectInfoGetValueFunction
1166 gi_object_info_get_get_value_function_pointer (GIObjectInfo *info)
1167 {
1168 g_return_val_if_fail (info != NULL, NULL);
1169 g_return_val_if_fail (GI_IS_OBJECT_INFO (info), NULL);
1170
1171 return (GIObjectInfoGetValueFunction)_get_func(info, (SymbolGetter)gi_object_info_get_get_value_function_name);
1172 }
1173
1174 void
1175 gi_object_info_class_init (gpointer g_class,
1176 gpointer class_data)
1177 {
1178 GIBaseInfoClass *info_class = g_class;
1179
1180 info_class->info_type = GI_INFO_TYPE_OBJECT;
1181 }