b11cc8fc24b18b4aa86d32a293fc96b2ed4311f6
[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   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1001
1002   if (rinfo->type_is_embedded)
1003     return (GIBaseInfo *) g_info_new (type->offset, (GIBaseInfo*)info, rinfo->typelib,
1004                                       rinfo->offset);
1005
1006   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1007     {
1008       InterfaceTypeBlob *blob = (InterfaceTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1009       
1010       if (blob->tag == GI_TYPE_TAG_INTERFACE)
1011         return g_info_from_entry (rinfo->repository, rinfo->typelib, blob->interface);
1012     }
1013
1014   return NULL;
1015 }
1016
1017 gint
1018 g_type_info_get_array_length (GITypeInfo *info)
1019 {
1020   GIRealInfo *rinfo = (GIRealInfo *)info;
1021   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1022   
1023   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1024     {
1025       ArrayTypeBlob *blob = (ArrayTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1026
1027       if (blob->tag == GI_TYPE_TAG_ARRAY)
1028         {
1029           if (blob->has_length)
1030             return blob->dimensions.length;
1031         }
1032     }
1033
1034   return -1;
1035 }
1036
1037 gint
1038 g_type_info_get_array_fixed_size (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_size)
1050             return blob->dimensions.size;
1051         }
1052     }
1053
1054   return -1;
1055 }
1056
1057 gboolean
1058 g_type_info_is_zero_terminated (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         return blob->zero_terminated;
1069     }
1070
1071   return FALSE;
1072 }
1073
1074 gint
1075 g_type_info_get_n_error_domains (GITypeInfo *info)
1076 {
1077   GIRealInfo *rinfo = (GIRealInfo *)info;
1078   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1079   
1080   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1081     {
1082       ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1083
1084       if (blob->tag == GI_TYPE_TAG_ERROR)
1085         return blob->n_domains;
1086     }
1087
1088   return 0;
1089 }
1090
1091 GIErrorDomainInfo *
1092 g_type_info_get_error_domain (GITypeInfo *info,
1093                               gint        n)
1094 {
1095   GIRealInfo *rinfo = (GIRealInfo *)info;
1096   SimpleTypeBlob *type = (SimpleTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1097   
1098   if (!(type->flags.reserved == 0 && type->flags.reserved2 == 0))
1099     {
1100       ErrorTypeBlob *blob = (ErrorTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1101
1102       if (blob->tag == GI_TYPE_TAG_ERROR)
1103         return (GIErrorDomainInfo *) g_info_from_entry (rinfo->repository,
1104                                                         rinfo->typelib,
1105                                                         blob->domains[n]);
1106     }
1107
1108   return NULL;
1109 }
1110
1111
1112 /* GIErrorDomainInfo functions */
1113 const gchar *
1114 g_error_domain_info_get_quark (GIErrorDomainInfo *info)
1115 {
1116   GIRealInfo *rinfo = (GIRealInfo *)info;
1117   ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset];
1118
1119   return g_typelib_get_string (rinfo->typelib, blob->get_quark);
1120 }
1121
1122 GIInterfaceInfo *
1123 g_error_domain_info_get_codes (GIErrorDomainInfo *info)
1124 {
1125   GIRealInfo *rinfo = (GIRealInfo *)info;
1126   ErrorDomainBlob *blob = (ErrorDomainBlob *)&rinfo->typelib->data[rinfo->offset];
1127   
1128   return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository,
1129                                                 rinfo->typelib, blob->error_codes);
1130 }
1131
1132
1133 /* GIValueInfo functions */ 
1134 glong
1135 g_value_info_get_value (GIValueInfo *info)
1136 {
1137   GIRealInfo *rinfo = (GIRealInfo *)info;
1138   ValueBlob *blob = (ValueBlob *)&rinfo->typelib->data[rinfo->offset];
1139
1140   return (glong)blob->value;
1141 }
1142
1143 /* GIFieldInfo functions */
1144 GIFieldInfoFlags
1145 g_field_info_get_flags (GIFieldInfo *info)
1146 {
1147   GIFieldInfoFlags flags;
1148
1149   GIRealInfo *rinfo = (GIRealInfo *)info;
1150   FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
1151
1152   flags = 0;
1153
1154   if (blob->readable)
1155     flags = flags | GI_FIELD_IS_READABLE;
1156
1157   if (blob->writable)
1158     flags = flags | GI_FIELD_IS_WRITABLE;
1159
1160   return flags;
1161 }
1162
1163 gint
1164 g_field_info_get_size (GIFieldInfo *info)
1165 {
1166   GIRealInfo *rinfo = (GIRealInfo *)info;
1167   FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
1168   
1169   return blob->bits;
1170 }
1171
1172 gint
1173 g_field_info_get_offset (GIFieldInfo *info)
1174 {
1175   GIRealInfo *rinfo = (GIRealInfo *)info;
1176   FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
1177   
1178   return blob->struct_offset;
1179 }
1180
1181 GITypeInfo *
1182 g_field_info_get_type (GIFieldInfo *info)
1183 {
1184   GIRealInfo *rinfo = (GIRealInfo *)info;
1185   Header *header = (Header *)rinfo->typelib->data;
1186   FieldBlob *blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset];
1187   GIRealInfo *type_info;
1188
1189   if (blob->has_embedded_type)
1190     {
1191       type_info = (GIRealInfo *) g_info_new (GI_INFO_TYPE_TYPE,
1192                                                 (GIBaseInfo*)info, rinfo->typelib,
1193                                                 rinfo->offset + header->field_blob_size);
1194       type_info->type_is_embedded = TRUE;
1195     }
1196   else
1197     return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (FieldBlob, type));
1198
1199   return (GIBaseInfo*)type_info;
1200 }
1201
1202 /* GIRegisteredTypeInfo functions */
1203 const gchar *
1204 g_registered_type_info_get_type_name (GIRegisteredTypeInfo *info)
1205 {
1206   GIRealInfo *rinfo = (GIRealInfo *)info;
1207   RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1208
1209   if (blob->gtype_name)
1210     return g_typelib_get_string (rinfo->typelib, blob->gtype_name);
1211
1212   return NULL;
1213 }
1214
1215 const gchar *
1216 g_registered_type_info_get_type_init (GIRegisteredTypeInfo *info)
1217 {
1218   GIRealInfo *rinfo = (GIRealInfo *)info;
1219   RegisteredTypeBlob *blob = (RegisteredTypeBlob *)&rinfo->typelib->data[rinfo->offset];
1220
1221   if (blob->gtype_init)
1222     return g_typelib_get_string (rinfo->typelib, blob->gtype_init);
1223
1224   return NULL;
1225 }
1226
1227 GType
1228 g_registered_type_info_get_g_type (GIRegisteredTypeInfo *info)
1229 {
1230   const char *type_init;
1231   GType (* get_type_func) (void);
1232   GIRealInfo *rinfo = (GIRealInfo*)info;
1233
1234   type_init = g_registered_type_info_get_type_init (info);  
1235   
1236   if (type_init == NULL)
1237     return G_TYPE_NONE;
1238   else if (!strcmp (type_init, "intern"))
1239     return G_TYPE_OBJECT;
1240   
1241   get_type_func = NULL;
1242   if (!g_typelib_symbol (rinfo->typelib,
1243                          type_init,
1244                          (void**) &get_type_func))
1245     return G_TYPE_NONE;
1246   
1247   return (* get_type_func) ();
1248 }
1249
1250 /* GIStructInfo functions */
1251 gint
1252 g_struct_info_get_n_fields (GIStructInfo *info)
1253 {
1254   GIRealInfo *rinfo = (GIRealInfo *)info;
1255   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1256   
1257   return blob->n_fields;
1258 }
1259
1260 static gint32
1261 g_struct_get_field_offset (GIStructInfo *info,
1262                            gint         n)
1263 {
1264   GIRealInfo *rinfo = (GIRealInfo *)info;
1265   Header *header = (Header *)rinfo->typelib->data;
1266   guint32 offset = rinfo->offset + header->struct_blob_size;
1267   gint i;
1268   FieldBlob *field_blob;
1269
1270   for (i = 0; i < n; i++)
1271     {
1272       field_blob = (FieldBlob *)&rinfo->typelib->data[offset];
1273       offset += header->field_blob_size;
1274       if (field_blob->has_embedded_type)
1275         offset += header->callback_blob_size;
1276     }
1277
1278   return offset;
1279 }
1280
1281 GIFieldInfo *
1282 g_struct_info_get_field (GIStructInfo *info,
1283                          gint          n)
1284 {
1285   GIRealInfo *rinfo = (GIRealInfo *)info;
1286  
1287   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, 
1288                                      g_struct_get_field_offset (info, n));
1289 }
1290
1291 gint
1292 g_struct_info_get_n_methods (GIStructInfo *info)
1293 {
1294   GIRealInfo *rinfo = (GIRealInfo *)info;
1295   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1296   
1297   return blob->n_methods;
1298 }
1299
1300 GIFunctionInfo *
1301 g_struct_info_get_method (GIStructInfo *info,
1302                           gint         n)
1303 {
1304   GIRealInfo *rinfo = (GIRealInfo *)info;
1305   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1306   Header *header = (Header *)rinfo->typelib->data;  
1307   gint offset;
1308
1309   offset = g_struct_get_field_offset (info, blob->n_fields) + n * header->function_blob_size;
1310   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, 
1311                                         rinfo->typelib, offset);
1312 }
1313
1314 static GIFunctionInfo *
1315 find_method (GIBaseInfo   *base,
1316              guint32       offset,
1317              gint          n_methods,
1318              const gchar  *name)
1319 {
1320   /* FIXME hash */
1321   GIRealInfo *rinfo = (GIRealInfo*)base;
1322   Header *header = (Header *)rinfo->typelib->data;  
1323   gint i;
1324
1325   for (i = 0; i < n_methods; i++)
1326     {
1327       FunctionBlob *fblob = (FunctionBlob *)&rinfo->typelib->data[offset];
1328       const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name];
1329
1330       if (strcmp (name, fname) == 0)
1331         return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, base, 
1332                                                               rinfo->typelib, offset);  
1333       
1334       offset += header->function_blob_size;
1335     }
1336       
1337   return NULL;
1338 }
1339
1340 GIFunctionInfo *
1341 g_struct_info_find_method (GIStructInfo *info,
1342                            const gchar  *name)
1343 {
1344   gint offset;
1345   GIRealInfo *rinfo = (GIRealInfo *)info;
1346   Header *header = (Header *)rinfo->typelib->data;  
1347   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1348
1349   offset = rinfo->offset + header->struct_blob_size
1350     + blob->n_fields * header->field_blob_size;
1351
1352   return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
1353 }
1354
1355 gsize
1356 g_struct_info_get_size (GIStructInfo *info)
1357 {
1358   GIRealInfo *rinfo = (GIRealInfo *)info;
1359   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1360
1361   return blob->size;
1362 }
1363
1364 gsize
1365 g_struct_info_get_alignment (GIStructInfo *info)
1366 {
1367   GIRealInfo *rinfo = (GIRealInfo *)info;
1368   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1369
1370   return blob->alignment;
1371 }
1372
1373 /**
1374  * g_struct_info_is_gtype_struct:
1375  * @info: GIStructInfo
1376  * 
1377  * Return true if this structure represents the "class structure" for some
1378  * #GObject or #GInterface.  This function is mainly useful to hide this kind of structure
1379  * from generated public APIs.
1380  *
1381  * Returns: %TRUE if this is a class struct, %FALSE otherwise
1382  */
1383 gboolean
1384 g_struct_info_is_gtype_struct (GIStructInfo *info)
1385 {
1386   GIRealInfo *rinfo = (GIRealInfo *)info;
1387   StructBlob *blob = (StructBlob *)&rinfo->typelib->data[rinfo->offset];
1388
1389   return blob->is_gtype_struct;
1390 }
1391
1392 gint
1393 g_enum_info_get_n_values (GIEnumInfo *info)
1394 {
1395   GIRealInfo *rinfo = (GIRealInfo *)info;
1396   EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
1397
1398   return blob->n_values;
1399 }
1400
1401 GIValueInfo *
1402 g_enum_info_get_value (GIEnumInfo *info,
1403                        gint            n)
1404 {
1405   GIRealInfo *rinfo = (GIRealInfo *)info;
1406   Header *header = (Header *)rinfo->typelib->data;  
1407   gint offset;
1408
1409   offset = rinfo->offset + header->enum_blob_size 
1410     + n * header->value_blob_size;
1411   return (GIValueInfo *) g_info_new (GI_INFO_TYPE_VALUE, (GIBaseInfo*)info, rinfo->typelib, offset);
1412 }
1413
1414 /**
1415  * g_enum_info_get_storage_type:
1416  * @info: GIEnumInfo
1417  *
1418  * Gets the tag of the type used for the enum in the C ABI. This will
1419  * will be a signed or unsigned integral type.
1420
1421  * Note that in the current implementation the width of the type is
1422  * computed correctly, but the signed or unsigned nature of the type
1423  * may not match the sign of the type used by the C compiler.
1424  *
1425  * Return Value: the storage type for the enumeration
1426  */
1427 GITypeTag
1428 g_enum_info_get_storage_type (GIEnumInfo *info)
1429 {
1430   GIRealInfo *rinfo = (GIRealInfo *)info;
1431   EnumBlob *blob = (EnumBlob *)&rinfo->typelib->data[rinfo->offset];
1432
1433   return blob->storage_type;
1434 }
1435
1436 /* GIObjectInfo functions */
1437 GIObjectInfo *
1438 g_object_info_get_parent (GIObjectInfo *info)
1439 {
1440   GIRealInfo *rinfo = (GIRealInfo *)info;
1441   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1442
1443   if (blob->parent)
1444     return (GIObjectInfo *) g_info_from_entry (rinfo->repository,
1445                                                rinfo->typelib, blob->parent);
1446   else
1447     return NULL;
1448 }
1449
1450 gboolean
1451 g_object_info_get_abstract (GIObjectInfo    *info)
1452 {
1453   GIRealInfo *rinfo = (GIRealInfo *)info;
1454   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1455   return blob->abstract != 0;
1456 }
1457
1458 const gchar *
1459 g_object_info_get_type_name (GIObjectInfo *info)
1460 {
1461   GIRealInfo *rinfo = (GIRealInfo *)info;
1462   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1463
1464   return g_typelib_get_string (rinfo->typelib, blob->gtype_name);
1465 }
1466
1467 const gchar *
1468 g_object_info_get_type_init (GIObjectInfo *info)
1469 {
1470   GIRealInfo *rinfo = (GIRealInfo *)info;
1471   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1472
1473   return g_typelib_get_string (rinfo->typelib, blob->gtype_init);
1474 }
1475
1476 gint
1477 g_object_info_get_n_interfaces (GIObjectInfo *info)
1478 {
1479   GIRealInfo *rinfo = (GIRealInfo *)info;
1480   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1481
1482   return blob->n_interfaces;
1483 }
1484
1485 GIInterfaceInfo *
1486 g_object_info_get_interface (GIObjectInfo *info,
1487                              gint          n)
1488 {
1489   GIRealInfo *rinfo = (GIRealInfo *)info;
1490   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1491
1492   return (GIInterfaceInfo *) g_info_from_entry (rinfo->repository,
1493                                                 rinfo->typelib, blob->interfaces[n]);
1494 }
1495
1496 gint
1497 g_object_info_get_n_fields (GIObjectInfo *info)
1498 {
1499   GIRealInfo *rinfo = (GIRealInfo *)info;
1500   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1501
1502   return blob->n_fields;
1503 }
1504
1505 GIFieldInfo *
1506 g_object_info_get_field (GIObjectInfo *info,
1507                          gint          n)
1508 {
1509   gint offset;
1510   GIRealInfo *rinfo = (GIRealInfo *)info;
1511   Header *header = (Header *)rinfo->typelib->data;  
1512   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1513   
1514   offset = rinfo->offset + header->object_blob_size
1515     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1516     + n * header->field_blob_size;
1517   
1518   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, offset);
1519 }
1520
1521 gint
1522 g_object_info_get_n_properties (GIObjectInfo *info)
1523 {
1524   GIRealInfo *rinfo = (GIRealInfo *)info;
1525   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1526
1527   return blob->n_properties;  
1528 }
1529
1530 GIPropertyInfo *
1531 g_object_info_get_property (GIObjectInfo *info,
1532                             gint          n)
1533 {
1534   gint offset;
1535   GIRealInfo *rinfo = (GIRealInfo *)info;
1536   Header *header = (Header *)rinfo->typelib->data;  
1537   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1538   
1539   offset = rinfo->offset + header->object_blob_size
1540     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1541     + blob->n_fields * header->field_blob_size
1542     + n * header->property_blob_size;
1543
1544   return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, 
1545                                         rinfo->typelib, offset);
1546 }
1547
1548 gint
1549 g_object_info_get_n_methods (GIObjectInfo *info)
1550 {
1551   GIRealInfo *rinfo = (GIRealInfo *)info;
1552   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1553
1554   return blob->n_methods;
1555 }
1556
1557 GIFunctionInfo *
1558 g_object_info_get_method (GIObjectInfo *info,
1559                           gint          n)
1560 {
1561   gint offset;
1562   GIRealInfo *rinfo = (GIRealInfo *)info;
1563   Header *header = (Header *)rinfo->typelib->data;  
1564   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1565   
1566   offset = rinfo->offset + header->object_blob_size
1567     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1568     + blob->n_fields * header->field_blob_size
1569     + blob->n_properties * header->property_blob_size
1570     + n * header->function_blob_size;
1571
1572     return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, 
1573                                           rinfo->typelib, offset);  
1574 }
1575
1576 GIFunctionInfo *
1577 g_object_info_find_method (GIObjectInfo *info,
1578                            const gchar  *name)
1579 {
1580   gint offset;
1581   GIRealInfo *rinfo = (GIRealInfo *)info;
1582   Header *header = (Header *)rinfo->typelib->data;  
1583   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1584
1585   offset = rinfo->offset + header->object_blob_size
1586     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1587     + blob->n_fields * header->field_blob_size +
1588     + blob->n_properties * header->property_blob_size;
1589
1590   return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
1591 }
1592
1593 gint
1594 g_object_info_get_n_signals (GIObjectInfo *info)
1595 {
1596   GIRealInfo *rinfo = (GIRealInfo *)info;
1597   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1598
1599   return blob->n_signals;
1600 }
1601
1602 GISignalInfo *
1603 g_object_info_get_signal (GIObjectInfo *info,
1604                           gint          n)
1605 {
1606   gint offset;
1607   GIRealInfo *rinfo = (GIRealInfo *)info;
1608   Header *header = (Header *)rinfo->typelib->data;  
1609   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1610   
1611   offset = rinfo->offset + header->object_blob_size
1612     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1613     + blob->n_fields * header->field_blob_size
1614     + blob->n_properties * header->property_blob_size
1615     + blob->n_methods * header->function_blob_size 
1616     + n * header->signal_blob_size;
1617
1618   return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, 
1619                                       rinfo->typelib, offset);  
1620 }
1621
1622 gint
1623 g_object_info_get_n_vfuncs (GIObjectInfo *info)
1624 {
1625   GIRealInfo *rinfo = (GIRealInfo *)info;
1626   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1627   
1628   return blob->n_vfuncs;
1629 }
1630
1631 GIVFuncInfo *
1632 g_object_info_get_vfunc (GIObjectInfo *info,
1633                          gint          n)
1634 {
1635   gint offset;
1636   GIRealInfo *rinfo = (GIRealInfo *)info;
1637   Header *header = (Header *)rinfo->typelib->data;  
1638   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1639   
1640   offset = rinfo->offset + header->object_blob_size
1641     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1642     + blob->n_fields * header->field_blob_size
1643     + blob->n_properties * header->property_blob_size
1644     + blob->n_methods * header->function_blob_size 
1645     + blob->n_signals * header->signal_blob_size 
1646     + n * header->vfunc_blob_size;
1647
1648   return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, 
1649                                      rinfo->typelib, offset);  
1650 }
1651
1652 static GIVFuncInfo *
1653 find_vfunc (GIRealInfo   *rinfo,
1654             guint32       offset,
1655             gint          n_vfuncs,
1656             const gchar  *name)
1657 {
1658   /* FIXME hash */
1659   Header *header = (Header *)rinfo->typelib->data;
1660   gint i;
1661
1662   for (i = 0; i < n_vfuncs; i++)
1663     {
1664       VFuncBlob *fblob = (VFuncBlob *)&rinfo->typelib->data[offset];
1665       const gchar *fname = (const gchar *)&rinfo->typelib->data[fblob->name];
1666
1667       if (strcmp (name, fname) == 0)
1668         return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*) rinfo,
1669                                            rinfo->typelib, offset);
1670
1671       offset += header->vfunc_blob_size;
1672     }
1673
1674   return NULL;
1675 }
1676
1677 /**
1678  * g_object_info_find_vfunc:
1679  * @info: An #GIObjectInfo
1680  * @name: The name of a virtual function to find.
1681  *
1682  * Locate a virtual function slot with name @name.  Note that the namespace
1683  * for virtuals is distinct from that of methods; there may or may not be
1684  * a concrete method associated for a virtual.  If there is one, it may
1685  * be retrieved using #g_vfunc_info_get_invoker.  See the documentation for
1686  * that function for more information on invoking virtuals.
1687  *
1688  * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name.
1689  */
1690 GIVFuncInfo *
1691 g_object_info_find_vfunc (GIObjectInfo *info,
1692                           const gchar  *name)
1693 {
1694   gint offset;
1695   GIRealInfo *rinfo = (GIRealInfo *)info;
1696   Header *header = (Header *)rinfo->typelib->data;
1697   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1698
1699   offset = rinfo->offset + header->object_blob_size
1700     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1701     + blob->n_fields * header->field_blob_size
1702     + blob->n_properties * header->property_blob_size
1703     + blob->n_methods * header->function_blob_size
1704     + blob->n_signals * header->signal_blob_size;
1705
1706   return find_vfunc (rinfo, offset, blob->n_vfuncs, name);
1707 }
1708
1709 gint
1710 g_object_info_get_n_constants (GIObjectInfo *info)
1711 {
1712   GIRealInfo *rinfo = (GIRealInfo *)info;
1713   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1714   
1715   return blob->n_constants;
1716 }
1717
1718 GIConstantInfo *
1719 g_object_info_get_constant (GIObjectInfo *info,
1720                             gint          n)
1721 {
1722   gint offset;
1723   GIRealInfo *rinfo = (GIRealInfo *)info;
1724   Header *header = (Header *)rinfo->typelib->data;  
1725   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1726   
1727   offset = rinfo->offset + header->object_blob_size
1728     + (blob->n_interfaces + blob->n_interfaces % 2) * 2
1729     + blob->n_fields * header->field_blob_size
1730     + blob->n_properties * header->property_blob_size
1731     + blob->n_methods * header->function_blob_size 
1732     + blob->n_signals * header->signal_blob_size 
1733     + blob->n_vfuncs * header->vfunc_blob_size 
1734     + n * header->constant_blob_size;
1735
1736   return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, 
1737                                         rinfo->typelib, offset);  
1738 }
1739
1740 /**
1741  * g_object_info_get_class_struct:
1742  * @info: A #GIObjectInfo to query
1743  * 
1744  * Every #GObject has two structures; an instance structure and a class
1745  * structure.  This function returns the metadata for the class structure.
1746  *
1747  * Returns: a #GIStructInfo for the class struct or %NULL if none found.
1748  */
1749 GIStructInfo *
1750 g_object_info_get_class_struct (GIObjectInfo *info)
1751 {
1752   GIRealInfo *rinfo = (GIRealInfo *)info;
1753   ObjectBlob *blob = (ObjectBlob *)&rinfo->typelib->data[rinfo->offset];
1754
1755   if (blob->gtype_struct)
1756     return (GIStructInfo *) g_info_from_entry (rinfo->repository,
1757                                                rinfo->typelib, blob->gtype_struct);
1758   else
1759     return NULL;
1760 }
1761
1762 /* GIInterfaceInfo functions */
1763 gint
1764 g_interface_info_get_n_prerequisites (GIInterfaceInfo *info)
1765 {
1766   GIRealInfo *rinfo = (GIRealInfo *)info;
1767   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1768
1769   return blob->n_prerequisites;
1770 }
1771
1772 GIBaseInfo *
1773 g_interface_info_get_prerequisite (GIInterfaceInfo *info,
1774                                    gint            n)
1775 {
1776   GIRealInfo *rinfo = (GIRealInfo *)info;
1777   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1778
1779   return g_info_from_entry (rinfo->repository,
1780                             rinfo->typelib, blob->prerequisites[n]);
1781 }
1782
1783
1784 gint
1785 g_interface_info_get_n_properties (GIInterfaceInfo *info)
1786 {
1787   GIRealInfo *rinfo = (GIRealInfo *)info;
1788   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1789
1790   return blob->n_properties;  
1791 }
1792
1793 GIPropertyInfo *
1794 g_interface_info_get_property (GIInterfaceInfo *info,
1795                                gint            n)
1796 {
1797   gint offset;
1798   GIRealInfo *rinfo = (GIRealInfo *)info;
1799   Header *header = (Header *)rinfo->typelib->data;  
1800   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1801   
1802   offset = rinfo->offset + header->interface_blob_size
1803     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1804     + n * header->property_blob_size;
1805
1806   return (GIPropertyInfo *) g_info_new (GI_INFO_TYPE_PROPERTY, (GIBaseInfo*)info, 
1807                                         rinfo->typelib, offset);
1808 }
1809
1810 gint
1811 g_interface_info_get_n_methods (GIInterfaceInfo *info)
1812 {
1813   GIRealInfo *rinfo = (GIRealInfo *)info;
1814   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1815
1816   return blob->n_methods;
1817 }
1818
1819 GIFunctionInfo *
1820 g_interface_info_get_method (GIInterfaceInfo *info,
1821                              gint            n)
1822 {
1823   gint offset;
1824   GIRealInfo *rinfo = (GIRealInfo *)info;
1825   Header *header = (Header *)rinfo->typelib->data;  
1826   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1827   
1828   offset = rinfo->offset + header->interface_blob_size
1829     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1830     + blob->n_properties * header->property_blob_size 
1831     + n * header->function_blob_size;
1832   
1833   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, 
1834                                         rinfo->typelib, offset);  
1835 }
1836
1837 GIFunctionInfo *
1838 g_interface_info_find_method (GIInterfaceInfo *info,
1839                               const gchar     *name)
1840 {
1841   gint offset;
1842   GIRealInfo *rinfo = (GIRealInfo *)info;
1843   Header *header = (Header *)rinfo->typelib->data;  
1844   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1845
1846   offset = rinfo->offset + header->interface_blob_size
1847     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1848     + blob->n_properties * header->property_blob_size;
1849
1850   return find_method ((GIBaseInfo*)info, offset, blob->n_methods, name);
1851 }
1852
1853 gint
1854 g_interface_info_get_n_signals (GIInterfaceInfo *info)
1855 {
1856   GIRealInfo *rinfo = (GIRealInfo *)info;
1857   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1858
1859   return blob->n_signals;
1860 }
1861
1862 GISignalInfo *
1863 g_interface_info_get_signal (GIInterfaceInfo *info,
1864                              gint            n)
1865 {
1866   gint offset;
1867   GIRealInfo *rinfo = (GIRealInfo *)info;
1868   Header *header = (Header *)rinfo->typelib->data;  
1869   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1870   
1871   offset = rinfo->offset + header->interface_blob_size 
1872     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1873     + blob->n_properties * header->property_blob_size 
1874     + blob->n_methods * header->function_blob_size 
1875     + n * header->signal_blob_size;
1876   
1877   return (GISignalInfo *) g_info_new (GI_INFO_TYPE_SIGNAL, (GIBaseInfo*)info, 
1878                                       rinfo->typelib, offset);  
1879 }
1880
1881 gint
1882 g_interface_info_get_n_vfuncs (GIInterfaceInfo *info)
1883 {
1884   GIRealInfo *rinfo = (GIRealInfo *)info;
1885   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1886
1887   return blob->n_vfuncs;
1888 }
1889
1890 GIVFuncInfo *
1891 g_interface_info_get_vfunc (GIInterfaceInfo *info,
1892                             gint            n)
1893 {
1894   gint offset;
1895   GIRealInfo *rinfo = (GIRealInfo *)info;
1896   Header *header = (Header *)rinfo->typelib->data;  
1897   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1898   
1899   offset = rinfo->offset + header->interface_blob_size 
1900     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1901     + blob->n_properties * header->property_blob_size 
1902     + blob->n_methods * header->function_blob_size 
1903     + blob->n_signals * header->signal_blob_size
1904     + n * header->vfunc_blob_size;
1905   
1906   return (GIVFuncInfo *) g_info_new (GI_INFO_TYPE_VFUNC, (GIBaseInfo*)info, 
1907                                      rinfo->typelib, offset);  
1908 }
1909
1910 /**
1911  * g_interface_info_find_vfunc:
1912  * @info: An #GIObjectInfo
1913  * @name: The name of a virtual function to find.
1914  *
1915  * Locate a virtual function slot with name @name.  See the documentation
1916  * for #g_object_info_find_vfunc for more information on virtuals.
1917  *
1918  * Return value: (transfer full): A #GIVFuncInfo, or %NULL if none with name @name.
1919  */
1920 GIVFuncInfo *
1921 g_interface_info_find_vfunc (GIInterfaceInfo *info,
1922                              const gchar  *name)
1923 {
1924   gint offset;
1925   GIRealInfo *rinfo = (GIRealInfo *)info;
1926   Header *header = (Header *)rinfo->typelib->data;
1927   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1928
1929   offset = rinfo->offset + header->interface_blob_size
1930     + (blob->n_prerequisites + blob->n_prerequisites % 2) * 2
1931     + blob->n_properties * header->property_blob_size
1932     + blob->n_methods * header->function_blob_size
1933     + blob->n_signals * header->signal_blob_size;
1934
1935   return find_vfunc (rinfo, offset, blob->n_vfuncs, name);
1936 }
1937
1938 gint
1939 g_interface_info_get_n_constants (GIInterfaceInfo *info)
1940 {
1941   GIRealInfo *rinfo = (GIRealInfo *)info;
1942   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1943   
1944   return blob->n_constants;
1945 }
1946
1947 GIConstantInfo *
1948 g_interface_info_get_constant (GIInterfaceInfo *info,
1949                                gint             n)
1950 {
1951   gint offset;
1952   GIRealInfo *rinfo = (GIRealInfo *)info;
1953   Header *header = (Header *)rinfo->typelib->data;  
1954   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1955   
1956   offset = rinfo->offset + header->interface_blob_size
1957     + (blob->n_prerequisites + (blob->n_prerequisites % 2)) * 2
1958     + blob->n_properties * header->property_blob_size
1959     + blob->n_methods * header->function_blob_size 
1960     + blob->n_signals * header->signal_blob_size 
1961     + blob->n_vfuncs * header->vfunc_blob_size 
1962     + n * header->constant_blob_size;
1963
1964   return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, 
1965                                         rinfo->typelib, offset);  
1966 }
1967
1968 /**
1969  * g_interface_info_get_iface_struct:
1970  * @info: A #GIInterfaceInfo to query
1971  *
1972  * Returns the layout C structure associated with this #GInterface.
1973  *
1974  * Returns: A #GIStructInfo for the class struct or %NULL if none found.
1975  */
1976 GIStructInfo *
1977 g_interface_info_get_iface_struct (GIInterfaceInfo *info)
1978 {
1979   GIRealInfo *rinfo = (GIRealInfo *)info;
1980   InterfaceBlob *blob = (InterfaceBlob *)&rinfo->typelib->data[rinfo->offset];
1981
1982   if (blob->gtype_struct)
1983     return (GIStructInfo *) g_info_from_entry (rinfo->repository,
1984                                                rinfo->typelib, blob->gtype_struct);
1985   else
1986     return NULL;
1987 }
1988
1989 /* GIPropertyInfo functions */
1990 GParamFlags
1991 g_property_info_get_flags (GIPropertyInfo *info)
1992 {
1993   GParamFlags flags;
1994   GIRealInfo *rinfo = (GIRealInfo *)info;
1995   PropertyBlob *blob = (PropertyBlob *)&rinfo->typelib->data[rinfo->offset];
1996   
1997   flags = 0;
1998
1999   if (blob->readable)
2000     flags = flags | G_PARAM_READABLE;
2001
2002   if (blob->writable)
2003     flags = flags | G_PARAM_WRITABLE;
2004
2005   if (blob->construct)
2006     flags = flags | G_PARAM_CONSTRUCT;
2007
2008   if (blob->construct_only)
2009     flags = flags | G_PARAM_CONSTRUCT_ONLY;
2010
2011   return flags;
2012 }
2013
2014 GITypeInfo *
2015 g_property_info_get_type (GIPropertyInfo *info)
2016 {
2017   GIRealInfo *rinfo = (GIRealInfo *)info;
2018
2019   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + G_STRUCT_OFFSET (PropertyBlob, type));
2020 }
2021
2022
2023 /* GISignalInfo functions */
2024 GSignalFlags
2025 g_signal_info_get_flags (GISignalInfo *info)
2026 {
2027   GSignalFlags flags;
2028
2029   GIRealInfo *rinfo = (GIRealInfo *)info;
2030   SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
2031
2032   flags = 0;
2033
2034   if (blob->run_first)
2035     flags = flags | G_SIGNAL_RUN_FIRST;
2036
2037   if (blob->run_last)
2038     flags = flags | G_SIGNAL_RUN_LAST;
2039
2040   if (blob->run_cleanup)
2041     flags = flags | G_SIGNAL_RUN_CLEANUP;
2042
2043   if (blob->no_recurse)
2044     flags = flags | G_SIGNAL_NO_RECURSE;
2045
2046   if (blob->detailed)
2047     flags = flags | G_SIGNAL_DETAILED;
2048
2049   if (blob->action)
2050     flags = flags | G_SIGNAL_ACTION;
2051
2052   if (blob->no_hooks)
2053     flags = flags | G_SIGNAL_NO_HOOKS;
2054
2055   return flags;
2056 }
2057
2058 GIVFuncInfo *
2059 g_signal_info_get_class_closure (GISignalInfo *info)
2060 {
2061   GIRealInfo *rinfo = (GIRealInfo *)info;
2062   SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
2063
2064   if (blob->has_class_closure)
2065     return g_interface_info_get_vfunc ((GIInterfaceInfo *)rinfo->container, blob->class_closure);
2066
2067   return NULL;
2068 }
2069
2070 gboolean
2071 g_signal_info_true_stops_emit (GISignalInfo *info)
2072 {
2073   GIRealInfo *rinfo = (GIRealInfo *)info;
2074   SignalBlob *blob = (SignalBlob *)&rinfo->typelib->data[rinfo->offset];
2075
2076   return blob->true_stops_emit;
2077 }
2078
2079 /* GIVFuncInfo functions */
2080 GIVFuncInfoFlags
2081 g_vfunc_info_get_flags (GIVFuncInfo *info)
2082 {
2083   GIVFuncInfoFlags flags;
2084
2085   GIRealInfo *rinfo = (GIRealInfo *)info;
2086   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2087
2088   flags = 0;
2089
2090   if (blob->must_chain_up)
2091     flags = flags | GI_VFUNC_MUST_CHAIN_UP;
2092
2093   if (blob->must_be_implemented)
2094     flags = flags | GI_VFUNC_MUST_OVERRIDE;
2095
2096   if (blob->must_not_be_implemented)
2097     flags = flags | GI_VFUNC_MUST_NOT_OVERRIDE;
2098
2099   return flags;
2100 }
2101
2102 gint
2103 g_vfunc_info_get_offset (GIVFuncInfo *info)
2104 {
2105   GIRealInfo *rinfo = (GIRealInfo *)info;
2106   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2107   
2108   return blob->struct_offset;
2109 }
2110
2111 GISignalInfo *
2112 g_vfunc_info_get_signal (GIVFuncInfo *info)
2113 {
2114   GIRealInfo *rinfo = (GIRealInfo *)info;
2115   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2116
2117   if (blob->class_closure)
2118     return g_interface_info_get_signal ((GIInterfaceInfo *)rinfo->container, blob->signal);
2119   
2120   return NULL;
2121 }
2122
2123 /**
2124  * g_vfunc_info_get_invoker:
2125  * @info: A #GIVFuncInfo
2126  *
2127  * If this virtual function has an associated invoker method, this
2128  * method will return it.  An invoker method is a C entry point.
2129  *
2130  * Not all virtuals will have invokers.
2131  *
2132  * Return value: (transfer full): An invoker function, or %NULL if none known
2133  */
2134 GIFunctionInfo *
2135 g_vfunc_info_get_invoker (GIVFuncInfo *info)
2136 {
2137   GIRealInfo *rinfo = (GIRealInfo *)info;
2138   VFuncBlob *blob = (VFuncBlob *)&rinfo->typelib->data[rinfo->offset];
2139   GIBaseInfo *container = rinfo->container;
2140   GIInfoType parent_type;
2141
2142   /* 1023 = 0x3ff is the maximum of the 10 bits for invoker index */
2143   if (blob->invoker == 1023)
2144     return NULL;
2145
2146   parent_type = g_base_info_get_type (container);
2147   if (parent_type == GI_INFO_TYPE_OBJECT)
2148     return g_object_info_get_method ((GIObjectInfo*)container, blob->invoker);
2149   else if (parent_type == GI_INFO_TYPE_INTERFACE)
2150     return g_interface_info_get_method ((GIInterfaceInfo*)container, blob->invoker);
2151   else
2152     g_assert_not_reached ();
2153 }
2154
2155 /* GIConstantInfo functions */
2156 GITypeInfo *
2157 g_constant_info_get_type (GIConstantInfo *info)
2158 {
2159   GIRealInfo *rinfo = (GIRealInfo *)info;
2160   
2161   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 8);
2162 }
2163
2164 gint
2165 g_constant_info_get_value (GIConstantInfo *info, 
2166                            GArgument      *value)
2167 {
2168   GIRealInfo *rinfo = (GIRealInfo *)info;
2169   ConstantBlob *blob = (ConstantBlob *)&rinfo->typelib->data[rinfo->offset];
2170
2171   /* FIXME non-basic types ? */
2172   if (blob->type.flags.reserved == 0 && blob->type.flags.reserved2 == 0)
2173     {
2174       if (blob->type.flags.pointer)
2175         value->v_pointer = g_memdup (&rinfo->typelib->data[blob->offset], blob->size);
2176       else
2177         {
2178           switch (blob->type.flags.tag)
2179             {
2180             case GI_TYPE_TAG_BOOLEAN:
2181               value->v_boolean = *(gboolean*)&rinfo->typelib->data[blob->offset];
2182               break;
2183             case GI_TYPE_TAG_INT8:
2184               value->v_int8 = *(gint8*)&rinfo->typelib->data[blob->offset];
2185               break;
2186             case GI_TYPE_TAG_UINT8:
2187               value->v_uint8 = *(guint8*)&rinfo->typelib->data[blob->offset];
2188               break;
2189             case GI_TYPE_TAG_INT16:
2190               value->v_int16 = *(gint16*)&rinfo->typelib->data[blob->offset];
2191               break;
2192             case GI_TYPE_TAG_UINT16:
2193               value->v_uint16 = *(guint16*)&rinfo->typelib->data[blob->offset];
2194               break;
2195             case GI_TYPE_TAG_INT32:
2196               value->v_int32 = *(gint32*)&rinfo->typelib->data[blob->offset];
2197               break;
2198             case GI_TYPE_TAG_UINT32:
2199               value->v_uint32 = *(guint32*)&rinfo->typelib->data[blob->offset];
2200               break;
2201             case GI_TYPE_TAG_INT64:
2202               value->v_int64 = *(gint64*)&rinfo->typelib->data[blob->offset];
2203               break;
2204             case GI_TYPE_TAG_UINT64:
2205               value->v_uint64 = *(guint64*)&rinfo->typelib->data[blob->offset];
2206               break;
2207             case GI_TYPE_TAG_FLOAT:
2208               value->v_float = *(gfloat*)&rinfo->typelib->data[blob->offset];
2209               break;
2210             case GI_TYPE_TAG_DOUBLE:
2211               value->v_double = *(gdouble*)&rinfo->typelib->data[blob->offset];
2212               break;
2213             case GI_TYPE_TAG_TIME_T:
2214               value->v_long = *(long*)&rinfo->typelib->data[blob->offset];
2215               break;
2216             case GI_TYPE_TAG_SHORT:
2217               value->v_short = *(gshort*)&rinfo->typelib->data[blob->offset];
2218               break;
2219             case GI_TYPE_TAG_USHORT:
2220               value->v_ushort = *(gushort*)&rinfo->typelib->data[blob->offset];
2221               break;
2222             case GI_TYPE_TAG_INT:
2223               value->v_int = *(gint*)&rinfo->typelib->data[blob->offset];
2224               break;
2225             case GI_TYPE_TAG_UINT:
2226               value->v_uint = *(guint*)&rinfo->typelib->data[blob->offset];
2227               break;
2228             case GI_TYPE_TAG_LONG:
2229               value->v_long = *(glong*)&rinfo->typelib->data[blob->offset];
2230               break;
2231             case GI_TYPE_TAG_ULONG:
2232               value->v_ulong = *(gulong*)&rinfo->typelib->data[blob->offset];
2233               break;
2234             }
2235         }
2236     }
2237
2238   return blob->size;
2239 }
2240
2241 /* GIUnionInfo functions */
2242 gint
2243 g_union_info_get_n_fields  (GIUnionInfo *info)
2244 {
2245   GIRealInfo *rinfo = (GIRealInfo *)info;
2246   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2247   
2248   return blob->n_fields;
2249 }
2250
2251 GIFieldInfo *
2252 g_union_info_get_field (GIUnionInfo *info,
2253                         gint         n)
2254 {
2255   GIRealInfo *rinfo = (GIRealInfo *)info;
2256   Header *header = (Header *)rinfo->typelib->data;  
2257  
2258   return (GIFieldInfo *) g_info_new (GI_INFO_TYPE_FIELD, (GIBaseInfo*)info, rinfo->typelib, 
2259                                      rinfo->offset + header->union_blob_size + 
2260                                      n * header->field_blob_size);
2261 }
2262
2263 gint
2264 g_union_info_get_n_methods (GIUnionInfo *info)
2265 {
2266   GIRealInfo *rinfo = (GIRealInfo *)info;
2267   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2268   
2269   return blob->n_functions;
2270 }
2271
2272 GIFunctionInfo *
2273 g_union_info_get_method (GIUnionInfo *info,
2274                          gint         n)
2275 {
2276   GIRealInfo *rinfo = (GIRealInfo *)info;
2277   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2278   Header *header = (Header *)rinfo->typelib->data;  
2279   gint offset;
2280
2281   offset = rinfo->offset + header->union_blob_size 
2282     + blob->n_fields * header->field_blob_size 
2283     + n * header->function_blob_size;
2284   return (GIFunctionInfo *) g_info_new (GI_INFO_TYPE_FUNCTION, (GIBaseInfo*)info, 
2285                                         rinfo->typelib, offset);
2286 }
2287
2288 gboolean
2289 g_union_info_is_discriminated (GIUnionInfo *info)
2290 {
2291   GIRealInfo *rinfo = (GIRealInfo *)info;
2292   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2293   
2294   return blob->discriminated;
2295 }
2296
2297 gint
2298 g_union_info_get_discriminator_offset (GIUnionInfo *info)
2299 {
2300   GIRealInfo *rinfo = (GIRealInfo *)info;
2301   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2302   
2303   return blob->discriminator_offset;
2304 }
2305
2306 GITypeInfo *
2307 g_union_info_get_discriminator_type (GIUnionInfo *info)
2308 {
2309   GIRealInfo *rinfo = (GIRealInfo *)info;
2310  
2311   return g_type_info_new ((GIBaseInfo*)info, rinfo->typelib, rinfo->offset + 24);
2312 }
2313
2314 GIConstantInfo *
2315 g_union_info_get_discriminator (GIUnionInfo *info,
2316                                 gint         n)
2317 {
2318   GIRealInfo *rinfo = (GIRealInfo *)info;
2319   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2320   
2321   if (blob->discriminated)
2322     {
2323       Header *header = (Header *)rinfo->typelib->data;  
2324       gint offset;
2325
2326       offset = rinfo->offset + header->union_blob_size 
2327         + blob->n_fields * header->field_blob_size 
2328         + blob->n_functions * header->function_blob_size
2329         + n * header->constant_blob_size;
2330       
2331       return (GIConstantInfo *) g_info_new (GI_INFO_TYPE_CONSTANT, (GIBaseInfo*)info, 
2332                                             rinfo->typelib, offset);  
2333     }
2334
2335   return NULL;
2336 }
2337
2338 GIFunctionInfo *
2339 g_union_info_find_method (GIUnionInfo *info,
2340                           const gchar *name)
2341 {
2342   gint offset;
2343   GIRealInfo *rinfo = (GIRealInfo *)info;
2344   Header *header = (Header *)rinfo->typelib->data;
2345   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2346
2347   offset = rinfo->offset + header->union_blob_size
2348     + blob->n_fields * header->field_blob_size;
2349
2350   return find_method ((GIBaseInfo*)info, offset, blob->n_functions, name);
2351 }
2352
2353 gsize
2354 g_union_info_get_size (GIUnionInfo *info)
2355 {
2356   GIRealInfo *rinfo = (GIRealInfo *)info;
2357   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2358
2359   return blob->size;
2360 }
2361
2362 gsize
2363 g_union_info_get_alignment (GIUnionInfo *info)
2364 {
2365   GIRealInfo *rinfo = (GIRealInfo *)info;
2366   UnionBlob *blob = (UnionBlob *)&rinfo->typelib->data[rinfo->offset];
2367
2368   return blob->alignment;
2369 }