[girepository] Remove trailing whitespace
[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 /**
1396  * g_struct_info_is_gtype_struct:
1397  * @info: GIStructInfo
1398  *
1399  * Return true if this structure represents the "class structure" for some
1400  * #GObject or #GInterface.  This function is mainly useful to hide this kind of structure
1401  * from generated public APIs.
1402  *
1403  * Returns: %TRUE if this is a class struct, %FALSE otherwise
1404  */
1405 gboolean
1406 g_struct_info_is_gtype_struct (GIStructInfo *info)
1407 {
1408   GIRealInfo *rinfo = (GIRealInfo *)info;
1409   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1410
1411   return blob->is_gtype_struct;
1412 }
1413
1414 gint
1415 g_enum_info_get_n_values (GIEnumInfo *info)
1416 {
1417   GIRealInfo *rinfo = (GIRealInfo *)info;
1418   EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
1419
1420   return blob->n_values;
1421 }
1422
1423 GIValueInfo *
1424 g_enum_info_get_value (GIEnumInfo *info,
1425                        gint            n)
1426 {
1427   GIRealInfo *rinfo = (GIRealInfo *)info;
1428   Header *header = (Header *)rinfo->typelib->data;
1429   gint offset;
1430
1431   offset = rinfo->offset + header->enum_blob_size
1432     + n * header->value_blob_size;
1433   return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset);
1434 }
1435
1436 /**
1437  * g_enum_info_get_storage_type:
1438  * @info: GIEnumInfo
1439  *
1440  * Gets the tag of the type used for the enum in the C ABI. This will
1441  * will be a signed or unsigned integral type.
1442
1443  * Note that in the current implementation the width of the type is
1444  * computed correctly, but the signed or unsigned nature of the type
1445  * may not match the sign of the type used by the C compiler.
1446  *
1447  * Return Value: the storage type for the enumeration
1448  */
1449 GITypeTag
1450 g_enum_info_get_storage_type (GIEnumInfo *info)
1451 {
1452   GIRealInfo *rinfo = (GIRealInfo *)info;
1453   EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
1454
1455   return blob->storage_type;
1456 }
1457
1458 /* GIObjectInfo functions */
1459 GIObjectInfo *
1460 g_object_info_get_parent (GIObjectInfo *info)
1461 {
1462   GIRealInfo *rinfo = (GIRealInfo *)info;
1463   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1464
1465   if (blob->parent)
1466     return (GIObjectInfo *) g_info_from_entry (rinfo->repository,
1467                                                rinfo->typelib, blob->parent);
1468   else
1469     return NULL;
1470 }
1471
1472 gboolean
1473 g_object_info_get_abstract (GIObjectInfo    *info)
1474 {
1475   GIRealInfo *rinfo = (GIRealInfo *)info;
1476   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1477   return blob->abstract != 0;
1478 }
1479
1480 const gchar *
1481 g_object_info_get_type_name (GIObjectInfo *info)
1482 {
1483   GIRealInfo *rinfo = (GIRealInfo *)info;
1484   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1485
1486   return g_typelib_get_string (rinfo->typelib, blob->gtype_name);
1487 }
1488
1489 const gchar *
1490 g_object_info_get_type_init (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_init);
1496 }
1497
1498 gint
1499 g_object_info_get_n_interfaces (GIObjectInfo *info)
1500 {
1501   GIRealInfo *rinfo = (GIRealInfo *)info;
1502   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1503
1504   return blob->n_interfaces;
1505 }
1506
1507 GIInterfaceInfo *
1508 g_object_info_get_interface (GIObjectInfo *info,
1509                              gint          n)
1510 {
1511   GIRealInfo *rinfo = (GIRealInfo *)info;
1512   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1513
1514   return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository,
1515                                                 rinfo->typelib, blob->interfaces[n]);
1516 }
1517
1518 gint
1519 g_object_info_get_n_fields (GIObjectInfo *info)
1520 {
1521   GIRealInfo *rinfo = (GIRealInfo *)info;
1522   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1523
1524   return blob->n_fields;
1525 }
1526
1527 GIFieldInfo *
1528 g_object_info_get_field (GIObjectInfo *info,
1529                          gint          n)
1530 {
1531   gint offset;
1532   GIRealInfo *rinfo = (GIRealInfo *)info;
1533   Header *header = (Header *)rinfo->typelib->data;
1534   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1535
1536   offset = rinfo->offset + header->object_blob_size
1537     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1538     + n * header->field_blob_size;
1539
1540   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset);
1541 }
1542
1543 gint
1544 g_object_info_get_n_properties (GIObjectInfo *info)
1545 {
1546   GIRealInfo *rinfo = (GIRealInfo *)info;
1547   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1548
1549   return blob->n_properties;
1550 }
1551
1552 GIPropertyInfo *
1553 g_object_info_get_property (GIObjectInfo *info,
1554                             gint          n)
1555 {
1556   gint offset;
1557   GIRealInfo *rinfo = (GIRealInfo *)info;
1558   Header *header = (Header *)rinfo->typelib->data;
1559   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1560
1561   offset = rinfo->offset + header->object_blob_size
1562     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1563     + blob->n_fields * header->field_blob_size
1564     + n * header->property_blob_size;
1565
1566   return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
1567                                         rinfo->typelib, offset);
1568 }
1569
1570 gint
1571 g_object_info_get_n_methods (GIObjectInfo *info)
1572 {
1573   GIRealInfo *rinfo = (GIRealInfo *)info;
1574   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1575
1576   return blob->n_methods;
1577 }
1578
1579 GIFunctionInfo *
1580 g_object_info_get_method (GIObjectInfo *info,
1581                           gint          n)
1582 {
1583   gint offset;
1584   GIRealInfo *rinfo = (GIRealInfo *)info;
1585   Header *header = (Header *)rinfo->typelib->data;
1586   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1587
1588   offset = rinfo->offset + header->object_blob_size
1589     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1590     + blob->n_fields * header->field_blob_size
1591     + blob->n_properties * header->property_blob_size
1592     + n * header->function_blob_size;
1593
1594     return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
1595                                           rinfo->typelib, offset);
1596 }
1597
1598 GIFunctionInfo *
1599 g_object_info_find_method (GIObjectInfo *info,
1600                            const gchar  *name)
1601 {
1602   gint offset;
1603   GIRealInfo *rinfo = (GIRealInfo *)info;
1604   Header *header = (Header *)rinfo->typelib->data;
1605   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1606
1607   offset = rinfo->offset + header->object_blob_size
1608     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1609     + blob->n_fields * header->field_blob_size +
1610     + blob->n_properties * header->property_blob_size;
1611
1612   return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
1613 }
1614
1615 gint
1616 g_object_info_get_n_signals (GIObjectInfo *info)
1617 {
1618   GIRealInfo *rinfo = (GIRealInfo *)info;
1619   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1620
1621   return blob->n_signals;
1622 }
1623
1624 GISignalInfo *
1625 g_object_info_get_signal (GIObjectInfo *info,
1626                           gint          n)
1627 {
1628   gint offset;
1629   GIRealInfo *rinfo = (GIRealInfo *)info;
1630   Header *header = (Header *)rinfo->typelib->data;
1631   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1632
1633   offset = rinfo->offset + header->object_blob_size
1634     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1635     + blob->n_fields * header->field_blob_size
1636     + blob->n_properties * header->property_blob_size
1637     + blob->n_methods * header->function_blob_size
1638     + n * header->signal_blob_size;
1639
1640   return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
1641                                       rinfo->typelib, offset);
1642 }
1643
1644 gint
1645 g_object_info_get_n_vfuncs (GIObjectInfo *info)
1646 {
1647   GIRealInfo *rinfo = (GIRealInfo *)info;
1648   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1649
1650   return blob->n_vfuncs;
1651 }
1652
1653 GIVFuncInfo *
1654 g_object_info_get_vfunc (GIObjectInfo *info,
1655                          gint          n)
1656 {
1657   gint offset;
1658   GIRealInfo *rinfo = (GIRealInfo *)info;
1659   Header *header = (Header *)rinfo->typelib->data;
1660   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1661
1662   offset = rinfo->offset + header->object_blob_size
1663     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1664     + blob->n_fields * header->field_blob_size
1665     + blob->n_properties * header->property_blob_size
1666     + blob->n_methods * header->function_blob_size
1667     + blob->n_signals * header->signal_blob_size
1668     + n * header->vfunc_blob_size;
1669
1670   return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
1671                                      rinfo->typelib, offset);
1672 }
1673
1674 static GIVFuncInfo *
1675 find_vfunc (GIRealInfo   *rinfo,
1676             guint32       offset,
1677             gint          n_vfuncs,
1678             const gchar  *name)
1679 {
1680   /* FIXME hash */
1681   Header *header = (Header *)rinfo->typelib->data;
1682   gint i;
1683
1684   for (i = 0; i < n_vfuncs; i++)
1685     {
1686       VFuncBlob *fblob = (VFuncBlob *)&rinfo->typelib->data[offset];
1687       const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name];
1688
1689       if (strcmp (name, fname) == 0)
1690         return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*) rinfo,
1691                                            rinfo->typelib, offset);
1692
1693       offset += header->vfunc_blob_size;
1694     }
1695
1696   return NULL;
1697 }
1698
1699 /**
1700  * g_object_info_find_vfunc:
1701  * @info: An #GIObjectInfo
1702  * @name: The name of a virtual function to find.
1703  *
1704  * Locate a virtual function slot with name @name.  Note that the namespace
1705  * for virtuals is distinct from that of methods; there may or may not be
1706  * a concrete method associated for a virtual.  If there is one, it may
1707  * be retrieved using #g_vfunc_info_get_invoker.  See the documentation for
1708  * that function for more information on invoking virtuals.
1709  *
1710  * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name.
1711  */
1712 GIVFuncInfo *
1713 g_object_info_find_vfunc (GIObjectInfo *info,
1714                           const gchar  *name)
1715 {
1716   gint offset;
1717   GIRealInfo *rinfo = (GIRealInfo *)info;
1718   Header *header = (Header *)rinfo->typelib->data;
1719   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1720
1721   offset = rinfo->offset + header->object_blob_size
1722     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1723     + blob->n_fields * header->field_blob_size
1724     + blob->n_properties * header->property_blob_size
1725     + blob->n_methods * header->function_blob_size
1726     + blob->n_signals * header->signal_blob_size;
1727
1728   return find_vfunc (rinfo, offset, blob->n_vfuncs, name);
1729 }
1730
1731 gint
1732 g_object_info_get_n_constants (GIObjectInfo *info)
1733 {
1734   GIRealInfo *rinfo = (GIRealInfo *)info;
1735   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1736
1737   return blob->n_constants;
1738 }
1739
1740 GIConstantInfo *
1741 g_object_info_get_constant (GIObjectInfo *info,
1742                             gint          n)
1743 {
1744   gint offset;
1745   GIRealInfo *rinfo = (GIRealInfo *)info;
1746   Header *header = (Header *)rinfo->typelib->data;
1747   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1748
1749   offset = rinfo->offset + header->object_blob_size
1750     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1751     + blob->n_fields * header->field_blob_size
1752     + blob->n_properties * header->property_blob_size
1753     + blob->n_methods * header->function_blob_size
1754     + blob->n_signals * header->signal_blob_size
1755     + blob->n_vfuncs * header->vfunc_blob_size
1756     + n * header->constant_blob_size;
1757
1758   return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
1759                                         rinfo->typelib, offset);
1760 }
1761
1762 /**
1763  * g_object_info_get_class_struct:
1764  * @info: A #GIObjectInfo to query
1765  *
1766  * Every #GObject has two structures; an instance structure and a class
1767  * structure.  This function returns the metadata for the class structure.
1768  *
1769  * Returns: a #GIStructInfo for the class struct or %NULL if none found.
1770  */
1771 GIStructInfo *
1772 g_object_info_get_class_struct (GIObjectInfo *info)
1773 {
1774   GIRealInfo *rinfo = (GIRealInfo *)info;
1775   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1776
1777   if (blob->gtype_struct)
1778     return (GIStructInfo *) g_info_from_entry (rinfo->repository,
1779                                                rinfo->typelib, blob->gtype_struct);
1780   else
1781     return NULL;
1782 }
1783
1784 /* GIInterfaceInfo functions */
1785 gint
1786 g_interface_info_get_n_prerequisites (GIInterfaceInfo *info)
1787 {
1788   GIRealInfo *rinfo = (GIRealInfo *)info;
1789   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1790
1791   return blob->n_prerequisites;
1792 }
1793
1794 GIBaseInfo *
1795 g_interface_info_get_prerequisite (GIInterfaceInfo *info,
1796                                    gint            n)
1797 {
1798   GIRealInfo *rinfo = (GIRealInfo *)info;
1799   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1800
1801   return g_info_from_entry (rinfo->repository,
1802                             rinfo->typelib, blob->prerequisites[n]);
1803 }
1804
1805
1806 gint
1807 g_interface_info_get_n_properties (GIInterfaceInfo *info)
1808 {
1809   GIRealInfo *rinfo = (GIRealInfo *)info;
1810   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1811
1812   return blob->n_properties;
1813 }
1814
1815 GIPropertyInfo *
1816 g_interface_info_get_property (GIInterfaceInfo *info,
1817                                gint            n)
1818 {
1819   gint offset;
1820   GIRealInfo *rinfo = (GIRealInfo *)info;
1821   Header *header = (Header *)rinfo->typelib->data;
1822   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1823
1824   offset = rinfo->offset + header->interface_blob_size
1825     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1826     + n * header->property_blob_size;
1827
1828   return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info,
1829                                         rinfo->typelib, offset);
1830 }
1831
1832 gint
1833 g_interface_info_get_n_methods (GIInterfaceInfo *info)
1834 {
1835   GIRealInfo *rinfo = (GIRealInfo *)info;
1836   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1837
1838   return blob->n_methods;
1839 }
1840
1841 GIFunctionInfo *
1842 g_interface_info_get_method (GIInterfaceInfo *info,
1843                              gint            n)
1844 {
1845   gint offset;
1846   GIRealInfo *rinfo = (GIRealInfo *)info;
1847   Header *header = (Header *)rinfo->typelib->data;
1848   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1849
1850   offset = rinfo->offset + header->interface_blob_size
1851     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1852     + blob->n_properties * header->property_blob_size
1853     + n * header->function_blob_size;
1854
1855   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
1856                                         rinfo->typelib, offset);
1857 }
1858
1859 GIFunctionInfo *
1860 g_interface_info_find_method (GIInterfaceInfo *info,
1861                               const gchar     *name)
1862 {
1863   gint offset;
1864   GIRealInfo *rinfo = (GIRealInfo *)info;
1865   Header *header = (Header *)rinfo->typelib->data;
1866   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1867
1868   offset = rinfo->offset + header->interface_blob_size
1869     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1870     + blob->n_properties * header->property_blob_size;
1871
1872   return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
1873 }
1874
1875 gint
1876 g_interface_info_get_n_signals (GIInterfaceInfo *info)
1877 {
1878   GIRealInfo *rinfo = (GIRealInfo *)info;
1879   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1880
1881   return blob->n_signals;
1882 }
1883
1884 GISignalInfo *
1885 g_interface_info_get_signal (GIInterfaceInfo *info,
1886                              gint            n)
1887 {
1888   gint offset;
1889   GIRealInfo *rinfo = (GIRealInfo *)info;
1890   Header *header = (Header *)rinfo->typelib->data;
1891   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1892
1893   offset = rinfo->offset + header->interface_blob_size
1894     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1895     + blob->n_properties * header->property_blob_size
1896     + blob->n_methods * header->function_blob_size
1897     + n * header->signal_blob_size;
1898
1899   return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info,
1900                                       rinfo->typelib, offset);
1901 }
1902
1903 gint
1904 g_interface_info_get_n_vfuncs (GIInterfaceInfo *info)
1905 {
1906   GIRealInfo *rinfo = (GIRealInfo *)info;
1907   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1908
1909   return blob->n_vfuncs;
1910 }
1911
1912 GIVFuncInfo *
1913 g_interface_info_get_vfunc (GIInterfaceInfo *info,
1914                             gint            n)
1915 {
1916   gint offset;
1917   GIRealInfo *rinfo = (GIRealInfo *)info;
1918   Header *header = (Header *)rinfo->typelib->data;
1919   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1920
1921   offset = rinfo->offset + header->interface_blob_size
1922     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1923     + blob->n_properties * header->property_blob_size
1924     + blob->n_methods * header->function_blob_size
1925     + blob->n_signals * header->signal_blob_size
1926     + n * header->vfunc_blob_size;
1927
1928   return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info,
1929                                      rinfo->typelib, offset);
1930 }
1931
1932 /**
1933  * g_interface_info_find_vfunc:
1934  * @info: An #GIObjectInfo
1935  * @name: The name of a virtual function to find.
1936  *
1937  * Locate a virtual function slot with name @name.  See the documentation
1938  * for #g_object_info_find_vfunc for more information on virtuals.
1939  *
1940  * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name.
1941  */
1942 GIVFuncInfo *
1943 g_interface_info_find_vfunc (GIInterfaceInfo *info,
1944                              const gchar  *name)
1945 {
1946   gint offset;
1947   GIRealInfo *rinfo = (GIRealInfo *)info;
1948   Header *header = (Header *)rinfo->typelib->data;
1949   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1950
1951   offset = rinfo->offset + header->interface_blob_size
1952     + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2
1953     + blob->n_properties * header->property_blob_size
1954     + blob->n_methods * header->function_blob_size
1955     + blob->n_signals * header->signal_blob_size;
1956
1957   return find_vfunc (rinfo, offset, blob->n_vfuncs, name);
1958 }
1959
1960 gint
1961 g_interface_info_get_n_constants (GIInterfaceInfo *info)
1962 {
1963   GIRealInfo *rinfo = (GIRealInfo *)info;
1964   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1965
1966   return blob->n_constants;
1967 }
1968
1969 GIConstantInfo *
1970 g_interface_info_get_constant (GIInterfaceInfo *info,
1971                                gint             n)
1972 {
1973   gint offset;
1974   GIRealInfo *rinfo = (GIRealInfo *)info;
1975   Header *header = (Header *)rinfo->typelib->data;
1976   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1977
1978   offset = rinfo->offset + header->interface_blob_size
1979     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1980     + blob->n_properties * header->property_blob_size
1981     + blob->n_methods * header->function_blob_size
1982     + blob->n_signals * header->signal_blob_size
1983     + blob->n_vfuncs * header->vfunc_blob_size
1984     + n * header->constant_blob_size;
1985
1986   return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
1987                                         rinfo->typelib, offset);
1988 }
1989
1990 /**
1991  * g_interface_info_get_iface_struct:
1992  * @info: A #GIInterfaceInfo to query
1993  *
1994  * Returns the layout C structure associated with this #GInterface.
1995  *
1996  * Returns: A #GIStructInfo for the class struct or %NULL if none found.
1997  */
1998 GIStructInfo *
1999 g_interface_info_get_iface_struct (GIInterfaceInfo *info)
2000 {
2001   GIRealInfo *rinfo = (GIRealInfo *)info;
2002   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
2003
2004   if (blob->gtype_struct)
2005     return (GIStructInfo *) g_info_from_entry (rinfo->repository,
2006                                                rinfo->typelib, blob->gtype_struct);
2007   else
2008     return NULL;
2009 }
2010
2011 /* GIPropertyInfo functions */
2012 GParamFlags
2013 g_property_info_get_flags (GIPropertyInfo *info)
2014 {
2015   GParamFlags flags;
2016   GIRealInfo *rinfo = (GIRealInfo *)info;
2017   PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
2018
2019   flags = 0;
2020
2021   if (blob->readable)
2022     flags = flags | G_PARAM_READABLE;
2023
2024   if (blob->writable)
2025     flags = flags | G_PARAM_WRITABLE;
2026
2027   if (blob->construct)
2028     flags = flags | G_PARAM_CONSTRUCT;
2029
2030   if (blob->construct_only)
2031     flags = flags | G_PARAM_CONSTRUCT_ONLY;
2032
2033   return flags;
2034 }
2035
2036 GITypeInfo *
2037 g_property_info_get_type (GIPropertyInfo *info)
2038 {
2039   GIRealInfo *rinfo = (GIRealInfo *)info;
2040
2041   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type));
2042 }
2043
2044
2045 /* GISignalInfo functions */
2046 GSignalFlags
2047 g_signal_info_get_flags (GISignalInfo *info)
2048 {
2049   GSignalFlags flags;
2050
2051   GIRealInfo *rinfo = (GIRealInfo *)info;
2052   SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
2053
2054   flags = 0;
2055
2056   if (blob->run_first)
2057     flags = flags | G_SIGNAL_RUN_FIRST;
2058
2059   if (blob->run_last)
2060     flags = flags | G_SIGNAL_RUN_LAST;
2061
2062   if (blob->run_cleanup)
2063     flags = flags | G_SIGNAL_RUN_CLEANUP;
2064
2065   if (blob->no_recurse)
2066     flags = flags | G_SIGNAL_NO_RECURSE;
2067
2068   if (blob->detailed)
2069     flags = flags | G_SIGNAL_DETAILED;
2070
2071   if (blob->action)
2072     flags = flags | G_SIGNAL_ACTION;
2073
2074   if (blob->no_hooks)
2075     flags = flags | G_SIGNAL_NO_HOOKS;
2076
2077   return flags;
2078 }
2079
2080 GIVFuncInfo *
2081 g_signal_info_get_class_closure (GISignalInfo *info)
2082 {
2083   GIRealInfo *rinfo = (GIRealInfo *)info;
2084   SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
2085
2086   if (blob->has_class_closure)
2087     return g_interface_info_get_vfunc ((GIInterfaceInfo *)rinfo->container, blob->class_closure);
2088
2089   return NULL;
2090 }
2091
2092 gboolean
2093 g_signal_info_true_stops_emit (GISignalInfo *info)
2094 {
2095   GIRealInfo *rinfo = (GIRealInfo *)info;
2096   SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
2097
2098   return blob->true_stops_emit;
2099 }
2100
2101 /* GIVFuncInfo functions */
2102 GIVFuncInfoFlags
2103 g_vfunc_info_get_flags (GIVFuncInfo *info)
2104 {
2105   GIVFuncInfoFlags flags;
2106
2107   GIRealInfo *rinfo = (GIRealInfo *)info;
2108   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2109
2110   flags = 0;
2111
2112   if (blob->must_chain_up)
2113     flags = flags | GI_VFUNC_MUST_CHAIN_UP;
2114
2115   if (blob->must_be_implemented)
2116     flags = flags | GI_VFUNC_MUST_OVERRIDE;
2117
2118   if (blob->must_not_be_implemented)
2119     flags = flags | GI_VFUNC_MUST_NOT_OVERRIDE;
2120
2121   return flags;
2122 }
2123
2124 gint
2125 g_vfunc_info_get_offset (GIVFuncInfo *info)
2126 {
2127   GIRealInfo *rinfo = (GIRealInfo *)info;
2128   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2129
2130   return blob->struct_offset;
2131 }
2132
2133 GISignalInfo *
2134 g_vfunc_info_get_signal (GIVFuncInfo *info)
2135 {
2136   GIRealInfo *rinfo = (GIRealInfo *)info;
2137   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2138
2139   if (blob->class_closure)
2140     return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal);
2141
2142   return NULL;
2143 }
2144
2145 /**
2146  * g_vfunc_info_get_invoker:
2147  * @info: A #GIVFuncInfo
2148  *
2149  * If this virtual function has an associated invoker method, this
2150  * method will return it.  An invoker method is a C entry point.
2151  *
2152  * Not all virtuals will have invokers.
2153  *
2154  * Return value: (transfer full): An invoker function, or %NULL if none known
2155  */
2156 GIFunctionInfo *
2157 g_vfunc_info_get_invoker (GIVFuncInfo *info)
2158 {
2159   GIRealInfo *rinfo = (GIRealInfo *)info;
2160   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2161   GIBaseInfo *container = rinfo->container;
2162   GIInfoType parent_type;
2163
2164   /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */
2165   if (blob->invoker == 1023)
2166     return NULL;
2167
2168   parent_type = g_base_info_get_type (container);
2169   if (parent_type == GI_INFO_TYPE_OBJECT)
2170     return g_object_info_get_method ((GIObjectInfo*)container, blob->invoker);
2171   else if (parent_type == GI_INFO_TYPE_INTERFACE)
2172     return g_interface_info_get_method ((GIInterfaceInfo*)container, blob->invoker);
2173   else
2174     g_assert_not_reached ();
2175 }
2176
2177 /* GIConstantInfo functions */
2178 GITypeInfo *
2179 g_constant_info_get_type (GIConstantInfo *info)
2180 {
2181   GIRealInfo *rinfo = (GIRealInfo *)info;
2182
2183   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8);
2184 }
2185
2186 gint
2187 g_constant_info_get_value (GIConstantInfo *info,
2188                            GArgument      *value)
2189 {
2190   GIRealInfo *rinfo = (GIRealInfo *)info;
2191   ConstantBlob *blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset];
2192
2193   /* FIXME non-basic types ? */
2194   if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0)
2195     {
2196       if (blob->type.flags.pointer)
2197         value->v_pointer = g_memdup (&rinfo->typelib->data[blob->offset], blob->size);
2198       else
2199         {
2200           switch (blob->type.flags.tag)
2201             {
2202             case GI_TYPE_TAG_BOOLEAN:
2203               value->v_boolean = *(gboolean*)&rinfo->typelib->data[blob->offset];
2204               break;
2205             case GI_TYPE_TAG_INT8:
2206               value->v_int8 = *(gint8*)&rinfo->typelib->data[blob->offset];
2207               break;
2208             case GI_TYPE_TAG_UINT8:
2209               value->v_uint8 = *(guint8*)&rinfo->typelib->data[blob->offset];
2210               break;
2211             case GI_TYPE_TAG_INT16:
2212               value->v_int16 = *(gint16*)&rinfo->typelib->data[blob->offset];
2213               break;
2214             case GI_TYPE_TAG_UINT16:
2215               value->v_uint16 = *(guint16*)&rinfo->typelib->data[blob->offset];
2216               break;
2217             case GI_TYPE_TAG_INT32:
2218               value->v_int32 = *(gint32*)&rinfo->typelib->data[blob->offset];
2219               break;
2220             case GI_TYPE_TAG_UINT32:
2221               value->v_uint32 = *(guint32*)&rinfo->typelib->data[blob->offset];
2222               break;
2223             case GI_TYPE_TAG_INT64:
2224               value->v_int64 = *(gint64*)&rinfo->typelib->data[blob->offset];
2225               break;
2226             case GI_TYPE_TAG_UINT64:
2227               value->v_uint64 = *(guint64*)&rinfo->typelib->data[blob->offset];
2228               break;
2229             case GI_TYPE_TAG_FLOAT:
2230               value->v_float = *(gfloat*)&rinfo->typelib->data[blob->offset];
2231               break;
2232             case GI_TYPE_TAG_DOUBLE:
2233               value->v_double = *(gdouble*)&rinfo->typelib->data[blob->offset];
2234               break;
2235             case GI_TYPE_TAG_TIME_T:
2236               value->v_long = *(long*)&rinfo->typelib->data[blob->offset];
2237               break;
2238             case GI_TYPE_TAG_SHORT:
2239               value->v_short = *(gshort*)&rinfo->typelib->data[blob->offset];
2240               break;
2241             case GI_TYPE_TAG_USHORT:
2242               value->v_ushort = *(gushort*)&rinfo->typelib->data[blob->offset];
2243               break;
2244             case GI_TYPE_TAG_INT:
2245               value->v_int = *(gint*)&rinfo->typelib->data[blob->offset];
2246               break;
2247             case GI_TYPE_TAG_UINT:
2248               value->v_uint = *(guint*)&rinfo->typelib->data[blob->offset];
2249               break;
2250             case GI_TYPE_TAG_LONG:
2251               value->v_long = *(glong*)&rinfo->typelib->data[blob->offset];
2252               break;
2253             case GI_TYPE_TAG_ULONG:
2254               value->v_ulong = *(gulong*)&rinfo->typelib->data[blob->offset];
2255               break;
2256             }
2257         }
2258     }
2259
2260   return blob->size;
2261 }
2262
2263 /* GIUnionInfo functions */
2264 gint
2265 g_union_info_get_n_fields  (GIUnionInfo *info)
2266 {
2267   GIRealInfo *rinfo = (GIRealInfo *)info;
2268   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2269
2270   return blob->n_fields;
2271 }
2272
2273 GIFieldInfo *
2274 g_union_info_get_field (GIUnionInfo *info,
2275                         gint         n)
2276 {
2277   GIRealInfo *rinfo = (GIRealInfo *)info;
2278   Header *header = (Header *)rinfo->typelib->data;
2279
2280   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib,
2281                                      rinfo->offset + header->union_blob_size +
2282                                      n * header->field_blob_size);
2283 }
2284
2285 gint
2286 g_union_info_get_n_methods (GIUnionInfo *info)
2287 {
2288   GIRealInfo *rinfo = (GIRealInfo *)info;
2289   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2290
2291   return blob->n_functions;
2292 }
2293
2294 GIFunctionInfo *
2295 g_union_info_get_method (GIUnionInfo *info,
2296                          gint         n)
2297 {
2298   GIRealInfo *rinfo = (GIRealInfo *)info;
2299   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2300   Header *header = (Header *)rinfo->typelib->data;
2301   gint offset;
2302
2303   offset = rinfo->offset + header->union_blob_size
2304     + blob->n_fields * header->field_blob_size
2305     + n * header->function_blob_size;
2306   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info,
2307                                         rinfo->typelib, offset);
2308 }
2309
2310 gboolean
2311 g_union_info_is_discriminated (GIUnionInfo *info)
2312 {
2313   GIRealInfo *rinfo = (GIRealInfo *)info;
2314   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2315
2316   return blob->discriminated;
2317 }
2318
2319 gint
2320 g_union_info_get_discriminator_offset (GIUnionInfo *info)
2321 {
2322   GIRealInfo *rinfo = (GIRealInfo *)info;
2323   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2324
2325   return blob->discriminator_offset;
2326 }
2327
2328 GITypeInfo *
2329 g_union_info_get_discriminator_type (GIUnionInfo *info)
2330 {
2331   GIRealInfo *rinfo = (GIRealInfo *)info;
2332
2333   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24);
2334 }
2335
2336 GIConstantInfo *
2337 g_union_info_get_discriminator (GIUnionInfo *info,
2338                                 gint         n)
2339 {
2340   GIRealInfo *rinfo = (GIRealInfo *)info;
2341   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2342
2343   if (blob->discriminated)
2344     {
2345       Header *header = (Header *)rinfo->typelib->data;
2346       gint offset;
2347
2348       offset = rinfo->offset + header->union_blob_size
2349         + blob->n_fields * header->field_blob_size
2350         + blob->n_functions * header->function_blob_size
2351         + n * header->constant_blob_size;
2352
2353       return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info,
2354                                             rinfo->typelib, offset);
2355     }
2356
2357   return NULL;
2358 }
2359
2360 GIFunctionInfo *
2361 g_union_info_find_method (GIUnionInfo *info,
2362                           const gchar *name)
2363 {
2364   gint offset;
2365   GIRealInfo *rinfo = (GIRealInfo *)info;
2366   Header *header = (Header *)rinfo->typelib->data;
2367   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2368
2369   offset = rinfo->offset + header->union_blob_size
2370     + blob->n_fields * header->field_blob_size;
2371
2372   return find_method ((GIBaseInfo*)info, offset, blob->n_functions, name);
2373 }
2374
2375 gsize
2376 g_union_info_get_size (GIUnionInfo *info)
2377 {
2378   GIRealInfo *rinfo = (GIRealInfo *)info;
2379   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2380
2381   return blob->size;
2382 }
2383
2384 gsize
2385 g_union_info_get_alignment (GIUnionInfo *info)
2386 {
2387   GIRealInfo *rinfo = (GIRealInfo *)info;
2388   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2389
2390   return blob->alignment;
2391 }