Bug 557786 - support fixed size arrays
[gnome.gobject-introspection] / girepository / ginfo.c
1 /* GObject introspection: Repository implementation
2  *
3  * Copyright (C) 2005 Matthias Clasen
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include <glib.h>
25 #include <glib-object.h>
26
27 #include "girepository.h"
28 #include "gtypelib.h"
29
30 struct _GIBaseInfo 
31 {
32   gint type;
33   gint ref_count;
34   GIBaseInfo *container;
35
36   GTypelib *typelib;
37   guint32 offset;
38 };
39
40 struct _GIUnresolvedInfo
41 {
42   gint type;
43   gint ref_count;
44   GIBaseInfo *container;
45
46   const gchar *name;
47   const gchar *namespace;
48 };
49
50 struct _GICallableInfo
51 {
52   GIBaseInfo base;
53 };
54
55 struct _GIFunctionInfo
56 {
57   GICallableInfo callable;
58 };
59
60 struct _GICallbackInfo
61 {
62   GICallableInfo callable;
63 };
64
65 struct _GIRegisteredTypeInfo
66 {
67   GIBaseInfo base;
68 };
69
70 struct _GIStructInfo
71 {
72   GIRegisteredTypeInfo registered;
73 };
74
75 struct _GIEnumInfo
76 {
77   GIRegisteredTypeInfo registered;
78 };
79
80 struct _GIObjectInfo
81 {
82   GIRegisteredTypeInfo registered;
83 };
84
85 struct _GIInterfaceInfo
86 {
87   GIRegisteredTypeInfo registered;
88 };
89
90 struct _GIConstantInfo
91 {
92   GIBaseInfo base;
93 };
94
95 struct _GIValueInfo
96 {
97   GIBaseInfo base;
98 };
99
100 struct _GISignalInfo
101 {
102   GICallableInfo callable;
103 };
104
105 struct _GIVFuncInfo
106 {
107   GICallableInfo callable;
108 };
109
110 struct _GIPropertyInfo
111 {
112   GIBaseInfo base;
113 };
114
115 struct _GIFieldInfo
116 {
117   GIBaseInfo base;
118 };
119
120 struct _GIArgInfo
121 {
122   GIBaseInfo base;
123 };
124
125 struct _GITypeInfo
126 {
127   GIBaseInfo base;
128 };
129
130 struct _GIUnionInfo
131 {
132   GIRegisteredTypeInfo registered;
133 };
134
135
136 /* info creation */
137 GIBaseInfo *
138 g_info_new (GIInfoType     type,
139             GIBaseInfo    *container,
140             GTypelib     *typelib, 
141             guint32        offset)
142 {
143   GIBaseInfo *info;
144
145   info = g_new0 (GIBaseInfo, 1);
146
147   info->ref_count = 1;
148   info->type = type;
149
150   info->typelib = typelib;
151   info->offset = offset;
152
153   if (container)
154     info->container = g_base_info_ref (container);
155
156   return info;
157 }
158
159 static GIBaseInfo *
160 g_info_from_entry (GTypelib *typelib,
161                    guint16    index)
162 {
163   GIBaseInfo *result;
164   DirEntry *entry = g_typelib_get_dir_entry (typelib, index);
165   
166   if (entry->local)
167     result = g_info_new (entry->blob_type, NULL, typelib, entry->offset);
168   else 
169     {
170       const gchar *namespace = g_typelib_get_string (typelib, entry->offset);
171       const gchar *name = g_typelib_get_string (typelib, entry->name);
172       
173       GIRepository *repository = g_irepository_get_default ();
174       
175       result = g_irepository_find_by_name (repository, namespace, name);
176       if (result == NULL)
177         {
178           GIUnresolvedInfo *unresolved;
179
180           unresolved = g_new0 (GIUnresolvedInfo, 1);
181           
182           unresolved->type = GI_INFO_TYPE_UNRESOLVED;
183           unresolved->ref_count = 1;
184           unresolved->container = NULL;
185           unresolved->name = name;
186           unresolved->namespace = namespace;
187           
188           return (GIBaseInfo*)unresolved;
189         }
190       return result;
191     }
192
193   return result;
194 }
195
196 /* GIBaseInfo functions */
197 GIBaseInfo *
198 g_base_info_ref (GIBaseInfo *info)
199 {
200   info->ref_count++;
201
202   return info;
203 }
204
205 void
206 g_base_info_unref (GIBaseInfo *info)
207 {
208   g_assert (info->ref_count > 0);
209   info->ref_count--;
210
211   if (!info->ref_count)
212     {
213       if (info->container)
214         g_base_info_unref (info->container);
215
216       g_free (info);
217     }
218 }
219
220 GIInfoType
221 g_base_info_get_type (GIBaseInfo *info)
222 {
223   
224   return info->type;
225 }
226
227 const gchar *
228 g_base_info_get_name (GIBaseInfo *info)
229 {
230   g_assert (info->ref_count > 0);
231   switch (info->type)
232     {
233     case GI_INFO_TYPE_FUNCTION:
234     case GI_INFO_TYPE_CALLBACK:
235     case GI_INFO_TYPE_STRUCT:
236     case GI_INFO_TYPE_BOXED:
237     case GI_INFO_TYPE_ENUM:
238     case GI_INFO_TYPE_FLAGS:
239     case GI_INFO_TYPE_OBJECT:
240     case GI_INFO_TYPE_INTERFACE:
241     case GI_INFO_TYPE_CONSTANT:
242     case GI_INFO_TYPE_ERROR_DOMAIN:
243     case GI_INFO_TYPE_UNION:
244       {
245         CommonBlob *blob = (CommonBlob *)&info->typelib->data[info->offset];
246
247         return g_typelib_get_string (info->typelib, blob->name);
248       }
249       break;
250
251     case GI_INFO_TYPE_VALUE:
252       {
253         ValueBlob *blob = (ValueBlob *)&info->typelib->data[info->offset];
254
255         return g_typelib_get_string (info->typelib, blob->name);
256       }
257       break;
258
259     case GI_INFO_TYPE_SIGNAL:
260       {
261         SignalBlob *blob = (SignalBlob *)&info->typelib->data[info->offset];
262
263         return g_typelib_get_string (info->typelib, blob->name);
264       }
265       break;
266
267     case GI_INFO_TYPE_PROPERTY:
268       {
269         PropertyBlob *blob = (PropertyBlob *)&info->typelib->data[info->offset];
270
271         return g_typelib_get_string (info->typelib, blob->name);
272       }
273       break;
274
275     case GI_INFO_TYPE_VFUNC:
276       {
277         VFuncBlob *blob = (VFuncBlob *)&info->typelib->data[info->offset];
278
279         return g_typelib_get_string (info->typelib, blob->name);
280       }
281       break;
282
283     case GI_INFO_TYPE_FIELD:
284       {
285         FieldBlob *blob = (FieldBlob *)&info->typelib->data[info->offset];
286         
287         return g_typelib_get_string (info->typelib, blob->name);
288       }
289       break;
290
291     case GI_INFO_TYPE_ARG:
292       {
293         ArgBlob *blob = (ArgBlob *)&info->typelib->data[info->offset];
294         
295         return g_typelib_get_string (info->typelib, blob->name);
296       }
297       break;
298     case GI_INFO_TYPE_UNRESOLVED:
299       {
300         GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
301
302         return unresolved->name;
303       }
304       break;
305     case GI_INFO_TYPE_TYPE:
306     default: ;
307       g_assert_not_reached ();
308       /* unnamed */
309     }
310
311   return NULL;
312 }
313
314 const gchar *
315 g_base_info_get_namespace (GIBaseInfo *info)
316 {
317   Header *header = (Header *)info->typelib->data;
318
319   g_assert (info->ref_count > 0);
320
321   if (info->type == GI_INFO_TYPE_UNRESOLVED)
322     {
323       GIUnresolvedInfo *unresolved = (GIUnresolvedInfo *)info;
324       
325       return unresolved->namespace;
326     }
327
328   return g_typelib_get_string (info->typelib, header->namespace);
329 }
330
331 gboolean 
332 g_base_info_is_deprecated (GIBaseInfo *info)
333 {
334   switch (info->type)
335     {
336     case GI_INFO_TYPE_FUNCTION:
337     case GI_INFO_TYPE_CALLBACK:
338     case GI_INFO_TYPE_STRUCT:
339     case GI_INFO_TYPE_BOXED:
340     case GI_INFO_TYPE_ENUM:
341     case GI_INFO_TYPE_FLAGS:
342     case GI_INFO_TYPE_OBJECT:
343     case GI_INFO_TYPE_INTERFACE:
344     case GI_INFO_TYPE_CONSTANT:
345     case GI_INFO_TYPE_ERROR_DOMAIN:
346       {
347         CommonBlob *blob = (CommonBlob *)&info->typelib->data[info->offset];
348
349         return blob->deprecated;
350       }
351       break;
352
353     case GI_INFO_TYPE_VALUE:
354       {
355         ValueBlob *blob = (ValueBlob *)&info->typelib->data[info->offset];
356
357         return blob->deprecated;
358       }
359       break;
360
361     case GI_INFO_TYPE_SIGNAL:
362       {
363         SignalBlob *blob = (SignalBlob *)&info->typelib->data[info->offset];
364
365         return blob->deprecated;
366       }
367       break;
368
369     case GI_INFO_TYPE_PROPERTY:
370       {
371         PropertyBlob *blob = (PropertyBlob *)&info->typelib->data[info->offset];
372
373         return blob->deprecated;
374       }
375       break;
376
377     case GI_INFO_TYPE_VFUNC:
378     case GI_INFO_TYPE_FIELD:
379     case GI_INFO_TYPE_ARG:
380     case GI_INFO_TYPE_TYPE:
381     default: ;
382       /* no deprecation flag for these */
383     }
384   
385   return FALSE;
386 }
387
388 static int
389 cmp_annotation (const void *av,
390                 const void *bv)
391 {
392   const AnnotationBlob *a = av;
393   const AnnotationBlob *b = bv;
394  
395   if (b->offset < a->offset)
396     return -1;
397
398   if (b->offset > a->offset)
399     return 1;
400   
401   return 0;
402 }
403
404 const gchar *
405 g_base_info_get_annotation (GIBaseInfo   *info,
406                             const gchar *name)
407 {
408   GIBaseInfo *base = (GIBaseInfo *)info;
409   Header *header = (Header *)base->typelib->data;
410   AnnotationBlob blob, *first, *after, *res, *next;
411   const gchar *rname;
412
413   blob.offset = base->offset;
414   
415   first = (AnnotationBlob *) &base->typelib->data[header->annotations];
416   after = (AnnotationBlob *) &base->typelib->data[header->annotations + 
417                                              header->n_annotations * header->annotation_blob_size];
418
419   res = bsearch (&blob, first, header->n_annotations,
420                  header->annotation_blob_size, cmp_annotation);
421   
422   if (res == NULL)
423     return NULL;
424
425   next = res;
426   do 
427     {
428       res = next;
429       next = res -= header->annotation_blob_size;
430     }
431   while (next >= first && next->offset == base->offset);
432     
433   next = res;
434   do 
435     {
436       res = next;
437       
438       rname = g_typelib_get_string (base->typelib, res->name);
439       if (strcmp (name, rname) == 0)
440         return g_typelib_get_string (base->typelib, res->value);
441
442       next = res += header->annotation_blob_size;
443     }
444   while (next < after && next->offset == base->offset);
445
446   return NULL;
447 }
448
449 GIBaseInfo *
450 g_base_info_get_container (GIBaseInfo *info)
451 {
452   return info->container;
453 }
454
455 GTypelib *
456 g_base_info_get_typelib (GIBaseInfo *info)
457 {
458   return info->typelib;
459 }
460
461 /* GIFunctionInfo functions */
462 const gchar *
463 g_function_info_get_symbol (GIFunctionInfo *info)
464 {
465   GIBaseInfo *base = (GIBaseInfo *)info;
466   FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset];
467
468   return g_typelib_get_string (base->typelib, blob->symbol);
469 }
470
471 GIFunctionInfoFlags
472 g_function_info_get_flags (GIFunctionInfo *info)
473 {
474   GIFunctionInfoFlags flags;
475   GIBaseInfo *base = (GIBaseInfo *)info;
476   FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset];
477   
478   flags = 0;
479
480   /* Make sure we don't flag Constructors as methods */
481   if (base->container != NULL && !blob->constructor)
482     flags = flags | GI_FUNCTION_IS_METHOD;
483     
484   if (blob->constructor)
485     flags = flags | GI_FUNCTION_IS_CONSTRUCTOR;
486
487   if (blob->getter)
488     flags = flags | GI_FUNCTION_IS_GETTER;
489
490   if (blob->setter)
491     flags = flags | GI_FUNCTION_IS_SETTER;
492
493   if (blob->wraps_vfunc)
494     flags = flags | GI_FUNCTION_WRAPS_VFUNC;
495
496   if (blob->throws)
497     flags = flags | GI_FUNCTION_THROWS;
498
499   return flags;
500 }
501
502 GIPropertyInfo *
503 g_function_info_get_property (GIFunctionInfo *info)
504 {
505   GIBaseInfo *base = (GIBaseInfo *)info;
506   FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset];
507   GIInterfaceInfo *container = (GIInterfaceInfo *)base->container;
508   
509   return g_interface_info_get_property (container, blob->index);  
510 }
511
512 GIVFuncInfo *
513 g_function_info_get_vfunc (GIFunctionInfo *info)
514 {
515   GIBaseInfo *base = (GIBaseInfo *)info;
516   FunctionBlob *blob = (FunctionBlob *)&base->typelib->data[base->offset];
517   GIInterfaceInfo *container = (GIInterfaceInfo *)base->container;
518   
519   return g_interface_info_get_vfunc (container, blob->index);  
520 }
521
522
523 /* GICallableInfo functions */
524 static guint32
525 signature_offset (GICallableInfo *info)
526 {
527   int sigoff = -1;
528   switch (info->base.type)
529     {
530     case GI_INFO_TYPE_FUNCTION:
531       sigoff = G_STRUCT_OFFSET (FunctionBlob, signature);
532       break;
533     case GI_INFO_TYPE_VFUNC:
534       sigoff = G_STRUCT_OFFSET (VFuncBlob, signature);
535       break;
536     case GI_INFO_TYPE_CALLBACK:
537       sigoff = G_STRUCT_OFFSET (CallbackBlob, signature);
538       break;
539     case GI_INFO_TYPE_SIGNAL:
540       sigoff = G_STRUCT_OFFSET (SignalBlob, signature);
541       break;
542     }
543   if (sigoff >= 0)
544     return *(guint32 *)&info->base.typelib->data[info->base.offset + sigoff];
545   return 0;
546 }
547
548 GITypeInfo *
549 g_type_info_new (GIBaseInfo    *container,
550                  GTypelib     *typelib,
551                  guint32        offset)
552 {
553   SimpleTypeBlob *type = (SimpleTypeBlob *)&typelib->data[offset];
554
555   return (GITypeInfo *) g_info_new (GI_INFO_TYPE_TYPE, container, typelib, 
556                                     (type->reserved == 0 && type->reserved2 == 0) ? offset : type->offset);
557 }
558
559 /**
560  * g_callable_info_get_return_type:
561  * @info: a #GICallableInfo
562  *
563  * Get the return type of a callable item as
564  * a #GITypeInfo
565  *
566  * Returns: a #GITypeInfo idexing the TypeBlob for the
567  * return type of #info
568  */
569 GITypeInfo *
570 g_callable_info_get_return_type (GICallableInfo *info)
571 {
572   GIBaseInfo *base = (GIBaseInfo *)info;
573   guint32 offset;
574
575   offset = signature_offset (info);
576
577   return g_type_info_new (base, base->typelib, offset);
578 }
579
580 /**
581  * g_callable_info_may_return_null:
582  * @info: a #GICallableInfo
583  *
584  * See if a callable could return NULL.
585  *
586  * Returns: TRUE if callable could return NULL
587  */
588 gboolean
589 g_callable_info_may_return_null (GICallableInfo *info)
590 {
591   GIBaseInfo *base = (GIBaseInfo *)info;
592   SignatureBlob *blob = (SignatureBlob *)&base->typelib->data[signature_offset (info)];
593
594   return blob->may_return_null;
595 }
596
597 /**
598  * g_callable_info_get_caller_owns:
599  * @info: a #GICallableInfo
600  *
601  * See whether the caller owns the return value
602  * of this callable.
603  *
604  * Returns: TRUE if the caller owns the return value, FALSE otherwise.
605  */
606 GITransfer
607 g_callable_info_get_caller_owns (GICallableInfo *info)
608 {
609   GIBaseInfo *base = (GIBaseInfo *)info;
610   SignatureBlob *blob = (SignatureBlob *)&base->typelib->data[signature_offset (info)];
611
612   if (blob->caller_owns_return_value)
613     return GI_TRANSFER_EVERYTHING;
614   else if (blob->caller_owns_return_container)
615     return GI_TRANSFER_CONTAINER;
616   else
617     return GI_TRANSFER_NOTHING;
618 }
619
620 /**
621  * g_callable_info_get_n_args:
622  * @info: a #GICallableInfo
623  *
624  * Get the number of arguments (both IN and OUT) for this callable.
625  *
626  * Returns: The number of arguments this callable expects.
627  */
628 gint 
629 g_callable_info_get_n_args (GICallableInfo *info)
630 {
631   GIBaseInfo *base = (GIBaseInfo *)info;
632   gint offset;
633   SignatureBlob *blob;
634
635   offset = signature_offset (info);
636   blob = (SignatureBlob *)&base->typelib->data[offset];
637
638   return blob->n_arguments;
639 }
640
641 /**
642  * g_callable_info_get_arg:
643  * @info: a #GICallableInfo
644  *
645  * Get information about a particular argument of this callable.
646  *
647  * Returns: A #GIArgInfo indexing the typelib on the given argument.
648  */
649 GIArgInfo *
650 g_callable_info_get_arg (GICallableInfo *info,
651                          gint           n)
652 {
653   GIBaseInfo *base = (GIBaseInfo *)info;
654   Header *header = (Header *)base->typelib->data;
655   gint offset;
656
657   offset = signature_offset (info);
658   
659   return (GIArgInfo *) g_info_new (GI_INFO_TYPE_ARG, base, base->typelib, 
660                                    offset + header->signature_blob_size + n * header->arg_blob_size);
661 }
662
663 /* GIArgInfo function */
664 GIDirection
665 g_arg_info_get_direction (GIArgInfo *info)
666 {
667   GIBaseInfo *base = (GIBaseInfo *)info;
668   ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
669   
670   if (blob->in && blob->out)
671     return GI_DIRECTION_INOUT;
672   else if (blob->out)
673     return GI_DIRECTION_OUT;
674   else
675     return GI_DIRECTION_IN;
676 }
677
678 gboolean
679 g_arg_info_is_return_value (GIArgInfo *info)
680 {
681   GIBaseInfo *base = (GIBaseInfo *)info;
682   ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
683   
684   return blob->return_value;
685 }
686
687 gboolean
688 g_arg_info_is_dipper (GIArgInfo *info)
689 {
690   GIBaseInfo *base = (GIBaseInfo *)info;
691   ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
692   
693   return blob->dipper;
694 }
695
696 gboolean
697 g_arg_info_is_optional (GIArgInfo *info)
698 {
699   GIBaseInfo *base = (GIBaseInfo *)info;
700   ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
701   
702   return blob->optional;
703 }
704
705 gboolean
706 g_arg_info_may_be_null (GIArgInfo *info)
707 {
708   GIBaseInfo *base = (GIBaseInfo *)info;
709   ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
710   
711   return blob->allow_none;
712 }
713
714 GITransfer
715 g_arg_info_get_ownership_transfer (GIArgInfo *info)
716 {
717   GIBaseInfo *base = (GIBaseInfo *)info;
718   ArgBlob *blob = (ArgBlob *)&base->typelib->data[base->offset];
719
720   if (blob->transfer_ownership)
721     return GI_TRANSFER_EVERYTHING;
722   else if (blob->transfer_container_ownership)
723     return GI_TRANSFER_CONTAINER;
724   else
725     return GI_TRANSFER_NOTHING;
726 }
727
728 GITypeInfo *
729 g_arg_info_get_type (GIArgInfo *info)
730 {
731   GIBaseInfo *base = (GIBaseInfo *)info;
732  
733   return g_type_info_new (base, base->typelib, base->offset + 8);
734 }
735
736 /* GITypeInfo functions */
737 gboolean
738 g_type_info_is_pointer (GITypeInfo *info)
739 {
740   GIBaseInfo *base = (GIBaseInfo *)info;
741   SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
742   
743   if (type->reserved == 0 && type->reserved2 == 0)
744     return type->pointer;
745   else
746     {
747       InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset];
748       
749       return iface->pointer;
750     }
751 }
752
753 GITypeTag
754 g_type_info_get_tag (GITypeInfo *info)
755 {
756   GIBaseInfo *base = (GIBaseInfo *)info;
757   SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
758
759   if (type->reserved == 0 && type->reserved2 == 0)
760     return type->tag;
761   else
762     {
763       InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&base->typelib->data[base->offset];
764
765       return iface->tag;
766     }
767 }
768
769 GITypeInfo *
770 g_type_info_get_param_type (GITypeInfo *info,
771                             gint       n)
772 {
773   GIBaseInfo *base = (GIBaseInfo *)info;
774   SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
775   
776   if (!(type->reserved == 0 && type->reserved2 == 0))
777     {
778       ParamTypeBlob *param = (ParamTypeBlob *)&base->typelib->data[base->offset];
779
780       switch (param->tag)
781         {
782         case GI_TYPE_TAG_ARRAY: 
783         case GI_TYPE_TAG_GLIST:
784         case GI_TYPE_TAG_GSLIST:
785         case GI_TYPE_TAG_GHASH:
786           return g_type_info_new (base, base->typelib, base->offset + 4 + 4 * n);
787           break;
788           
789         default: ;
790         }
791     }
792       
793   return NULL;
794 }
795
796 GIBaseInfo *
797 g_type_info_get_interface (GITypeInfo *info)
798 {
799   GIBaseInfo *base = (GIBaseInfo *)info;
800   SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
801   
802   if (!(type->reserved == 0 && type->reserved2 == 0))
803     {
804       InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&base->typelib->data[base->offset];
805       
806       if (blob->tag == GI_TYPE_TAG_INTERFACE)
807         return g_info_from_entry (base->typelib, blob->interface);
808     }
809
810   return NULL;
811 }
812
813 gint
814 g_type_info_get_array_length (GITypeInfo *info)
815 {
816   GIBaseInfo *base = (GIBaseInfo *)info;
817   SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
818   
819   if (!(type->reserved == 0 && type->reserved2 == 0))
820     {
821       ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset];
822
823       if (blob->tag == GI_TYPE_TAG_ARRAY)
824         {
825           if (blob->has_length)
826             return blob->length;
827         }
828     }
829
830   return -1;
831 }
832
833 gint
834 g_type_info_get_array_fixed_size (GITypeInfo *info)
835 {
836   GIBaseInfo *base = (GIBaseInfo *)info;
837   SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
838   
839   if (!(type->reserved == 0 && type->reserved2 == 0))
840     {
841       ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset];
842
843       if (blob->tag == GI_TYPE_TAG_ARRAY)
844         {
845           if (blob->has_size)
846             return blob->size;
847         }
848     }
849
850   return -1;
851 }
852
853 gboolean
854 g_type_info_is_zero_terminated (GITypeInfo *info)
855 {
856   GIBaseInfo *base = (GIBaseInfo *)info;
857   SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
858   
859   if (!(type->reserved == 0 && type->reserved2 == 0))
860     {
861       ArrayTypeBlob *blob = (ArrayTypeBlob *)&base->typelib->data[base->offset];
862
863       if (blob->tag == GI_TYPE_TAG_ARRAY)
864         return blob->zero_terminated;
865     }
866
867   return FALSE;
868 }
869
870 gint
871 g_type_info_get_n_error_domains (GITypeInfo *info)
872 {
873   GIBaseInfo *base = (GIBaseInfo *)info;
874   SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
875   
876   if (!(type->reserved == 0 && type->reserved2 == 0))
877     {
878       ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset];
879
880       if (blob->tag == GI_TYPE_TAG_ERROR)
881         return blob->n_domains;
882     }
883
884   return 0;
885 }
886
887 GIErrorDomainInfo *
888 g_type_info_get_error_domain (GITypeInfo *info,
889                               gint       n)
890 {
891   GIBaseInfo *base = (GIBaseInfo *)info;
892   SimpleTypeBlob *type = (SimpleTypeBlob *)&base->typelib->data[base->offset];
893   
894   if (!(type->reserved == 0 && type->reserved2 == 0))
895     {
896       ErrorTypeBlob *blob = (ErrorTypeBlob *)&base->typelib->data[base->offset];
897
898       if (blob->tag == GI_TYPE_TAG_ERROR)
899         return (GIErrorDomainInfo *) g_info_from_entry (base->typelib, 
900                                                         blob->domains[n]);
901     }
902
903   return NULL;
904 }
905
906
907 /* GIErrorDomainInfo functions */
908 const gchar *
909 g_error_domain_info_get_quark (GIErrorDomainInfo *info)
910 {
911   GIBaseInfo *base = (GIBaseInfo *)info;
912   ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset];
913
914   return g_typelib_get_string (base->typelib, blob->get_quark);
915 }
916
917 GIInterfaceInfo *
918 g_error_domain_info_get_codes (GIErrorDomainInfo *info)
919 {
920   GIBaseInfo *base = (GIBaseInfo *)info;
921   ErrorDomainBlob *blob = (ErrorDomainBlob *)&base->typelib->data[base->offset];
922   
923   return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->error_codes);
924 }
925
926
927 /* GIValueInfo functions */ 
928 glong
929 g_value_info_get_value (GIValueInfo *info)
930 {
931   GIBaseInfo *base = (GIBaseInfo *)info;
932   ValueBlob *blob = (ValueBlob *)&base->typelib->data[base->offset];
933
934   return (glong)blob->value;
935 }
936
937 /* GIFieldInfo functions */
938 GIFieldInfoFlags
939 g_field_info_get_flags (GIFieldInfo *info)
940 {
941   GIFieldInfoFlags flags;
942
943   GIBaseInfo *base = (GIBaseInfo *)info;
944   FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset];
945
946   flags = 0;
947
948   if (blob->readable)
949     flags = flags | GI_FIELD_IS_READABLE;
950
951   if (blob->writable)
952     flags = flags | GI_FIELD_IS_WRITABLE;
953
954   return flags;
955 }
956
957 gint
958 g_field_info_get_size (GIFieldInfo *info)
959 {
960   GIBaseInfo *base = (GIBaseInfo *)info;
961   FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset];
962   
963   return blob->bits;
964 }
965
966 gint
967 g_field_info_get_offset (GIFieldInfo *info)
968 {
969   GIBaseInfo *base = (GIBaseInfo *)info;
970   FieldBlob *blob = (FieldBlob *)&base->typelib->data[base->offset];
971   
972   return blob->struct_offset;
973 }
974
975 GITypeInfo *
976 g_field_info_get_type (GIFieldInfo *info)
977 {
978   GIBaseInfo *base = (GIBaseInfo *)info;
979   
980   return g_type_info_new (base, base->typelib, base->offset + 8);
981 }
982
983 /* GIRegisteredTypeInfo functions */
984 const gchar *
985 g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info)
986 {
987   GIBaseInfo *base = (GIBaseInfo *)info;
988   RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->typelib->data[base->offset];
989
990   if (blob->gtype_name)
991     return g_typelib_get_string (base->typelib, blob->gtype_name);
992
993   return NULL;
994 }
995
996 const gchar *
997 g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info)
998 {
999   GIBaseInfo *base = (GIBaseInfo *)info;
1000   RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&base->typelib->data[base->offset];
1001
1002   if (blob->gtype_init)
1003     return g_typelib_get_string (base->typelib, blob->gtype_init);
1004
1005   return NULL;
1006 }
1007
1008 GType
1009 g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info)
1010 {
1011   const char *type_init;
1012   GType (* get_type_func) (void);
1013
1014   type_init = g_registered_type_info_get_type_init (info);  
1015   
1016   if (type_init == NULL)
1017     return G_TYPE_NONE;
1018   
1019   get_type_func = NULL;
1020   if (!g_typelib_symbol (((GIBaseInfo*)info)->typelib,
1021                          type_init,
1022                          (void**) &get_type_func))
1023     return G_TYPE_NONE;
1024   
1025   return (* get_type_func) ();
1026 }
1027
1028 /* GIStructInfo functions */
1029 gint
1030 g_struct_info_get_n_fields (GIStructInfo *info)
1031 {
1032   GIBaseInfo *base = (GIBaseInfo *)info;
1033   StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
1034   
1035   return blob->n_fields;
1036 }
1037
1038 GIFieldInfo *
1039 g_struct_info_get_field (GIStructInfo *info,
1040                          gint         n)
1041 {
1042   GIBaseInfo *base = (GIBaseInfo *)info;
1043   Header *header = (Header *)base->typelib->data;  
1044  
1045   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, 
1046                                      base->offset + header->struct_blob_size + 
1047                                      n * header->field_blob_size);
1048 }
1049
1050 gint
1051 g_struct_info_get_n_methods (GIStructInfo *info)
1052 {
1053   GIBaseInfo *base = (GIBaseInfo *)info;
1054   StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
1055   
1056   return blob->n_methods;
1057 }
1058
1059 GIFunctionInfo *
1060 g_struct_info_get_method (GIStructInfo *info,
1061                           gint         n)
1062 {
1063   GIBaseInfo *base = (GIBaseInfo *)info;
1064   StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
1065   Header *header = (Header *)base->typelib->data;  
1066   gint offset;
1067
1068   offset = base->offset + header->struct_blob_size 
1069     + blob->n_fields * header->field_blob_size 
1070     + n * header->function_blob_size;
1071   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
1072                                         base->typelib, offset);
1073 }
1074
1075 static GIFunctionInfo *
1076 find_method (GIBaseInfo   *base,
1077              guint32       offset,
1078              gint          n_methods,
1079              const gchar  *name)
1080 {
1081   /* FIXME hash */
1082   Header *header = (Header *)base->typelib->data;  
1083   gint i;
1084
1085   for (i = 0; i < n_methods; i++)
1086     {
1087       FunctionBlob *fblob = (FunctionBlob *)&base->typelib->data[offset];
1088       const gchar *fname = (const gchar *)&base->typelib->data[fblob->name];
1089
1090       if (strcmp (name, fname) == 0)
1091         return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
1092                                               base->typelib, offset);  
1093       
1094       offset += header->function_blob_size;
1095     }
1096       
1097   return NULL;
1098 }
1099
1100 GIFunctionInfo *
1101 g_struct_info_find_method (GIStructInfo *info,
1102                            const gchar  *name)
1103 {
1104   gint offset;
1105   GIBaseInfo *base = (GIBaseInfo *)info;
1106   Header *header = (Header *)base->typelib->data;  
1107   StructBlob *blob = (StructBlob *)&base->typelib->data[base->offset];
1108
1109   offset = base->offset + header->struct_blob_size
1110     + blob->n_fields * header->field_blob_size;
1111
1112   return find_method (base, offset, blob->n_methods, name);
1113 }
1114
1115 gint
1116 g_enum_info_get_n_values (GIEnumInfo *info)
1117 {
1118   GIBaseInfo *base = (GIBaseInfo *)info;
1119   EnumBlob *blob = (EnumBlob *)&base->typelib->data[base->offset];
1120
1121   return blob->n_values;
1122 }
1123
1124 GIValueInfo *
1125 g_enum_info_get_value (GIEnumInfo *info,
1126                        gint            n)
1127 {
1128   GIBaseInfo *base = (GIBaseInfo *)info;
1129   Header *header = (Header *)base->typelib->data;  
1130   gint offset;
1131
1132   offset = base->offset + header->enum_blob_size 
1133     + n * header->value_blob_size;
1134   return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, base, base->typelib, offset);
1135 }
1136
1137 /* GIObjectInfo functions */
1138 GIObjectInfo *
1139 g_object_info_get_parent (GIObjectInfo *info)
1140 {
1141   GIBaseInfo *base = (GIBaseInfo *)info;
1142   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1143
1144   if (blob->parent)
1145     return (GIObjectInfo *) g_info_from_entry (base->typelib, blob->parent);
1146   else
1147     return NULL;
1148 }
1149
1150 gboolean
1151 g_object_info_get_abstract (GIObjectInfo    *info)
1152 {
1153   GIBaseInfo *base = (GIBaseInfo *)info;
1154   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1155   return blob->abstract != 0;
1156 }
1157
1158 const gchar *
1159 g_object_info_get_type_name (GIObjectInfo *info)
1160 {
1161   GIBaseInfo *base = (GIBaseInfo *)info;
1162   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1163
1164   return g_typelib_get_string (base->typelib, blob->gtype_name);
1165 }
1166
1167 const gchar *
1168 g_object_info_get_type_init (GIObjectInfo *info)
1169 {
1170   GIBaseInfo *base = (GIBaseInfo *)info;
1171   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1172
1173   return g_typelib_get_string (base->typelib, blob->gtype_init);
1174 }
1175
1176 gint
1177 g_object_info_get_n_interfaces (GIObjectInfo *info)
1178 {
1179   GIBaseInfo *base = (GIBaseInfo *)info;
1180   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1181
1182   return blob->n_interfaces;
1183 }
1184
1185 GIInterfaceInfo *
1186 g_object_info_get_interface (GIObjectInfo *info,
1187                              gint          n)
1188 {
1189   GIBaseInfo *base = (GIBaseInfo *)info;
1190   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1191
1192   return (GIInterfaceInfo *) g_info_from_entry (base->typelib, blob->interfaces[n]);
1193 }
1194
1195 gint
1196 g_object_info_get_n_fields (GIObjectInfo *info)
1197 {
1198   GIBaseInfo *base = (GIBaseInfo *)info;
1199   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1200
1201   return blob->n_fields;
1202 }
1203
1204 GIFieldInfo *
1205 g_object_info_get_field (GIObjectInfo *info,
1206                          gint          n)
1207 {
1208   gint offset;
1209   GIBaseInfo *base = (GIBaseInfo *)info;
1210   Header *header = (Header *)base->typelib->data;  
1211   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1212   
1213   offset = base->offset + header->object_blob_size
1214     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1215     + n * header->field_blob_size;
1216   
1217   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, offset);
1218 }
1219
1220 gint
1221 g_object_info_get_n_properties (GIObjectInfo *info)
1222 {
1223   GIBaseInfo *base = (GIBaseInfo *)info;
1224   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1225
1226   return blob->n_properties;  
1227 }
1228
1229 GIPropertyInfo *
1230 g_object_info_get_property (GIObjectInfo *info,
1231                             gint          n)
1232 {
1233   gint offset;
1234   GIBaseInfo *base = (GIBaseInfo *)info;
1235   Header *header = (Header *)base->typelib->data;  
1236   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1237   
1238   offset = base->offset + header->object_blob_size
1239     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1240     + blob->n_fields * header->field_blob_size
1241     + n * header->property_blob_size;
1242
1243   return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, 
1244                                         base->typelib, offset);
1245 }
1246
1247 gint
1248 g_object_info_get_n_methods (GIObjectInfo *info)
1249 {
1250   GIBaseInfo *base = (GIBaseInfo *)info;
1251   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1252
1253   return blob->n_methods;
1254 }
1255
1256 GIFunctionInfo *
1257 g_object_info_get_method (GIObjectInfo *info,
1258                           gint          n)
1259 {
1260   gint offset;
1261   GIBaseInfo *base = (GIBaseInfo *)info;
1262   Header *header = (Header *)base->typelib->data;  
1263   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1264   
1265   offset = base->offset + header->object_blob_size
1266     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1267     + blob->n_fields * header->field_blob_size
1268     + blob->n_properties * header->property_blob_size
1269     + n * header->function_blob_size;
1270
1271     return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
1272                                           base->typelib, offset);  
1273 }
1274
1275 GIFunctionInfo *
1276 g_object_info_find_method (GIObjectInfo *info,
1277                            const gchar  *name)
1278 {
1279   gint offset;
1280   GIBaseInfo *base = (GIBaseInfo *)info;
1281   Header *header = (Header *)base->typelib->data;  
1282   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1283
1284   offset = base->offset + header->object_blob_size
1285     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1286     + blob->n_fields * header->field_blob_size +
1287     + blob->n_properties * header->property_blob_size;
1288
1289   return find_method (base, offset, blob->n_methods, name);
1290 }
1291
1292 gint
1293 g_object_info_get_n_signals (GIObjectInfo *info)
1294 {
1295   GIBaseInfo *base = (GIBaseInfo *)info;
1296   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1297
1298   return blob->n_signals;
1299 }
1300
1301 GISignalInfo *
1302 g_object_info_get_signal (GIObjectInfo *info,
1303                           gint          n)
1304 {
1305   gint offset;
1306   GIBaseInfo *base = (GIBaseInfo *)info;
1307   Header *header = (Header *)base->typelib->data;  
1308   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1309   
1310   offset = base->offset + header->object_blob_size
1311     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1312     + blob->n_fields * header->field_blob_size
1313     + blob->n_properties * header->property_blob_size
1314     + blob->n_methods * header->function_blob_size 
1315     + n * header->signal_blob_size;
1316
1317   return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, 
1318                                       base->typelib, offset);  
1319 }
1320
1321 gint
1322 g_object_info_get_n_vfuncs (GIObjectInfo *info)
1323 {
1324   GIBaseInfo *base = (GIBaseInfo *)info;
1325   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1326   
1327   return blob->n_vfuncs;
1328 }
1329
1330 GIVFuncInfo *
1331 g_object_info_get_vfunc (GIObjectInfo *info,
1332                          gint          n)
1333 {
1334   gint offset;
1335   GIBaseInfo *base = (GIBaseInfo *)info;
1336   Header *header = (Header *)base->typelib->data;  
1337   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1338   
1339   offset = base->offset + header->object_blob_size
1340     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1341     + blob->n_fields * header->field_blob_size
1342     + blob->n_properties * header->property_blob_size
1343     + blob->n_methods * header->function_blob_size 
1344     + blob->n_signals * header->signal_blob_size 
1345     + n * header->vfunc_blob_size;
1346
1347   return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, 
1348                                      base->typelib, offset);  
1349 }
1350
1351 gint
1352 g_object_info_get_n_constants (GIObjectInfo *info)
1353 {
1354   GIBaseInfo *base = (GIBaseInfo *)info;
1355   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1356   
1357   return blob->n_constants;
1358 }
1359
1360 GIConstantInfo *
1361 g_object_info_get_constant (GIObjectInfo *info,
1362                             gint          n)
1363 {
1364   gint offset;
1365   GIBaseInfo *base = (GIBaseInfo *)info;
1366   Header *header = (Header *)base->typelib->data;  
1367   ObjectBlob *blob = (ObjectBlob *)&base->typelib->data[base->offset];
1368   
1369   offset = base->offset + header->object_blob_size
1370     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1371     + blob->n_fields * header->field_blob_size
1372     + blob->n_properties * header->property_blob_size
1373     + blob->n_methods * header->function_blob_size 
1374     + blob->n_signals * header->signal_blob_size 
1375     + blob->n_vfuncs * header->vfunc_blob_size 
1376     + n * header->constant_blob_size;
1377
1378   return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, 
1379                                         base->typelib, offset);  
1380 }
1381
1382
1383 /* GIInterfaceInfo functions */
1384 gint
1385 g_interface_info_get_n_prerequisites (GIInterfaceInfo *info)
1386 {
1387   GIBaseInfo *base = (GIBaseInfo *)info;
1388   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1389
1390   return blob->n_prerequisites;
1391 }
1392
1393 GIBaseInfo *
1394 g_interface_info_get_prerequisite (GIInterfaceInfo *info,
1395                                    gint            n)
1396 {
1397   GIBaseInfo *base = (GIBaseInfo *)info;
1398   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1399
1400   return g_info_from_entry (base->typelib, blob->prerequisites[n]);
1401 }
1402
1403
1404 gint
1405 g_interface_info_get_n_properties (GIInterfaceInfo *info)
1406 {
1407   GIBaseInfo *base = (GIBaseInfo *)info;
1408   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1409
1410   return blob->n_properties;  
1411 }
1412
1413 GIPropertyInfo *
1414 g_interface_info_get_property (GIInterfaceInfo *info,
1415                                gint            n)
1416 {
1417   gint offset;
1418   GIBaseInfo *base = (GIBaseInfo *)info;
1419   Header *header = (Header *)base->typelib->data;  
1420   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1421   
1422   offset = base->offset + header->interface_blob_size
1423     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1424     + n * header->property_blob_size;
1425
1426   return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, base, 
1427                                         base->typelib, offset);
1428 }
1429
1430 gint
1431 g_interface_info_get_n_methods (GIInterfaceInfo *info)
1432 {
1433   GIBaseInfo *base = (GIBaseInfo *)info;
1434   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1435
1436   return blob->n_methods;
1437 }
1438
1439 GIFunctionInfo *
1440 g_interface_info_get_method (GIInterfaceInfo *info,
1441                              gint            n)
1442 {
1443   gint offset;
1444   GIBaseInfo *base = (GIBaseInfo *)info;
1445   Header *header = (Header *)base->typelib->data;  
1446   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1447   
1448   offset = base->offset + header->interface_blob_size
1449     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1450     + blob->n_properties * header->property_blob_size 
1451     + n * header->function_blob_size;
1452   
1453   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
1454                                         base->typelib, offset);  
1455 }
1456
1457 GIFunctionInfo *
1458 g_interface_info_find_method (GIInterfaceInfo *info,
1459                               const gchar     *name)
1460 {
1461   gint offset;
1462   GIBaseInfo *base = (GIBaseInfo *)info;
1463   Header *header = (Header *)base->typelib->data;  
1464   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1465
1466   offset = base->offset + header->interface_blob_size
1467     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1468     + blob->n_properties * header->property_blob_size;
1469
1470   return find_method (base, offset, blob->n_methods, name);
1471 }
1472
1473 gint
1474 g_interface_info_get_n_signals (GIInterfaceInfo *info)
1475 {
1476   GIBaseInfo *base = (GIBaseInfo *)info;
1477   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1478
1479   return blob->n_signals;
1480 }
1481
1482 GISignalInfo *
1483 g_interface_info_get_signal (GIInterfaceInfo *info,
1484                              gint            n)
1485 {
1486   gint offset;
1487   GIBaseInfo *base = (GIBaseInfo *)info;
1488   Header *header = (Header *)base->typelib->data;  
1489   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1490   
1491   offset = base->offset + header->interface_blob_size 
1492     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1493     + blob->n_properties * header->property_blob_size 
1494     + blob->n_methods * header->function_blob_size 
1495     + n * header->signal_blob_size;
1496   
1497   return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, base, 
1498                                       base->typelib, offset);  
1499 }
1500
1501 gint
1502 g_interface_info_get_n_vfuncs (GIInterfaceInfo *info)
1503 {
1504   GIBaseInfo *base = (GIBaseInfo *)info;
1505   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1506
1507   return blob->n_vfuncs;
1508 }
1509
1510 GIVFuncInfo *
1511 g_interface_info_get_vfunc (GIInterfaceInfo *info,
1512                             gint            n)
1513 {
1514   gint offset;
1515   GIBaseInfo *base = (GIBaseInfo *)info;
1516   Header *header = (Header *)base->typelib->data;  
1517   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1518   
1519   offset = base->offset + header->interface_blob_size 
1520     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1521     + blob->n_properties * header->property_blob_size 
1522     + blob->n_methods * header->function_blob_size 
1523     + blob->n_signals * header->signal_blob_size
1524     + n * header->vfunc_blob_size;
1525   
1526   return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, base, 
1527                                      base->typelib, offset);  
1528 }
1529
1530 gint
1531 g_interface_info_get_n_constants (GIInterfaceInfo *info)
1532 {
1533   GIBaseInfo *base = (GIBaseInfo *)info;
1534   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1535   
1536   return blob->n_constants;
1537 }
1538
1539 GIConstantInfo *
1540 g_interface_info_get_constant (GIInterfaceInfo *info,
1541                                gint             n)
1542 {
1543   gint offset;
1544   GIBaseInfo *base = (GIBaseInfo *)info;
1545   Header *header = (Header *)base->typelib->data;  
1546   InterfaceBlob *blob = (InterfaceBlob *)&base->typelib->data[base->offset];
1547   
1548   offset = base->offset + header->interface_blob_size
1549     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1550     + blob->n_properties * header->property_blob_size
1551     + blob->n_methods * header->function_blob_size 
1552     + blob->n_signals * header->signal_blob_size 
1553     + blob->n_vfuncs * header->vfunc_blob_size 
1554     + n * header->constant_blob_size;
1555
1556   return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, 
1557                                         base->typelib, offset);  
1558 }
1559
1560
1561
1562
1563 /* GIPropertyInfo functions */
1564 GParamFlags
1565 g_property_info_get_flags (GIPropertyInfo *info)
1566 {
1567   GParamFlags flags;
1568   GIBaseInfo *base = (GIBaseInfo *)info;
1569   PropertyBlob *blob = (PropertyBlob *)&base->typelib->data[base->offset];
1570   
1571   flags = 0;
1572
1573   if (blob->readable)
1574     flags = flags | G_PARAM_READABLE;
1575
1576   if (blob->writable)
1577     flags = flags | G_PARAM_WRITABLE;
1578
1579   if (blob->construct)
1580     flags = flags | G_PARAM_CONSTRUCT;
1581
1582   if (blob->construct_only)
1583     flags = flags | G_PARAM_CONSTRUCT_ONLY;
1584
1585   return flags;
1586 }
1587
1588 GITypeInfo *
1589 g_property_info_get_type (GIPropertyInfo *info)
1590 {
1591   GIBaseInfo *base = (GIBaseInfo *)info;
1592
1593   return g_type_info_new (base, base->typelib, base->offset + 8);  
1594 }
1595
1596
1597 /* GISignalInfo functions */
1598 GSignalFlags
1599 g_signal_info_get_flags (GISignalInfo *info)
1600 {
1601   GSignalFlags flags;
1602
1603   GIBaseInfo *base = (GIBaseInfo *)info;
1604   SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset];
1605
1606   flags = 0;
1607
1608   if (blob->run_first)
1609     flags = flags | G_SIGNAL_RUN_FIRST;
1610
1611   if (blob->run_last)
1612     flags = flags | G_SIGNAL_RUN_LAST;
1613
1614   if (blob->run_cleanup)
1615     flags = flags | G_SIGNAL_RUN_CLEANUP;
1616
1617   if (blob->no_recurse)
1618     flags = flags | G_SIGNAL_NO_RECURSE;
1619
1620   if (blob->detailed)
1621     flags = flags | G_SIGNAL_DETAILED;
1622
1623   if (blob->action)
1624     flags = flags | G_SIGNAL_ACTION;
1625
1626   if (blob->no_hooks)
1627     flags = flags | G_SIGNAL_NO_HOOKS;
1628
1629   return flags;
1630 }
1631
1632 GIVFuncInfo *
1633 g_signal_info_get_class_closure (GISignalInfo *info)
1634 {
1635   GIBaseInfo *base = (GIBaseInfo *)info;
1636   SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset];
1637
1638   if (blob->has_class_closure)
1639     return g_interface_info_get_vfunc ((GIInterfaceInfo *)base->container, blob->class_closure);
1640
1641   return NULL;
1642 }
1643
1644 gboolean
1645 g_signal_info_true_stops_emit (GISignalInfo *info)
1646 {
1647   GIBaseInfo *base = (GIBaseInfo *)info;
1648   SignalBlob *blob = (SignalBlob *)&base->typelib->data[base->offset];
1649
1650   return blob->true_stops_emit;
1651 }
1652
1653 /* GIVFuncInfo functions */
1654 GIVFuncInfoFlags
1655 g_vfunc_info_get_flags (GIVFuncInfo *info)
1656 {
1657   GIVFuncInfoFlags flags;
1658
1659   GIBaseInfo *base = (GIBaseInfo *)info;
1660   VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset];
1661
1662   flags = 0;
1663
1664   if (blob->must_chain_up)
1665     flags = flags | GI_VFUNC_MUST_CHAIN_UP;
1666
1667   if (blob->must_be_implemented)
1668     flags = flags | GI_VFUNC_MUST_OVERRIDE;
1669
1670   if (blob->must_not_be_implemented)
1671     flags = flags | GI_VFUNC_MUST_NOT_OVERRIDE;
1672
1673   return flags;
1674 }
1675
1676 gint
1677 g_vfunc_info_get_offset (GIVFuncInfo *info)
1678 {
1679   GIBaseInfo *base = (GIBaseInfo *)info;
1680   VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset];
1681   
1682   return blob->struct_offset;
1683 }
1684
1685 GISignalInfo *
1686 g_vfunc_info_get_signal (GIVFuncInfo *info)
1687 {
1688   GIBaseInfo *base = (GIBaseInfo *)info;
1689   VFuncBlob *blob = (VFuncBlob *)&base->typelib->data[base->offset];
1690
1691   if (blob->class_closure)
1692     return g_interface_info_get_signal ((GIInterfaceInfo *)base->container, blob->signal);
1693   
1694   return NULL;
1695 }
1696
1697
1698 /* GIConstantInfo functions */
1699 GITypeInfo *
1700 g_constant_info_get_type (GIConstantInfo *info)
1701 {
1702   GIBaseInfo *base = (GIBaseInfo *)info;
1703   
1704   return g_type_info_new (base, base->typelib, base->offset + 8);
1705 }
1706
1707 gint
1708 g_constant_info_get_value (GIConstantInfo *info, 
1709                            GArgument      *value)
1710 {
1711   GIBaseInfo *base = (GIBaseInfo *)info;
1712   ConstantBlob *blob = (ConstantBlob *)&base->typelib->data[base->offset];
1713
1714   /* FIXME non-basic types ? */
1715   if (blob->type.reserved == 0 && blob->type.reserved2 == 0)
1716     {
1717       if (blob->type.pointer)
1718         value->v_pointer = g_memdup (&base->typelib->data[blob->offset], blob->size);
1719       else
1720         {
1721           switch (blob->type.tag)
1722             {
1723             case GI_TYPE_TAG_BOOLEAN:
1724               value->v_boolean = *(gboolean*)&base->typelib->data[blob->offset];
1725               break;
1726             case GI_TYPE_TAG_INT8:
1727               value->v_int8 = *(gint8*)&base->typelib->data[blob->offset];
1728               break;
1729             case GI_TYPE_TAG_UINT8:
1730               value->v_uint8 = *(guint8*)&base->typelib->data[blob->offset];
1731               break;
1732             case GI_TYPE_TAG_INT16:
1733               value->v_int16 = *(gint16*)&base->typelib->data[blob->offset];
1734               break;
1735             case GI_TYPE_TAG_UINT16:
1736               value->v_uint16 = *(guint16*)&base->typelib->data[blob->offset];
1737               break;
1738             case GI_TYPE_TAG_INT32:
1739               value->v_int32 = *(gint32*)&base->typelib->data[blob->offset];
1740               break;
1741             case GI_TYPE_TAG_UINT32:
1742               value->v_uint32 = *(guint32*)&base->typelib->data[blob->offset];
1743               break;
1744             case GI_TYPE_TAG_INT64:
1745               value->v_int64 = *(gint64*)&base->typelib->data[blob->offset];
1746               break;
1747             case GI_TYPE_TAG_UINT64:
1748               value->v_uint64 = *(guint64*)&base->typelib->data[blob->offset];
1749               break;
1750             case GI_TYPE_TAG_FLOAT:
1751               value->v_float = *(gfloat*)&base->typelib->data[blob->offset];
1752               break;
1753             case GI_TYPE_TAG_DOUBLE:
1754               value->v_double = *(gdouble*)&base->typelib->data[blob->offset];
1755               break;
1756             case GI_TYPE_TAG_TIME_T:
1757               value->v_long = *(long*)&base->typelib->data[blob->offset];
1758               break;
1759             case GI_TYPE_TAG_INT:
1760               value->v_int = *(gint*)&base->typelib->data[blob->offset];
1761               break;
1762             case GI_TYPE_TAG_UINT:
1763               value->v_uint = *(guint*)&base->typelib->data[blob->offset];
1764               break;
1765             case GI_TYPE_TAG_LONG:
1766               value->v_long = *(glong*)&base->typelib->data[blob->offset];
1767               break;
1768             case GI_TYPE_TAG_ULONG:
1769               value->v_ulong = *(gulong*)&base->typelib->data[blob->offset];
1770               break;
1771             }
1772         }
1773     }
1774
1775   return blob->size;
1776 }
1777
1778 /* GIUnionInfo functions */
1779 gint
1780 g_union_info_get_n_fields  (GIUnionInfo *info)
1781 {
1782   GIBaseInfo *base = (GIBaseInfo *)info;
1783   UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
1784   
1785   return blob->n_fields;
1786 }
1787
1788 GIFieldInfo *
1789 g_union_info_get_field (GIUnionInfo *info,
1790                         gint         n)
1791 {
1792   GIBaseInfo *base = (GIBaseInfo *)info;
1793   Header *header = (Header *)base->typelib->data;  
1794  
1795   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, base, base->typelib, 
1796                                      base->offset + header->union_blob_size + 
1797                                      n * header->field_blob_size);
1798 }
1799
1800 gint
1801 g_union_info_get_n_methods (GIUnionInfo *info)
1802 {
1803   GIBaseInfo *base = (GIBaseInfo *)info;
1804   UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
1805   
1806   return blob->n_functions;
1807 }
1808
1809 GIFunctionInfo *
1810 g_union_info_get_method (GIUnionInfo *info,
1811                          gint         n)
1812 {
1813   GIBaseInfo *base = (GIBaseInfo *)info;
1814   UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
1815   Header *header = (Header *)base->typelib->data;  
1816   gint offset;
1817
1818   offset = base->offset + header->union_blob_size 
1819     + blob->n_fields * header->field_blob_size 
1820     + n * header->function_blob_size;
1821   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
1822                                         base->typelib, offset);
1823 }
1824
1825 gboolean
1826 g_union_info_is_discriminated (GIUnionInfo *info)
1827 {
1828   GIBaseInfo *base = (GIBaseInfo *)info;
1829   UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
1830   
1831   return blob->discriminated;
1832 }
1833
1834 gint
1835 g_union_info_get_discriminator_offset (GIUnionInfo *info)
1836 {
1837   GIBaseInfo *base = (GIBaseInfo *)info;
1838   UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
1839   
1840   return blob->discriminator_offset;
1841 }
1842
1843 GITypeInfo *
1844 g_union_info_get_discriminator_type (GIUnionInfo *info)
1845 {
1846   GIBaseInfo *base = (GIBaseInfo *)info;
1847  
1848   return g_type_info_new (base, base->typelib, base->offset + 24);
1849 }
1850
1851 GIConstantInfo *
1852 g_union_info_get_discriminator (GIUnionInfo *info,
1853                                 gint         n)
1854 {
1855   GIBaseInfo *base = (GIBaseInfo *)info;
1856   UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
1857   
1858   if (blob->discriminated)
1859     {
1860       Header *header = (Header *)base->typelib->data;  
1861       gint offset;
1862
1863       offset = base->offset + header->union_blob_size 
1864         + blob->n_fields * header->field_blob_size 
1865         + blob->n_functions * header->function_blob_size
1866         + n * header->constant_blob_size;
1867       
1868       return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, base, 
1869                                             base->typelib, offset);  
1870     }
1871
1872   return NULL;
1873 }
1874
1875 GIFunctionInfo *
1876 g_union_info_find_method (GIUnionInfo *info,
1877                           const gchar *name)
1878 {
1879   gint offset;
1880   GIBaseInfo *base = (GIBaseInfo *)info;
1881   Header *header = (Header *)base->typelib->data;
1882   UnionBlob *blob = (UnionBlob *)&base->typelib->data[base->offset];
1883
1884   offset = base->offset + header->union_blob_size
1885     + blob->n_fields * header->field_blob_size;
1886
1887   return find_method (base, offset, blob->n_functions, name);
1888 }
1889