Add support for foreign structs
[gnome.gobject-introspection] / girepository / ginfo.c
1 /* GObject introspection: Repository implementation
2  *
3  * Copyright (C) 2005 Matthias Clasen
4  * Copyright (C) 2008,2009 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include <glib.h>
26 #include <glib-object.h>
27
28 #include "gtypelib.h"
29 #include "ginfo.h"
30
31 typedef struct _GIRealInfo GIRealInfo;
32
33 /**
34  * We just use one structure for all of the info object
35  * types; in general, we should be reading data directly
36  * from the typelib, and not having computed data in
37  * per-type structures.
38  */
39 struct _GIRealInfo
40 {
41   /* Keep this part in sync with GIUnresolvedInfo below */
42   gint32 type;
43   gint32 ref_count;
44   GIRepository *repository;
45   GIBaseInfo *container;
46
47   /* Resolved specific */
48
49   GTypelib *typelib;
50   guint32 offset;
51
52   guint32 type_is_embedded : 1; /* Used by GITypeInfo */
53   guint32 reserved : 31;
54
55   gpointer reserved2[4];
56 };
57
58 struct _GIUnresolvedInfo
59 {
60   /* Keep this part in sync with GIBaseInfo above */
61   gint32 type;
62   gint32 ref_count;
63   GIRepository *repository;
64   GIBaseInfo *container;
65
66   /* Unresolved specific */
67
68   const gchar *name;
69   const gchar *namespace;
70 };
71
72 #define INVALID_REFCOUNT 0x7FFFFFFF
73
74 static void
75 g_info_init (GIRealInfo     *info,
76              GIInfoType      type,
77              GIRepository   *repository,
78              GIBaseInfo     *container,
79              GTypelib       *typelib,
80              guint32         offset)
81 {
82   memset (info, 0, sizeof (GIRealInfo));
83
84   /* Invalid refcount used to flag stack-allocated infos */
85   info->ref_count = INVALID_REFCOUNT;
86   info->type = type;
87
88   info->typelib = typelib;
89   info->offset = offset;
90
91   if (container)
92     info->container = container;
93
94   g_assert (G_IS_IREPOSITORY (repository));
95   info->repository = repository;
96 }
97
98 /* info creation */
99 GIBaseInfo *
100 g_info_new_full (GIInfoType     type,
101                  GIRepository  *repository,
102                  GIBaseInfo    *container,
103                  GTypelib      *typelib,
104                  guint32        offset)
105 {
106   GIRealInfo *info;
107
108   g_return_val_if_fail (container != NULL || repository != NULL, NULL);
109
110   info = g_new (GIRealInfo, 1);
111
112   g_info_init (info, type, repository, container, typelib, offset);
113   info->ref_count = 1;
114
115   if (container && ((GIRealInfo *) container)->ref_count != INVALID_REFCOUNT)
116     g_base_info_ref (info->container);
117
118   g_object_ref (info->repository);
119
120   return (GIBaseInfo*)info;
121 }
122
123 GIBaseInfo *
124 g_info_new (GIInfoType     type,
125             GIBaseInfo    *container,
126             GTypelib      *typelib,
127             guint32        offset)
128 {
129   return g_info_new_full (type, ((GIRealInfo*)container)->repository, container, typelib, offset);
130 }
131
132 static GIBaseInfo *
133 g_info_from_entry (GIRepository *repository,
134                    GTypelib     *typelib,
135                    guint16       index)
136 {
137   GIBaseInfo *result;
138   DirEntry *entry = g_typelib_get_dir_entry (typelib, index);
139
140   if (entry->local)
141     result = g_info_new_full (entry->blob_type, repository, NULL, typelib, entry->offset);
142   else
143     {
144       const gchar *namespace = g_typelib_get_string (typelib, entry->offset);
145       const gchar *name = g_typelib_get_string (typelib, entry->name);
146
147       result = g_irepository_find_by_name (repository, namespace, name);
148       if (result == NULL)
149         {
150           GIUnresolvedInfo *unresolved;
151
152           unresolved = g_new0 (GIUnresolvedInfo, 1);
153
154           unresolved->type = GI_INFO_TYPE_UNRESOLVED;
155           unresolved->ref_count = 1;
156           unresolved->repository = g_object_ref (repository);
157           unresolved->container = NULL;
158           unresolved->name = name;
159           unresolved->namespace = namespace;
160
161           return (GIBaseInfo *)unresolved;
162             }
163       return (GIBaseInfo *)result;
164     }
165
166   return (GIBaseInfo *)result;
167 }
168
169 /* GIBaseInfo functions */
170 GIBaseInfo *
171 g_base_info_ref (GIBaseInfo *info)
172 {
173   GIRealInfo *rinfo = (GIRealInfo*)info;
174
175   g_assert (rinfo->ref_count != INVALID_REFCOUNT);
176   ((GIRealInfo*)info)->ref_count++;
177
178   return info;
179 }
180
181 void
182 g_base_info_unref (GIBaseInfo *info)
183 {
184   GIRealInfo *rinfo = (GIRealInfo*)info;
185
186   g_assert (rinfo->ref_count > 0 && rinfo->ref_count != INVALID_REFCOUNT);
187   rinfo->ref_count--;
188
189   if (!rinfo->ref_count)
190     {
191       if (rinfo->container && ((GIRealInfo *) rinfo->container)->ref_count != INVALID_REFCOUNT)
192         g_base_info_unref (rinfo->container);
193
194       if (rinfo->repository)
195         g_object_unref (rinfo->repository);
196
197       g_free (rinfo);
198     }
199 }
200
201 GIInfoType
202 g_base_info_get_type (GIBaseInfo *info)
203 {
204
205   return ((GIRealInfo*)info)->type;
206 }
207
208 const gchar *
209 g_base_info_get_name (GIBaseInfo *info)
210 {
211   GIRealInfo *rinfo = (GIRealInfo*)info;
212   g_assert (rinfo->ref_count > 0);
213   switch (rinfo->type)
214     {
215     case GI_INFO_TYPE_FUNCTION:
216     case GI_INFO_TYPE_CALLBACK:
217     case GI_INFO_TYPE_STRUCT:
218     case GI_INFO_TYPE_BOXED:
219     case GI_INFO_TYPE_ENUM:
220     case GI_INFO_TYPE_FLAGS:
221     case GI_INFO_TYPE_OBJECT:
222     case GI_INFO_TYPE_INTERFACE:
223     case GI_INFO_TYPE_CONSTANT:
224     case GI_INFO_TYPE_ERROR_DOMAIN:
225     case GI_INFO_TYPE_UNION:
226       {
227         CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
228
229         return g_typelib_get_string (rinfo->typelib, blob->name);
230       }
231       break;
232
233     case GI_INFO_TYPE_VALUE:
234       {
235         ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
236
237         return g_typelib_get_string (rinfo->typelib, blob->name);
238       }
239       break;
240
241     case GI_INFO_TYPE_SIGNAL:
242       {
243         SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
244
245         return g_typelib_get_string (rinfo->typelib, blob->name);
246       }
247       break;
248
249     case GI_INFO_TYPE_PROPERTY:
250       {
251         PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
252
253         return g_typelib_get_string (rinfo->typelib, blob->name);
254       }
255       break;
256
257     case GI_INFO_TYPE_VFUNC:
258       {
259         VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
260
261         return g_typelib_get_string (rinfo->typelib, blob->name);
262       }
263       break;
264
265     case GI_INFO_TYPE_FIELD:
266       {
267         FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
268
269         return g_typelib_get_string (rinfo->typelib, blob->name);
270       }
271       break;
272
273     case GI_INFO_TYPE_ARG:
274       {
275         ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
276
277         return g_typelib_get_string (rinfo->typelib, blob->name);
278       }
279       break;
280     case GI_INFO_TYPE_UNRESOLVED:
281       {
282         GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
283
284         return unresolved->name;
285       }
286       break;
287     case GI_INFO_TYPE_TYPE:
288     default: ;
289       g_assert_not_reached ();
290       /* unnamed */
291     }
292
293   return NULL;
294 }
295
296 const gchar *
297 g_base_info_get_namespace (GIBaseInfo *info)
298 {
299   GIRealInfo *rinfo = (GIRealInfo*) info;
300   Header *header = (Header *)rinfo->typelib->data;
301
302   g_assert (rinfo->ref_count > 0);
303
304   if (rinfo->type == GI_INFO_TYPE_UNRESOLVED)
305     {
306       GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
307
308       return unresolved->namespace;
309     }
310
311   return g_typelib_get_string (rinfo->typelib, header->namespace);
312 }
313
314 gboolean
315 g_base_info_is_deprecated (GIBaseInfo *info)
316 {
317   GIRealInfo *rinfo = (GIRealInfo*) info;
318   switch (rinfo->type)
319     {
320     case GI_INFO_TYPE_FUNCTION:
321     case GI_INFO_TYPE_CALLBACK:
322     case GI_INFO_TYPE_STRUCT:
323     case GI_INFO_TYPE_BOXED:
324     case GI_INFO_TYPE_ENUM:
325     case GI_INFO_TYPE_FLAGS:
326     case GI_INFO_TYPE_OBJECT:
327     case GI_INFO_TYPE_INTERFACE:
328     case GI_INFO_TYPE_CONSTANT:
329     case GI_INFO_TYPE_ERROR_DOMAIN:
330       {
331         CommonBlob *blob = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
332
333         return blob->deprecated;
334       }
335       break;
336
337     case GI_INFO_TYPE_VALUE:
338       {
339         ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
340
341         return blob->deprecated;
342       }
343       break;
344
345     case GI_INFO_TYPE_SIGNAL:
346       {
347         SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
348
349         return blob->deprecated;
350       }
351       break;
352
353     case GI_INFO_TYPE_PROPERTY:
354       {
355         PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
356
357         return blob->deprecated;
358       }
359       break;
360
361     case GI_INFO_TYPE_VFUNC:
362     case GI_INFO_TYPE_FIELD:
363     case GI_INFO_TYPE_ARG:
364     case GI_INFO_TYPE_TYPE:
365     default: ;
366       /* no deprecation flag for these */
367     }
368
369   return FALSE;
370 }
371
372 /**
373  * g_base_info_get_attribute:
374  * @info: A #GIBaseInfo
375  * @name: A freeform string naming an attribute
376  *
377  * Retrieve an arbitrary attribute associated with this node.
378  *
379  * Return value: The value of the attribute, or %NULL if no such attribute exists
380  */
381 const gchar *
382 g_base_info_get_attribute (GIBaseInfo   *info,
383                            const gchar  *name)
384 {
385   GIAttributeIter iter = { 0, };
386   gchar *curname, *curvalue;
387   while (g_base_info_iterate_attributes (info, &iter, &curname, &curvalue))
388     {
389       if (strcmp (name, curname) == 0)
390         return (const gchar*) curvalue;
391     }
392
393   return NULL;
394 }
395
396 static int
397 cmp_attribute (const void *av,
398                 const void *bv)
399 {
400   const AttributeBlob *a = av;
401   const AttributeBlob *b = bv;
402
403   if (a->offset < b->offset)
404     return -1;
405   else if (a->offset == b->offset)
406     return 0;
407   else
408     return 1;
409 }
410
411 static AttributeBlob *
412 find_first_attribute (GIRealInfo *rinfo)
413 {
414   Header *header = (Header *)rinfo->typelib->data;
415   AttributeBlob blob, *first, *res, *previous;
416
417   blob.offset = rinfo->offset;
418
419   first = (AttributeBlob *) &rinfo->typelib->data[header->attributes];
420
421   res = bsearch (&blob, first, header->n_attributes,
422                  header->attribute_blob_size, cmp_attribute);
423
424   if (res == NULL)
425     return NULL;
426
427   previous = res - 1;
428   while (previous >= first && previous->offset == rinfo->offset)
429     {
430       res = previous;
431       previous = res - 1;
432     }
433
434   return res;
435 }
436
437 /**
438  * g_base_info_iterate_attributes:
439  * @info: A #GIBaseInfo
440  * @iter: A #GIAttributeIter structure, must be initialized; see below
441  * @name: (out) (transfer none): Returned name, must not be freed
442  * @value: (out) (transfer none): Returned name, must not be freed
443  *
444  * Iterate over all attributes associated with this node.  The iterator
445  * structure is typically stack allocated, and must have its first
446  * member initialized to %NULL.
447  *
448  * Both the @name and @value should be treated as constants
449  * and must not be freed.
450  *
451  * <example>
452  * <title>Iterating over attributes</title>
453  * <programlisting>
454  * void
455  * print_attributes (GIBaseInfo *info)
456  * {
457  *   GIAttributeIter iter = { 0, };
458  *   char *name;
459  *   char *value;
460  *   while (g_base_info_iterate_attributes (info, &iter, &name, &value))
461  *     {
462  *       g_print ("attribute name: %s value: %s", name, value);
463  *     }
464  * }
465  * </programlisting>
466  * </example>
467  *
468  * Return value: %TRUE if there are more attributes, %FALSE otherwise
469  */
470 gboolean
471 g_base_info_iterate_attributes (GIBaseInfo       *info,
472                                  GIAttributeIter *iter,
473                                  gchar           **name,
474                                  gchar           **value)
475 {
476   GIRealInfo *rinfo = (GIRealInfo *)info;
477   Header *header = (Header *)rinfo->typelib->data;
478   AttributeBlob *next, *after;
479
480   after = (AttributeBlob *) &rinfo->typelib->data[header->attributes +
481                                                   header->n_attributes * header->attribute_blob_size];
482
483   if (iter->data != NULL)
484     next = (AttributeBlob *) iter->data;
485   else
486     next = find_first_attribute (rinfo);
487
488   if (next == NULL || next->offset != rinfo->offset || next >= after)
489     return FALSE;
490
491   *name = (gchar*) g_typelib_get_string (rinfo->typelib, next->name);
492   *value = (gchar*) g_typelib_get_string (rinfo->typelib, next->value);
493   iter->data = next + 1;
494
495   return TRUE;
496 }
497
498 GIBaseInfo *
499 g_base_info_get_container (GIBaseInfo *info)
500 {
501   return ((GIRealInfo*)info)->container;
502 }
503
504 GTypelib *
505 g_base_info_get_typelib (GIBaseInfo *info)
506 {
507   return ((GIRealInfo*)info)->typelib;
508 }
509
510 /*
511  * g_base_info_equal:
512  * @info1: A #GIBaseInfo
513  * @info2: A #GIBaseInfo
514  *
515  * Compare two #GIBaseInfo.
516  *
517  * Using pointer comparison is not practical since many functions return
518  * different instances of #GIBaseInfo that refers to the same part of the
519  * TypeLib; use this function instead to do #GIBaseInfo comparisons.
520  *
521  * Return value: TRUE if and only if @info1 equals @info2.
522  */
523 gboolean
524 g_base_info_equal (GIBaseInfo *info1, GIBaseInfo *info2)
525 {
526   /* Compare the TypeLib pointers, which are mmapped. */
527   GIRealInfo *rinfo1 = (GIRealInfo*)info1;
528   GIRealInfo *rinfo2 = (GIRealInfo*)info2;
529   return rinfo1->typelib->data + rinfo1->offset == rinfo2->typelib->data + rinfo2->offset;
530 }
531
532 /* GIFunctionInfo functions */
533 const gchar *
534 g_function_info_get_symbol (GIFunctionInfo *info)
535 {
536   GIRealInfo *rinfo = (GIRealInfo *)info;
537   FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset];
538
539   return g_typelib_get_string (rinfo->typelib, blob->symbol);
540 }
541
542 GIFunctionInfoFlags
543 g_function_info_get_flags (GIFunctionInfo *info)
544 {
545   GIFunctionInfoFlags flags;
546   GIRealInfo *rinfo = (GIRealInfo *)info;
547   FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset];
548
549   flags = 0;
550
551   /* Make sure we don't flag Constructors as methods */
552   if (!blob->constructor && !blob->is_static)
553     flags = flags | GI_FUNCTION_IS_METHOD;
554
555   if (blob->constructor)
556     flags = flags | GI_FUNCTION_IS_CONSTRUCTOR;
557
558   if (blob->getter)
559     flags = flags | GI_FUNCTION_IS_GETTER;
560
561   if (blob->setter)
562     flags = flags | GI_FUNCTION_IS_SETTER;
563
564   if (blob->wraps_vfunc)
565     flags = flags | GI_FUNCTION_WRAPS_VFUNC;
566
567   if (blob->throws)
568     flags = flags | GI_FUNCTION_THROWS;
569
570   return flags;
571 }
572
573 GIPropertyInfo *
574 g_function_info_get_property (GIFunctionInfo *info)
575 {
576   GIRealInfo *rinfo = (GIRealInfo *)info;
577   FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset];
578   GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container;
579
580   return g_interface_info_get_property (container, blob->index);
581 }
582
583 GIVFuncInfo *
584 g_function_info_get_vfunc (GIFunctionInfo *info)
585 {
586   GIRealInfo *rinfo = (GIRealInfo*)info;
587   FunctionBlob *blob = (FunctionBlob *)&rinfo->typelib->data[rinfo->offset];
588   GIInterfaceInfo *container = (GIInterfaceInfo *)rinfo->container;
589
590   return g_interface_info_get_vfunc (container, blob->index);
591 }
592
593 /* GICallableInfo functions */
594 static guint32
595 signature_offset (GICallableInfo *info)
596 {
597   GIRealInfo *rinfo = (GIRealInfo*)info;
598   int sigoff = -1;
599
600   switch (rinfo->type)
601     {
602     case GI_INFO_TYPE_FUNCTION:
603       sigoff = G_STRUCT_OFFSET (FunctionBlob, signature);
604       break;
605     case GI_INFO_TYPE_VFUNC:
606       sigoff = G_STRUCT_OFFSET (VFuncBlob, signature);
607       break;
608     case GI_INFO_TYPE_CALLBACK:
609       sigoff = G_STRUCT_OFFSET (CallbackBlob, signature);
610       break;
611     case GI_INFO_TYPE_SIGNAL:
612       sigoff = G_STRUCT_OFFSET (SignalBlob, signature);
613       break;
614     }
615   if (sigoff >= 0)
616     return *(guint32 *)&rinfo->typelib->data[rinfo->offset + sigoff];
617   return 0;
618 }
619
620 GITypeInfo *
621 g_type_info_new (GIBaseInfo    *container,
622                  GTypelib      *typelib,
623                  guint32        offset)
624 {
625   SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset];
626
627   return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib,
628                                     (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset);
629 }
630
631 static void
632 g_type_info_init (GIBaseInfo *info,
633                   GIBaseInfo *container,
634                   GTypelib   *typelib,
635                   guint32     offset)
636 {
637   GIRealInfo *rinfo = (GIRealInfo*)container;
638   SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset];
639
640   g_info_init ((GIRealInfo*)info, GI_INFO_TYPE_TYPE, rinfo->repository, container, typelib,
641                (type->flags.reserved == 0 && type->flags.reserved2 == 0) ? offset : type->offset);
642 }
643
644 /**
645  * g_callable_info_get_return_type:
646  * @info: a #GICallableInfo
647  *
648  * Get the return type of a callable item as
649  * a #GITypeInfo
650  *
651  * Returns: a #GITypeInfo idexing the TypeBlob for the
652  * return type of #info
653  */
654 GITypeInfo *
655 g_callable_info_get_return_type (GICallableInfo *info)
656 {
657   GIRealInfo *rinfo = (GIRealInfo *)info;
658   guint32 offset;
659
660   offset = signature_offset (info);
661
662   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, offset);
663 }
664
665
666 /**
667  * g_callable_info_load_return_type:
668  * @info: a #GICallableInfo
669  * @type: (out caller-allocates): Initialized with return type of @info
670  *
671  * Get information about a return value of callable; this
672  * function is a variant of g_callable_info_get_return_type() designed for stack
673  * allocation.
674  *
675  * The initialized @type must not be referenced after @info is deallocated.
676  */
677 void
678 g_callable_info_load_return_type (GICallableInfo *info,
679                                   GITypeInfo     *type)
680 {
681   GIRealInfo *rinfo = (GIRealInfo *)info;
682   guint32 offset;
683
684   offset = signature_offset (info);
685
686   g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, offset);
687 }
688
689 /**
690  * g_callable_info_may_return_null:
691  * @info: a #GICallableInfo
692  *
693  * See if a callable could return NULL.
694  *
695  * Returns: TRUE if callable could return NULL
696  */
697 gboolean
698 g_callable_info_may_return_null (GICallableInfo *info)
699 {
700   GIRealInfo *rinfo = (GIRealInfo *)info;
701   SignatureBlob *blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)];
702
703   return blob->may_return_null;
704 }
705
706 /**
707  * g_callable_info_get_caller_owns:
708  * @info: a #GICallableInfo
709  *
710  * See whether the caller owns the return value
711  * of this callable.
712  *
713  * Returns: TRUE if the caller owns the return value, FALSE otherwise.
714  */
715 GITransfer
716 g_callable_info_get_caller_owns (GICallableInfo *info)
717 {
718   GIRealInfo *rinfo = (GIRealInfo*) info;
719   SignatureBlob *blob = (SignatureBlob *)&rinfo->typelib->data[signature_offset (info)];
720
721   if (blob->caller_owns_return_value)
722     return GI_TRANSFER_EVERYTHING;
723   else if (blob->caller_owns_return_container)
724     return GI_TRANSFER_CONTAINER;
725   else
726     return GI_TRANSFER_NOTHING;
727 }
728
729 /**
730  * g_callable_info_get_n_args:
731  * @info: a #GICallableInfo
732  *
733  * Get the number of arguments (both IN and OUT) for this callable.
734  *
735  * Returns: The number of arguments this callable expects.
736  */
737 gint
738 g_callable_info_get_n_args (GICallableInfo *info)
739 {
740   GIRealInfo *rinfo = (GIRealInfo *)info;
741   gint offset;
742   SignatureBlob *blob;
743
744   offset = signature_offset (info);
745   blob = (SignatureBlob *)&rinfo->typelib->data[offset];
746
747   return blob->n_arguments;
748 }
749
750 /**
751  * g_callable_info_get_arg:
752  * @info: a #GICallableInfo
753  * @n: the argument index to fetch
754  *
755  * Get information about a particular argument of this callable.
756  *
757  * Returns: A #GIArgInfo indexing the typelib on the given argument.
758  */
759 GIArgInfo *
760 g_callable_info_get_arg (GICallableInfo *info,
761                          gint           n)
762 {
763   GIRealInfo *rinfo = (GIRealInfo *)info;
764   Header *header = (Header *)rinfo->typelib->data;
765   gint offset;
766
767   offset = signature_offset (info);
768
769   return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, (GIBaseInfo*)info, rinfo->typelib,
770                                    offset + header->signature_blob_size + n * header->arg_blob_size);
771 }
772
773 /**
774  * g_callable_info_load_arg:
775  * @info: a #GICallableInfo
776  * @n: the argument index to fetch
777  * @arg: (out caller-allocates): Initialize with argument number @n
778  *
779  * Get information about a particular argument of this callable; this
780  * function is a variant of g_callable_info_get_arg() designed for stack
781  * allocation.
782  *
783  * The initialized @arg must not be referenced after @info is deallocated.
784  */
785 void
786 g_callable_info_load_arg (GICallableInfo *info,
787                           gint            n,
788                           GIArgInfo     *arg)
789 {
790   GIRealInfo *rinfo = (GIRealInfo *)info;
791   Header *header = (Header *)rinfo->typelib->data;
792   gint offset;
793
794   offset = signature_offset (info);
795
796   g_info_init ((GIRealInfo*)arg, GI_INFO_TYPE_ARG, rinfo->repository, (GIBaseInfo*)info, rinfo->typelib,
797                            offset + header->signature_blob_size + n * header->arg_blob_size);
798 }
799
800 /* GIArgInfo function */
801 GIDirection
802 g_arg_info_get_direction (GIArgInfo *info)
803 {
804   GIRealInfo *rinfo = (GIRealInfo *)info;
805   ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
806
807   if (blob->in && blob->out)
808     return GI_DIRECTION_INOUT;
809   else if (blob->out)
810     return GI_DIRECTION_OUT;
811   else
812     return GI_DIRECTION_IN;
813 }
814
815 gboolean
816 g_arg_info_is_return_value (GIArgInfo *info)
817 {
818   GIRealInfo *rinfo = (GIRealInfo *)info;
819   ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
820
821   return blob->return_value;
822 }
823
824 gboolean
825 g_arg_info_is_dipper (GIArgInfo *info)
826 {
827   GIRealInfo *rinfo = (GIRealInfo *)info;
828   ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
829
830   return blob->dipper;
831 }
832
833 gboolean
834 g_arg_info_is_optional (GIArgInfo *info)
835 {
836   GIRealInfo *rinfo = (GIRealInfo *)info;
837   ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
838
839   return blob->optional;
840 }
841
842 gboolean
843 g_arg_info_may_be_null (GIArgInfo *info)
844 {
845   GIRealInfo *rinfo = (GIRealInfo *)info;
846   ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
847
848   return blob->allow_none;
849 }
850
851 GITransfer
852 g_arg_info_get_ownership_transfer (GIArgInfo *info)
853 {
854   GIRealInfo *rinfo = (GIRealInfo *)info;
855   ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
856
857   if (blob->transfer_ownership)
858     return GI_TRANSFER_EVERYTHING;
859   else if (blob->transfer_container_ownership)
860     return GI_TRANSFER_CONTAINER;
861   else
862     return GI_TRANSFER_NOTHING;
863 }
864
865 GIScopeType
866 g_arg_info_get_scope (GIArgInfo *info)
867 {
868   GIRealInfo *rinfo = (GIRealInfo *)info;
869   ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
870
871   return blob->scope;
872 }
873
874 gint
875 g_arg_info_get_closure (GIArgInfo *info)
876 {
877   GIRealInfo *rinfo = (GIRealInfo *)info;
878   ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
879
880   return blob->closure;
881 }
882
883 gint
884 g_arg_info_get_destroy (GIArgInfo *info)
885 {
886   GIRealInfo *rinfo = (GIRealInfo *)info;
887   ArgBlob *blob = (ArgBlob *)&rinfo->typelib->data[rinfo->offset];
888
889   return blob->destroy;
890 }
891
892 /**
893  * g_arg_info_get_type:
894  * @info: A #GIArgInfo
895  *
896  * Returns: (transfer full): Information about the type of argument @info
897  */
898 GITypeInfo *
899 g_arg_info_get_type (GIArgInfo *info)
900 {
901   GIRealInfo *rinfo = (GIRealInfo *)info;
902
903   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type));
904 }
905
906 /**
907  * g_arg_info_load_type:
908  * @info: A #GIArgInfo
909  * @type: (out caller-allocates): Initialized with information about type of @info
910  *
911  * Get information about a the type of given argument @info; this
912  * function is a variant of g_arg_info_get_type() designed for stack
913  * allocation.
914  *
915  * The initialized @type must not be referenced after @info is deallocated.
916  */
917 void
918 g_arg_info_load_type (GIArgInfo *info,
919                       GITypeInfo *type)
920 {
921   GIRealInfo *rinfo = (GIRealInfo*) info;
922   g_type_info_init (type, (GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (ArgBlob, arg_type));
923 }
924
925 /* GITypeInfo functions */
926 gboolean
927 g_type_info_is_pointer (GITypeInfo *info)
928 {
929   GIRealInfo *rinfo = (GIRealInfo *)info;
930   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
931
932   if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
933     return type->flags.pointer;
934   else
935     {
936       InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
937
938       return iface->pointer;
939     }
940 }
941
942 GITypeTag
943 g_type_info_get_tag (GITypeInfo *info)
944 {
945   GIRealInfo *rinfo = (GIRealInfo *)info;
946   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
947
948   if (rinfo->type_is_embedded)
949     return GI_TYPE_TAG_INTERFACE;
950   else if (type->flags.reserved == 0 && type->flags.reserved2 == 0)
951     return type->flags.tag;
952   else
953     {
954       InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
955
956       return iface->tag;
957     }
958 }
959
960 GITypeInfo *
961 g_type_info_get_param_type (GITypeInfo *info,
962                             gint       n)
963 {
964   GIRealInfo *rinfo = (GIRealInfo *)info;
965   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
966
967   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
968     {
969       ParamTypeBlob *param = (ParamTypeBlob *)&rinfo->typelib->data[rinfo->offset];
970
971       switch (param->tag)
972         {
973           case GI_TYPE_TAG_ARRAY:
974           case GI_TYPE_TAG_GLIST:
975           case GI_TYPE_TAG_GSLIST:
976           case GI_TYPE_TAG_GHASH:
977             return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib,
978                                     rinfo->offset + sizeof (ParamTypeBlob)
979                                     + sizeof (SimpleTypeBlob) * n);
980             break;
981           default:
982             break;
983         }
984     }
985
986   return NULL;
987 }
988
989 /**
990  * g_type_info_get_interface:
991  * @info: A #GITypeInfo
992  *
993  * For types which have #GI_TYPE_TAG_INTERFACE such as GObjects and boxed values,
994  * this function returns full information about the referenced type.  You can then
995  * inspect the type of the returned #GIBaseInfo to further query whether it is
996  * a concrete GObject, a GInterface, a structure, etc. using g_base_info_get_type().
997  */
998 GIBaseInfo *
999 g_type_info_get_interface (GITypeInfo *info)
1000 {
1001   GIRealInfo *rinfo = (GIRealInfo *)info;
1002
1003   /* For embedded types, the given offset is a pointer to the actual blob,
1004    * after the end of the field.  In that case we know it's a "subclass" of
1005    * CommonBlob, so use that to determine the info type.
1006    */
1007   if (rinfo->type_is_embedded)
1008     {
1009       CommonBlob *common = (CommonBlob *)&rinfo->typelib->data[rinfo->offset];
1010       GIInfoType info_type;
1011
1012       switch (common->blob_type)
1013         {
1014           case BLOB_TYPE_CALLBACK:
1015             info_type = GI_INFO_TYPE_CALLBACK;
1016             break;
1017           default:
1018             g_assert_not_reached ();
1019             return NULL;
1020         }
1021       return (GIBaseInfo *) g_info_new (info_type, (GIBaseInfo*)info, rinfo->typelib,
1022                                         rinfo->offset);
1023     }
1024   else
1025     {
1026       SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1027       if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1028         {
1029           InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1030
1031           if (blob->tag == GI_TYPE_TAG_INTERFACE)
1032             return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
1033         }
1034     }
1035
1036   return NULL;
1037 }
1038
1039 gint
1040 g_type_info_get_array_length (GITypeInfo *info)
1041 {
1042   GIRealInfo *rinfo = (GIRealInfo *)info;
1043   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1044
1045   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1046     {
1047       ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1048
1049       if (blob->tag == GI_TYPE_TAG_ARRAY)
1050         {
1051           if (blob->has_length)
1052             return blob->dimensions.length;
1053         }
1054     }
1055
1056   return -1;
1057 }
1058
1059 gint
1060 g_type_info_get_array_fixed_size (GITypeInfo *info)
1061 {
1062   GIRealInfo *rinfo = (GIRealInfo *)info;
1063   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1064
1065   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1066     {
1067       ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1068
1069       if (blob->tag == GI_TYPE_TAG_ARRAY)
1070         {
1071           if (blob->has_size)
1072             return blob->dimensions.size;
1073         }
1074     }
1075
1076   return -1;
1077 }
1078
1079 gboolean
1080 g_type_info_is_zero_terminated (GITypeInfo *info)
1081 {
1082   GIRealInfo *rinfo = (GIRealInfo *)info;
1083   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1084
1085   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1086     {
1087       ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1088
1089       if (blob->tag == GI_TYPE_TAG_ARRAY)
1090         return blob->zero_terminated;
1091     }
1092
1093   return FALSE;
1094 }
1095
1096 gint
1097 g_type_info_get_n_error_domains (GITypeInfo *info)
1098 {
1099   GIRealInfo *rinfo = (GIRealInfo *)info;
1100   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1101
1102   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1103     {
1104       ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1105
1106       if (blob->tag == GI_TYPE_TAG_ERROR)
1107         return blob->n_domains;
1108     }
1109
1110   return 0;
1111 }
1112
1113 GIErrorDomainInfo *
1114 g_type_info_get_error_domain (GITypeInfo *info,
1115                               gint        n)
1116 {
1117   GIRealInfo *rinfo = (GIRealInfo *)info;
1118   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1119
1120   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1121     {
1122       ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1123
1124       if (blob->tag == GI_TYPE_TAG_ERROR)
1125         return (GIErrorDomainInfo *) g_info_from_entry (rinfo->repository,
1126                                                         rinfo->typelib,
1127                                                         blob->domains[n]);
1128     }
1129
1130   return NULL;
1131 }
1132
1133
1134 /* GIErrorDomainInfo functions */
1135 const gchar *
1136 g_error_domain_info_get_quark (GIErrorDomainInfo *info)
1137 {
1138   GIRealInfo *rinfo = (GIRealInfo *)info;
1139   ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset];
1140
1141   return g_typelib_get_string (rinfo->typelib, blob->get_quark);
1142 }
1143
1144 GIInterfaceInfo *
1145 g_error_domain_info_get_codes (GIErrorDomainInfo *info)
1146 {
1147   GIRealInfo *rinfo = (GIRealInfo *)info;
1148   ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset];
1149
1150   return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository,
1151                                                 rinfo->typelib, blob->error_codes);
1152 }
1153
1154
1155 /* GIValueInfo functions */
1156 glong
1157 g_value_info_get_value (GIValueInfo *info)
1158 {
1159   GIRealInfo *rinfo = (GIRealInfo *)info;
1160   ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
1161
1162   return (glong)blob->value;
1163 }
1164
1165 /* GIFieldInfo functions */
1166 GIFieldInfoFlags
1167 g_field_info_get_flags (GIFieldInfo *info)
1168 {
1169   GIFieldInfoFlags flags;
1170
1171   GIRealInfo *rinfo = (GIRealInfo *)info;
1172   FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
1173
1174   flags = 0;
1175
1176   if (blob->readable)
1177     flags = flags | GI_FIELD_IS_READABLE;
1178
1179   if (blob->writable)
1180     flags = flags | GI_FIELD_IS_WRITABLE;
1181
1182   return flags;
1183 }
1184
1185 gint
1186 g_field_info_get_size (GIFieldInfo *info)
1187 {
1188   GIRealInfo *rinfo = (GIRealInfo *)info;
1189   FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
1190
1191   return blob->bits;
1192 }
1193
1194 gint
1195 g_field_info_get_offset (GIFieldInfo *info)
1196 {
1197   GIRealInfo *rinfo = (GIRealInfo *)info;
1198   FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
1199
1200   return blob->struct_offset;
1201 }
1202
1203 GITypeInfo *
1204 g_field_info_get_type (GIFieldInfo *info)
1205 {
1206   GIRealInfo *rinfo = (GIRealInfo *)info;
1207   Header *header = (Header *)rinfo->typelib->data;
1208   FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
1209   GIRealInfo *type_info;
1210
1211   if (blob->has_embedded_type)
1212     {
1213       type_info = (GIRealInfo *) g_info_new (GI_INFO_TYPE_TYPE,
1214                                                 (GIBaseInfo*)info, rinfo->typelib,
1215                                                 rinfo->offset + header->field_blob_size);
1216       type_info->type_is_embedded = TRUE;
1217     }
1218   else
1219     return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type));
1220
1221   return (GIBaseInfo*)type_info;
1222 }
1223
1224 /* GIRegisteredTypeInfo functions */
1225 const gchar *
1226 g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info)
1227 {
1228   GIRealInfo *rinfo = (GIRealInfo *)info;
1229   RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1230
1231   if (blob->gtype_name)
1232     return g_typelib_get_string (rinfo->typelib, blob->gtype_name);
1233
1234   return NULL;
1235 }
1236
1237 const gchar *
1238 g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info)
1239 {
1240   GIRealInfo *rinfo = (GIRealInfo *)info;
1241   RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1242
1243   if (blob->gtype_init)
1244     return g_typelib_get_string (rinfo->typelib, blob->gtype_init);
1245
1246   return NULL;
1247 }
1248
1249 GType
1250 g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info)
1251 {
1252   const char *type_init;
1253   GType (* get_type_func) (void);
1254   GIRealInfo *rinfo = (GIRealInfo*)info;
1255
1256   type_init = g_registered_type_info_get_type_init (info);
1257
1258   if (type_init == NULL)
1259     return G_TYPE_NONE;
1260   else if (!strcmp (type_init, "intern"))
1261     return G_TYPE_OBJECT;
1262
1263   get_type_func = NULL;
1264   if (!g_typelib_symbol (rinfo->typelib,
1265                          type_init,
1266                          (void**) &get_type_func))
1267     return G_TYPE_NONE;
1268
1269   return (* get_type_func) ();
1270 }
1271
1272 /* GIStructInfo functions */
1273 gint
1274 g_struct_info_get_n_fields (GIStructInfo *info)
1275 {
1276   GIRealInfo *rinfo = (GIRealInfo *)info;
1277   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1278
1279   return blob->n_fields;
1280 }
1281
1282 static gint32
1283 g_struct_get_field_offset (GIStructInfo *info,
1284                            gint         n)
1285 {
1286   GIRealInfo *rinfo = (GIRealInfo *)info;
1287   Header *header = (Header *)rinfo->typelib->data;
1288   guint32 offset = rinfo->offset + header->struct_blob_size;
1289   gint i;
1290   FieldBlob *field_blob;
1291
1292   for (i = 0; i < n; i++)
1293     {
1294       field_blob = (FieldBlob *)&rinfo->typelib->data[offset];
1295       offset += header->field_blob_size;
1296       if (field_blob->has_embedded_type)
1297         offset += header->callback_blob_size;
1298     }
1299
1300   return offset;
1301 }
1302
1303 GIFieldInfo *
1304 g_struct_info_get_field (GIStructInfo *info,
1305                          gint          n)
1306 {
1307   GIRealInfo *rinfo = (GIRealInfo *)info;
1308
1309   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib,
1310                                      g_struct_get_field_offset (info, n));
1311 }
1312
1313 gint
1314 g_struct_info_get_n_methods (GIStructInfo *info)
1315 {
1316   GIRealInfo *rinfo = (GIRealInfo *)info;
1317   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1318
1319   return blob->n_methods;
1320 }
1321
1322 GIFunctionInfo *
1323 g_struct_info_get_method (GIStructInfo *info,
1324                           gint         n)
1325 {
1326   GIRealInfo *rinfo = (GIRealInfo *)info;
1327   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1328   Header *header = (Header *)rinfo->typelib->data;
1329   gint offset;
1330
1331   offset = g_struct_get_field_offset (info, blob->n_fields) + n * header->function_blob_size;
1332   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
1333                                         rinfo->typelib, offset);
1334 }
1335
1336 static GIFunctionInfo *
1337 find_method (GIBaseInfo   *base,
1338              guint32       offset,
1339              gint          n_methods,
1340              const gchar  *name)
1341 {
1342   /* FIXME hash */
1343   GIRealInfo *rinfo = (GIRealInfo*)base;
1344   Header *header = (Header *)rinfo->typelib->data;
1345   gint i;
1346
1347   for (i = 0; i < n_methods; i++)
1348     {
1349       FunctionBlob *fblob = (FunctionBlob *)&rinfo->typelib->data[offset];
1350       const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name];
1351
1352       if (strcmp (name, fname) == 0)
1353         return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base,
1354                                               rinfo->typelib, offset);
1355
1356       offset += header->function_blob_size;
1357     }
1358
1359   return NULL;
1360 }
1361
1362 GIFunctionInfo *
1363 g_struct_info_find_method (GIStructInfo *info,
1364                            const gchar  *name)
1365 {
1366   gint offset;
1367   GIRealInfo *rinfo = (GIRealInfo *)info;
1368   Header *header = (Header *)rinfo->typelib->data;
1369   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1370
1371   offset = rinfo->offset + header->struct_blob_size
1372     + blob->n_fields * header->field_blob_size;
1373
1374   return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
1375 }
1376
1377 gsize
1378 g_struct_info_get_size (GIStructInfo *info)
1379 {
1380   GIRealInfo *rinfo = (GIRealInfo *)info;
1381   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1382
1383   return blob->size;
1384 }
1385
1386 gsize
1387 g_struct_info_get_alignment (GIStructInfo *info)
1388 {
1389   GIRealInfo *rinfo = (GIRealInfo *)info;
1390   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1391
1392   return blob->alignment;
1393 }
1394
1395 gboolean
1396 g_struct_info_is_foreign (GIStructInfo *info)
1397 {
1398   GIRealInfo *rinfo = (GIRealInfo *)info;
1399   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1400
1401   return blob->foreign;
1402 }
1403
1404 /**
1405  * g_struct_info_is_gtype_struct:
1406  * @info: GIStructInfo
1407  *
1408  * Return true if this structure represents the "class structure" for some
1409  * #GObject or #GInterface.  This function is mainly useful to hide this kind of structure
1410  * from generated public APIs.
1411  *
1412  * Returns: %TRUE if this is a class struct, %FALSE otherwise
1413  */
1414 gboolean
1415 g_struct_info_is_gtype_struct (GIStructInfo *info)
1416 {
1417   GIRealInfo *rinfo = (GIRealInfo *)info;
1418   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1419
1420   return blob->is_gtype_struct;
1421 }
1422
1423 gint
1424 g_enum_info_get_n_values (GIEnumInfo *info)
1425 {
1426   GIRealInfo *rinfo = (GIRealInfo *)info;
1427   EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
1428
1429   return blob->n_values;
1430 }
1431
1432 GIValueInfo *
1433 g_enum_info_get_value (GIEnumInfo *info,
1434                        gint            n)
1435 {
1436   GIRealInfo *rinfo = (GIRealInfo *)info;
1437   Header *header = (Header *)rinfo->typelib->data;
1438   gint offset;
1439
1440   offset = rinfo->offset + header->enum_blob_size
1441     + n * header->value_blob_size;
1442   return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset);
1443 }
1444
1445 /**
1446  * g_enum_info_get_storage_type:
1447  * @info: GIEnumInfo
1448  *
1449  * Gets the tag of the type used for the enum in the C ABI. This will
1450  * will be a signed or unsigned integral type.
1451
1452  * Note that in the current implementation the width of the type is
1453  * computed correctly, but the signed or unsigned nature of the type
1454  * may not match the sign of the type used by the C compiler.
1455  *
1456  * Return Value: the storage type for the enumeration
1457  */
1458 GITypeTag
1459 g_enum_info_get_storage_type (GIEnumInfo *info)
1460 {
1461   GIRealInfo *rinfo = (GIRealInfo *)info;
1462   EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
1463
1464   return blob->storage_type;
1465 }
1466
1467 /* GIObjectInfo functions */
1468 GIObjectInfo *
1469 g_object_info_get_parent (GIObjectInfo *info)
1470 {
1471   GIRealInfo *rinfo = (GIRealInfo *)info;
1472   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1473
1474   if (blob->parent)
1475     return (GIObjectInfo *) g_info_from_entry (rinfo->repository,
1476                                                rinfo->typelib, blob->parent);
1477   else
1478     return NULL;
1479 }
1480
1481 gboolean
1482 g_object_info_get_abstract (GIObjectInfo    *info)
1483 {
1484   GIRealInfo *rinfo = (GIRealInfo *)info;
1485   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1486   return blob->abstract != 0;
1487 }
1488
1489 const gchar *
1490 g_object_info_get_type_name (GIObjectInfo *info)
1491 {
1492   GIRealInfo *rinfo = (GIRealInfo *)info;
1493   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1494
1495   return g_typelib_get_string (rinfo->typelib, blob->gtype_name);
1496 }
1497
1498 const gchar *
1499 g_object_info_get_type_init (GIObjectInfo *info)
1500 {
1501   GIRealInfo *rinfo = (GIRealInfo *)info;
1502   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1503
1504   return g_typelib_get_string (rinfo->typelib, blob->gtype_init);
1505 }
1506
1507 gint
1508 g_object_info_get_n_interfaces (GIObjectInfo *info)
1509 {
1510   GIRealInfo *rinfo = (GIRealInfo *)info;
1511   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1512
1513   return blob->n_interfaces;
1514 }
1515
1516 GIInterfaceInfo *
1517 g_object_info_get_interface (GIObjectInfo *info,
1518                              gint          n)
1519 {
1520   GIRealInfo *rinfo = (GIRealInfo *)info;
1521   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1522
1523   return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository,
1524                                                 rinfo->typelib, blob->interfaces[n]);
1525 }
1526
1527 gint
1528 g_object_info_get_n_fields (GIObjectInfo *info)
1529 {
1530   GIRealInfo *rinfo = (GIRealInfo *)info;
1531   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1532
1533   return blob->n_fields;
1534 }
1535
1536 GIFieldInfo *
1537 g_object_info_get_field (GIObjectInfo *info,
1538                          gint          n)
1539 {
1540   gint offset;
1541   GIRealInfo *rinfo = (GIRealInfo *)info;
1542   Header *header = (Header *)rinfo->typelib->data;
1543   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1544
1545   offset = rinfo->offset + header->object_blob_size
1546     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1547     + n * header->field_blob_size;
1548
1549   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset);
1550 }
1551
1552 gint
1553 g_object_info_get_n_properties (GIObjectInfo *info)
1554 {
1555   GIRealInfo *rinfo = (GIRealInfo *)info;
1556   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1557
1558   return blob->n_properties;
1559 }
1560
1561 GIPropertyInfo *
1562 g_object_info_get_property (GIObjectInfo *info,
1563                             gint          n)
1564 {
1565   gint offset;
1566   GIRealInfo *rinfo = (GIRealInfo *)info;
1567   Header *header = (Header *)rinfo->typelib->data;
1568   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1569
1570   offset = rinfo->offset + header->object_blob_size
1571     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1572     + blob->n_fields * header->field_blob_size
1573     + n * header->property_blob_size;
1574
1575   return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
1576                                         rinfo->typelib, offset);
1577 }
1578
1579 gint
1580 g_object_info_get_n_methods (GIObjectInfo *info)
1581 {
1582   GIRealInfo *rinfo = (GIRealInfo *)info;
1583   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1584
1585   return blob->n_methods;
1586 }
1587
1588 GIFunctionInfo *
1589 g_object_info_get_method (GIObjectInfo *info,
1590                           gint          n)
1591 {
1592   gint offset;
1593   GIRealInfo *rinfo = (GIRealInfo *)info;
1594   Header *header = (Header *)rinfo->typelib->data;
1595   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1596
1597   offset = rinfo->offset + header->object_blob_size
1598     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1599     + blob->n_fields * header->field_blob_size
1600     + blob->n_properties * header->property_blob_size
1601     + n * header->function_blob_size;
1602
1603     return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
1604                                           rinfo->typelib, offset);
1605 }
1606
1607 GIFunctionInfo *
1608 g_object_info_find_method (GIObjectInfo *info,
1609                            const gchar  *name)
1610 {
1611   gint offset;
1612   GIRealInfo *rinfo = (GIRealInfo *)info;
1613   Header *header = (Header *)rinfo->typelib->data;
1614   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1615
1616   offset = rinfo->offset + header->object_blob_size
1617     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1618     + blob->n_fields * header->field_blob_size +
1619     + blob->n_properties * header->property_blob_size;
1620
1621   return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
1622 }
1623
1624 gint
1625 g_object_info_get_n_signals (GIObjectInfo *info)
1626 {
1627   GIRealInfo *rinfo = (GIRealInfo *)info;
1628   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1629
1630   return blob->n_signals;
1631 }
1632
1633 GISignalInfo *
1634 g_object_info_get_signal (GIObjectInfo *info,
1635                           gint          n)
1636 {
1637   gint offset;
1638   GIRealInfo *rinfo = (GIRealInfo *)info;
1639   Header *header = (Header *)rinfo->typelib->data;
1640   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1641
1642   offset = rinfo->offset + header->object_blob_size
1643     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1644     + blob->n_fields * header->field_blob_size
1645     + blob->n_properties * header->property_blob_size
1646     + blob->n_methods * header->function_blob_size
1647     + n * header->signal_blob_size;
1648
1649   return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
1650                                       rinfo->typelib, offset);
1651 }
1652
1653 gint
1654 g_object_info_get_n_vfuncs (GIObjectInfo *info)
1655 {
1656   GIRealInfo *rinfo = (GIRealInfo *)info;
1657   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1658
1659   return blob->n_vfuncs;
1660 }
1661
1662 GIVFuncInfo *
1663 g_object_info_get_vfunc (GIObjectInfo *info,
1664                          gint          n)
1665 {
1666   gint offset;
1667   GIRealInfo *rinfo = (GIRealInfo *)info;
1668   Header *header = (Header *)rinfo->typelib->data;
1669   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1670
1671   offset = rinfo->offset + header->object_blob_size
1672     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1673     + blob->n_fields * header->field_blob_size
1674     + blob->n_properties * header->property_blob_size
1675     + blob->n_methods * header->function_blob_size
1676     + blob->n_signals * header->signal_blob_size
1677     + n * header->vfunc_blob_size;
1678
1679   return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
1680                                      rinfo->typelib, offset);
1681 }
1682
1683 static GIVFuncInfo *
1684 find_vfunc (GIRealInfo   *rinfo,
1685             guint32       offset,
1686             gint          n_vfuncs,
1687             const gchar  *name)
1688 {
1689   /* FIXME hash */
1690   Header *header = (Header *)rinfo->typelib->data;
1691   gint i;
1692
1693   for (i = 0; i < n_vfuncs; i++)
1694     {
1695       VFuncBlob *fblob = (VFuncBlob *)&rinfo->typelib->data[offset];
1696       const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name];
1697
1698       if (strcmp (name, fname) == 0)
1699         return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*) rinfo,
1700                                            rinfo->typelib, offset);
1701
1702       offset += header->vfunc_blob_size;
1703     }
1704
1705   return NULL;
1706 }
1707
1708 /**
1709  * g_object_info_find_vfunc:
1710  * @info: An #GIObjectInfo
1711  * @name: The name of a virtual function to find.
1712  *
1713  * Locate a virtual function slot with name @name.  Note that the namespace
1714  * for virtuals is distinct from that of methods; there may or may not be
1715  * a concrete method associated for a virtual.  If there is one, it may
1716  * be retrieved using #g_vfunc_info_get_invoker.  See the documentation for
1717  * that function for more information on invoking virtuals.
1718  *
1719  * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name.
1720  */
1721 GIVFuncInfo *
1722 g_object_info_find_vfunc (GIObjectInfo *info,
1723                           const gchar  *name)
1724 {
1725   gint offset;
1726   GIRealInfo *rinfo = (GIRealInfo *)info;
1727   Header *header = (Header *)rinfo->typelib->data;
1728   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1729
1730   offset = rinfo->offset + header->object_blob_size
1731     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1732     + blob->n_fields * header->field_blob_size
1733     + blob->n_properties * header->property_blob_size
1734     + blob->n_methods * header->function_blob_size
1735     + blob->n_signals * header->signal_blob_size;
1736
1737   return find_vfunc (rinfo, offset, blob->n_vfuncs, name);
1738 }
1739
1740 gint
1741 g_object_info_get_n_constants (GIObjectInfo *info)
1742 {
1743   GIRealInfo *rinfo = (GIRealInfo *)info;
1744   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1745
1746   return blob->n_constants;
1747 }
1748
1749 GIConstantInfo *
1750 g_object_info_get_constant (GIObjectInfo *info,
1751                             gint          n)
1752 {
1753   gint offset;
1754   GIRealInfo *rinfo = (GIRealInfo *)info;
1755   Header *header = (Header *)rinfo->typelib->data;
1756   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1757
1758   offset = rinfo->offset + header->object_blob_size
1759     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1760     + blob->n_fields * header->field_blob_size
1761     + blob->n_properties * header->property_blob_size
1762     + blob->n_methods * header->function_blob_size
1763     + blob->n_signals * header->signal_blob_size
1764     + blob->n_vfuncs * header->vfunc_blob_size
1765     + n * header->constant_blob_size;
1766
1767   return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
1768                                         rinfo->typelib, offset);
1769 }
1770
1771 /**
1772  * g_object_info_get_class_struct:
1773  * @info: A #GIObjectInfo to query
1774  *
1775  * Every #GObject has two structures; an instance structure and a class
1776  * structure.  This function returns the metadata for the class structure.
1777  *
1778  * Returns: a #GIStructInfo for the class struct or %NULL if none found.
1779  */
1780 GIStructInfo *
1781 g_object_info_get_class_struct (GIObjectInfo *info)
1782 {
1783   GIRealInfo *rinfo = (GIRealInfo *)info;
1784   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1785
1786   if (blob->gtype_struct)
1787     return (GIStructInfo *) g_info_from_entry (rinfo->repository,
1788                                                rinfo->typelib, blob->gtype_struct);
1789   else
1790     return NULL;
1791 }
1792
1793 /* GIInterfaceInfo functions */
1794 gint
1795 g_interface_info_get_n_prerequisites (GIInterfaceInfo *info)
1796 {
1797   GIRealInfo *rinfo = (GIRealInfo *)info;
1798   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1799
1800   return blob->n_prerequisites;
1801 }
1802
1803 GIBaseInfo *
1804 g_interface_info_get_prerequisite (GIInterfaceInfo *info,
1805                                    gint            n)
1806 {
1807   GIRealInfo *rinfo = (GIRealInfo *)info;
1808   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1809
1810   return g_info_from_entry (rinfo->repository,
1811                             rinfo->typelib, blob->prerequisites[n]);
1812 }
1813
1814
1815 gint
1816 g_interface_info_get_n_properties (GIInterfaceInfo *info)
1817 {
1818   GIRealInfo *rinfo = (GIRealInfo *)info;
1819   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1820
1821   return blob->n_properties;
1822 }
1823
1824 GIPropertyInfo *
1825 g_interface_info_get_property (GIInterfaceInfo *info,
1826                                gint            n)
1827 {
1828   gint offset;
1829   GIRealInfo *rinfo = (GIRealInfo *)info;
1830   Header *header = (Header *)rinfo->typelib->data;
1831   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1832
1833   offset = rinfo->offset + header->interface_blob_size
1834     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1835     + n * header->property_blob_size;
1836
1837   return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
1838                                         rinfo->typelib, offset);
1839 }
1840
1841 gint
1842 g_interface_info_get_n_methods (GIInterfaceInfo *info)
1843 {
1844   GIRealInfo *rinfo = (GIRealInfo *)info;
1845   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1846
1847   return blob->n_methods;
1848 }
1849
1850 GIFunctionInfo *
1851 g_interface_info_get_method (GIInterfaceInfo *info,
1852                              gint            n)
1853 {
1854   gint offset;
1855   GIRealInfo *rinfo = (GIRealInfo *)info;
1856   Header *header = (Header *)rinfo->typelib->data;
1857   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1858
1859   offset = rinfo->offset + header->interface_blob_size
1860     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1861     + blob->n_properties * header->property_blob_size
1862     + n * header->function_blob_size;
1863
1864   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
1865                                         rinfo->typelib, offset);
1866 }
1867
1868 GIFunctionInfo *
1869 g_interface_info_find_method (GIInterfaceInfo *info,
1870                               const gchar     *name)
1871 {
1872   gint offset;
1873   GIRealInfo *rinfo = (GIRealInfo *)info;
1874   Header *header = (Header *)rinfo->typelib->data;
1875   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1876
1877   offset = rinfo->offset + header->interface_blob_size
1878     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1879     + blob->n_properties * header->property_blob_size;
1880
1881   return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
1882 }
1883
1884 gint
1885 g_interface_info_get_n_signals (GIInterfaceInfo *info)
1886 {
1887   GIRealInfo *rinfo = (GIRealInfo *)info;
1888   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1889
1890   return blob->n_signals;
1891 }
1892
1893 GISignalInfo *
1894 g_interface_info_get_signal (GIInterfaceInfo *info,
1895                              gint            n)
1896 {
1897   gint offset;
1898   GIRealInfo *rinfo = (GIRealInfo *)info;
1899   Header *header = (Header *)rinfo->typelib->data;
1900   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1901
1902   offset = rinfo->offset + header->interface_blob_size
1903     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1904     + blob->n_properties * header->property_blob_size
1905     + blob->n_methods * header->function_blob_size
1906     + n * header->signal_blob_size;
1907
1908   return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
1909                                       rinfo->typelib, offset);
1910 }
1911
1912 gint
1913 g_interface_info_get_n_vfuncs (GIInterfaceInfo *info)
1914 {
1915   GIRealInfo *rinfo = (GIRealInfo *)info;
1916   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1917
1918   return blob->n_vfuncs;
1919 }
1920
1921 GIVFuncInfo *
1922 g_interface_info_get_vfunc (GIInterfaceInfo *info,
1923                             gint            n)
1924 {
1925   gint offset;
1926   GIRealInfo *rinfo = (GIRealInfo *)info;
1927   Header *header = (Header *)rinfo->typelib->data;
1928   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1929
1930   offset = rinfo->offset + header->interface_blob_size
1931     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1932     + blob->n_properties * header->property_blob_size
1933     + blob->n_methods * header->function_blob_size
1934     + blob->n_signals * header->signal_blob_size
1935     + n * header->vfunc_blob_size;
1936
1937   return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
1938                                      rinfo->typelib, offset);
1939 }
1940
1941 /**
1942  * g_interface_info_find_vfunc:
1943  * @info: An #GIObjectInfo
1944  * @name: The name of a virtual function to find.
1945  *
1946  * Locate a virtual function slot with name @name.  See the documentation
1947  * for #g_object_info_find_vfunc for more information on virtuals.
1948  *
1949  * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name.
1950  */
1951 GIVFuncInfo *
1952 g_interface_info_find_vfunc (GIInterfaceInfo *info,
1953                              const gchar  *name)
1954 {
1955   gint offset;
1956   GIRealInfo *rinfo = (GIRealInfo *)info;
1957   Header *header = (Header *)rinfo->typelib->data;
1958   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1959
1960   offset = rinfo->offset + header->interface_blob_size
1961     + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2
1962     + blob->n_properties * header->property_blob_size
1963     + blob->n_methods * header->function_blob_size
1964     + blob->n_signals * header->signal_blob_size;
1965
1966   return find_vfunc (rinfo, offset, blob->n_vfuncs, name);
1967 }
1968
1969 gint
1970 g_interface_info_get_n_constants (GIInterfaceInfo *info)
1971 {
1972   GIRealInfo *rinfo = (GIRealInfo *)info;
1973   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1974
1975   return blob->n_constants;
1976 }
1977
1978 GIConstantInfo *
1979 g_interface_info_get_constant (GIInterfaceInfo *info,
1980                                gint             n)
1981 {
1982   gint offset;
1983   GIRealInfo *rinfo = (GIRealInfo *)info;
1984   Header *header = (Header *)rinfo->typelib->data;
1985   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1986
1987   offset = rinfo->offset + header->interface_blob_size
1988     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1989     + blob->n_properties * header->property_blob_size
1990     + blob->n_methods * header->function_blob_size
1991     + blob->n_signals * header->signal_blob_size
1992     + blob->n_vfuncs * header->vfunc_blob_size
1993     + n * header->constant_blob_size;
1994
1995   return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
1996                                         rinfo->typelib, offset);
1997 }
1998
1999 /**
2000  * g_interface_info_get_iface_struct:
2001  * @info: A #GIInterfaceInfo to query
2002  *
2003  * Returns the layout C structure associated with this #GInterface.
2004  *
2005  * Returns: A #GIStructInfo for the class struct or %NULL if none found.
2006  */
2007 GIStructInfo *
2008 g_interface_info_get_iface_struct (GIInterfaceInfo *info)
2009 {
2010   GIRealInfo *rinfo = (GIRealInfo *)info;
2011   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
2012
2013   if (blob->gtype_struct)
2014     return (GIStructInfo *) g_info_from_entry (rinfo->repository,
2015                                                rinfo->typelib, blob->gtype_struct);
2016   else
2017     return NULL;
2018 }
2019
2020 /* GIPropertyInfo functions */
2021 GParamFlags
2022 g_property_info_get_flags (GIPropertyInfo *info)
2023 {
2024   GParamFlags flags;
2025   GIRealInfo *rinfo = (GIRealInfo *)info;
2026   PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
2027
2028   flags = 0;
2029
2030   if (blob->readable)
2031     flags = flags | G_PARAM_READABLE;
2032
2033   if (blob->writable)
2034     flags = flags | G_PARAM_WRITABLE;
2035
2036   if (blob->construct)
2037     flags = flags | G_PARAM_CONSTRUCT;
2038
2039   if (blob->construct_only)
2040     flags = flags | G_PARAM_CONSTRUCT_ONLY;
2041
2042   return flags;
2043 }
2044
2045 GITypeInfo *
2046 g_property_info_get_type (GIPropertyInfo *info)
2047 {
2048   GIRealInfo *rinfo = (GIRealInfo *)info;
2049
2050   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type));
2051 }
2052
2053
2054 /* GISignalInfo functions */
2055 GSignalFlags
2056 g_signal_info_get_flags (GISignalInfo *info)
2057 {
2058   GSignalFlags flags;
2059
2060   GIRealInfo *rinfo = (GIRealInfo *)info;
2061   SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
2062
2063   flags = 0;
2064
2065   if (blob->run_first)
2066     flags = flags | G_SIGNAL_RUN_FIRST;
2067
2068   if (blob->run_last)
2069     flags = flags | G_SIGNAL_RUN_LAST;
2070
2071   if (blob->run_cleanup)
2072     flags = flags | G_SIGNAL_RUN_CLEANUP;
2073
2074   if (blob->no_recurse)
2075     flags = flags | G_SIGNAL_NO_RECURSE;
2076
2077   if (blob->detailed)
2078     flags = flags | G_SIGNAL_DETAILED;
2079
2080   if (blob->action)
2081     flags = flags | G_SIGNAL_ACTION;
2082
2083   if (blob->no_hooks)
2084     flags = flags | G_SIGNAL_NO_HOOKS;
2085
2086   return flags;
2087 }
2088
2089 GIVFuncInfo *
2090 g_signal_info_get_class_closure (GISignalInfo *info)
2091 {
2092   GIRealInfo *rinfo = (GIRealInfo *)info;
2093   SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
2094
2095   if (blob->has_class_closure)
2096     return g_interface_info_get_vfunc ((GIInterfaceInfo *)rinfo->container, blob->class_closure);
2097
2098   return NULL;
2099 }
2100
2101 gboolean
2102 g_signal_info_true_stops_emit (GISignalInfo *info)
2103 {
2104   GIRealInfo *rinfo = (GIRealInfo *)info;
2105   SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
2106
2107   return blob->true_stops_emit;
2108 }
2109
2110 /* GIVFuncInfo functions */
2111 GIVFuncInfoFlags
2112 g_vfunc_info_get_flags (GIVFuncInfo *info)
2113 {
2114   GIVFuncInfoFlags flags;
2115
2116   GIRealInfo *rinfo = (GIRealInfo *)info;
2117   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2118
2119   flags = 0;
2120
2121   if (blob->must_chain_up)
2122     flags = flags | GI_VFUNC_MUST_CHAIN_UP;
2123
2124   if (blob->must_be_implemented)
2125     flags = flags | GI_VFUNC_MUST_OVERRIDE;
2126
2127   if (blob->must_not_be_implemented)
2128     flags = flags | GI_VFUNC_MUST_NOT_OVERRIDE;
2129
2130   return flags;
2131 }
2132
2133 gint
2134 g_vfunc_info_get_offset (GIVFuncInfo *info)
2135 {
2136   GIRealInfo *rinfo = (GIRealInfo *)info;
2137   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2138
2139   return blob->struct_offset;
2140 }
2141
2142 GISignalInfo *
2143 g_vfunc_info_get_signal (GIVFuncInfo *info)
2144 {
2145   GIRealInfo *rinfo = (GIRealInfo *)info;
2146   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2147
2148   if (blob->class_closure)
2149     return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal);
2150
2151   return NULL;
2152 }
2153
2154 /**
2155  * g_vfunc_info_get_invoker:
2156  * @info: A #GIVFuncInfo
2157  *
2158  * If this virtual function has an associated invoker method, this
2159  * method will return it.  An invoker method is a C entry point.
2160  *
2161  * Not all virtuals will have invokers.
2162  *
2163  * Return value: (transfer full): An invoker function, or %NULL if none known
2164  */
2165 GIFunctionInfo *
2166 g_vfunc_info_get_invoker (GIVFuncInfo *info)
2167 {
2168   GIRealInfo *rinfo = (GIRealInfo *)info;
2169   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2170   GIBaseInfo *container = rinfo->container;
2171   GIInfoType parent_type;
2172
2173   /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */
2174   if (blob->invoker == 1023)
2175     return NULL;
2176
2177   parent_type = g_base_info_get_type (container);
2178   if (parent_type == GI_INFO_TYPE_OBJECT)
2179     return g_object_info_get_method ((GIObjectInfo*)container, blob->invoker);
2180   else if (parent_type == GI_INFO_TYPE_INTERFACE)
2181     return g_interface_info_get_method ((GIInterfaceInfo*)container, blob->invoker);
2182   else
2183     g_assert_not_reached ();
2184 }
2185
2186 /* GIConstantInfo functions */
2187 GITypeInfo *
2188 g_constant_info_get_type (GIConstantInfo *info)
2189 {
2190   GIRealInfo *rinfo = (GIRealInfo *)info;
2191
2192   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8);
2193 }
2194
2195 gint
2196 g_constant_info_get_value (GIConstantInfo *info,
2197                            GArgument      *value)
2198 {
2199   GIRealInfo *rinfo = (GIRealInfo *)info;
2200   ConstantBlob *blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset];
2201
2202   /* FIXME non-basic types ? */
2203   if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0)
2204     {
2205       if (blob->type.flags.pointer)
2206         value->v_pointer = g_memdup (&rinfo->typelib->data[blob->offset], blob->size);
2207       else
2208         {
2209           switch (blob->type.flags.tag)
2210             {
2211             case GI_TYPE_TAG_BOOLEAN:
2212               value->v_boolean = *(gboolean*)&rinfo->typelib->data[blob->offset];
2213               break;
2214             case GI_TYPE_TAG_INT8:
2215               value->v_int8 = *(gint8*)&rinfo->typelib->data[blob->offset];
2216               break;
2217             case GI_TYPE_TAG_UINT8:
2218               value->v_uint8 = *(guint8*)&rinfo->typelib->data[blob->offset];
2219               break;
2220             case GI_TYPE_TAG_INT16:
2221               value->v_int16 = *(gint16*)&rinfo->typelib->data[blob->offset];
2222               break;
2223             case GI_TYPE_TAG_UINT16:
2224               value->v_uint16 = *(guint16*)&rinfo->typelib->data[blob->offset];
2225               break;
2226             case GI_TYPE_TAG_INT32:
2227               value->v_int32 = *(gint32*)&rinfo->typelib->data[blob->offset];
2228               break;
2229             case GI_TYPE_TAG_UINT32:
2230               value->v_uint32 = *(guint32*)&rinfo->typelib->data[blob->offset];
2231               break;
2232             case GI_TYPE_TAG_INT64:
2233               value->v_int64 = *(gint64*)&rinfo->typelib->data[blob->offset];
2234               break;
2235             case GI_TYPE_TAG_UINT64:
2236               value->v_uint64 = *(guint64*)&rinfo->typelib->data[blob->offset];
2237               break;
2238             case GI_TYPE_TAG_FLOAT:
2239               value->v_float = *(gfloat*)&rinfo->typelib->data[blob->offset];
2240               break;
2241             case GI_TYPE_TAG_DOUBLE:
2242               value->v_double = *(gdouble*)&rinfo->typelib->data[blob->offset];
2243               break;
2244             case GI_TYPE_TAG_TIME_T:
2245               value->v_long = *(long*)&rinfo->typelib->data[blob->offset];
2246               break;
2247             case GI_TYPE_TAG_SHORT:
2248               value->v_short = *(gshort*)&rinfo->typelib->data[blob->offset];
2249               break;
2250             case GI_TYPE_TAG_USHORT:
2251               value->v_ushort = *(gushort*)&rinfo->typelib->data[blob->offset];
2252               break;
2253             case GI_TYPE_TAG_INT:
2254               value->v_int = *(gint*)&rinfo->typelib->data[blob->offset];
2255               break;
2256             case GI_TYPE_TAG_UINT:
2257               value->v_uint = *(guint*)&rinfo->typelib->data[blob->offset];
2258               break;
2259             case GI_TYPE_TAG_LONG:
2260               value->v_long = *(glong*)&rinfo->typelib->data[blob->offset];
2261               break;
2262             case GI_TYPE_TAG_ULONG:
2263               value->v_ulong = *(gulong*)&rinfo->typelib->data[blob->offset];
2264               break;
2265             }
2266         }
2267     }
2268
2269   return blob->size;
2270 }
2271
2272 /* GIUnionInfo functions */
2273 gint
2274 g_union_info_get_n_fields  (GIUnionInfo *info)
2275 {
2276   GIRealInfo *rinfo = (GIRealInfo *)info;
2277   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2278
2279   return blob->n_fields;
2280 }
2281
2282 GIFieldInfo *
2283 g_union_info_get_field (GIUnionInfo *info,
2284                         gint         n)
2285 {
2286   GIRealInfo *rinfo = (GIRealInfo *)info;
2287   Header *header = (Header *)rinfo->typelib->data;
2288
2289   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib,
2290                                      rinfo->offset + header->union_blob_size +
2291                                      n * header->field_blob_size);
2292 }
2293
2294 gint
2295 g_union_info_get_n_methods (GIUnionInfo *info)
2296 {
2297   GIRealInfo *rinfo = (GIRealInfo *)info;
2298   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2299
2300   return blob->n_functions;
2301 }
2302
2303 GIFunctionInfo *
2304 g_union_info_get_method (GIUnionInfo *info,
2305                          gint         n)
2306 {
2307   GIRealInfo *rinfo = (GIRealInfo *)info;
2308   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2309   Header *header = (Header *)rinfo->typelib->data;
2310   gint offset;
2311
2312   offset = rinfo->offset + header->union_blob_size
2313     + blob->n_fields * header->field_blob_size
2314     + n * header->function_blob_size;
2315   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
2316                                         rinfo->typelib, offset);
2317 }
2318
2319 gboolean
2320 g_union_info_is_discriminated (GIUnionInfo *info)
2321 {
2322   GIRealInfo *rinfo = (GIRealInfo *)info;
2323   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2324
2325   return blob->discriminated;
2326 }
2327
2328 gint
2329 g_union_info_get_discriminator_offset (GIUnionInfo *info)
2330 {
2331   GIRealInfo *rinfo = (GIRealInfo *)info;
2332   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2333
2334   return blob->discriminator_offset;
2335 }
2336
2337 GITypeInfo *
2338 g_union_info_get_discriminator_type (GIUnionInfo *info)
2339 {
2340   GIRealInfo *rinfo = (GIRealInfo *)info;
2341
2342   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24);
2343 }
2344
2345 GIConstantInfo *
2346 g_union_info_get_discriminator (GIUnionInfo *info,
2347                                 gint         n)
2348 {
2349   GIRealInfo *rinfo = (GIRealInfo *)info;
2350   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2351
2352   if (blob->discriminated)
2353     {
2354       Header *header = (Header *)rinfo->typelib->data;
2355       gint offset;
2356
2357       offset = rinfo->offset + header->union_blob_size
2358         + blob->n_fields * header->field_blob_size
2359         + blob->n_functions * header->function_blob_size
2360         + n * header->constant_blob_size;
2361
2362       return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
2363                                             rinfo->typelib, offset);
2364     }
2365
2366   return NULL;
2367 }
2368
2369 GIFunctionInfo *
2370 g_union_info_find_method (GIUnionInfo *info,
2371                           const gchar *name)
2372 {
2373   gint offset;
2374   GIRealInfo *rinfo = (GIRealInfo *)info;
2375   Header *header = (Header *)rinfo->typelib->data;
2376   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2377
2378   offset = rinfo->offset + header->union_blob_size
2379     + blob->n_fields * header->field_blob_size;
2380
2381   return find_method ((GIBaseInfo*)info, offset, blob->n_functions, name);
2382 }
2383
2384 gsize
2385 g_union_info_get_size (GIUnionInfo *info)
2386 {
2387   GIRealInfo *rinfo = (GIRealInfo *)info;
2388   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2389
2390   return blob->size;
2391 }
2392
2393 gsize
2394 g_union_info_get_alignment (GIUnionInfo *info)
2395 {
2396   GIRealInfo *rinfo = (GIRealInfo *)info;
2397   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2398
2399   return blob->alignment;
2400 }