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