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