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