Initial revision
[gnome.gobject-introspection] / src / gidlnode.c
1 /* GObject introspection: Metadata creation
2  *
3  * Copyright (C) 2005 Matthias Clasen
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include <stdio.h>
22
23 #include "gidlmodule.h"
24 #include "gidlnode.h"
25 #include "gmetadata.h"
26
27 #define ALIGN_VALUE(this, boundary) \
28   (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
29
30
31 GIdlNode *
32 g_idl_node_new (GIdlNodeTypeId type)
33 {
34   GIdlNode *node = NULL;
35
36   switch (type)
37     {
38    case G_IDL_NODE_FUNCTION:
39       node = g_malloc0 (sizeof (GIdlNodeFunction));
40       break;
41
42    case G_IDL_NODE_PARAM:
43       node = g_malloc0 (sizeof (GIdlNodeParam));
44       break;
45
46    case G_IDL_NODE_TYPE:
47       node = g_malloc0 (sizeof (GIdlNodeType));
48       break;
49
50     case G_IDL_NODE_OBJECT:
51     case G_IDL_NODE_INTERFACE:
52       node = g_malloc0 (sizeof (GIdlNodeInterface));
53       break;
54
55     case G_IDL_NODE_SIGNAL:
56       node = g_malloc0 (sizeof (GIdlNodeSignal));
57       break;
58
59     case G_IDL_NODE_PROPERTY:
60       node = g_malloc0 (sizeof (GIdlNodeProperty));
61       break;
62
63     case G_IDL_NODE_VFUNC:
64       node = g_malloc0 (sizeof (GIdlNodeFunction));
65       break;
66
67     case G_IDL_NODE_FIELD:
68       node = g_malloc0 (sizeof (GIdlNodeField));
69       break;
70
71     case G_IDL_NODE_ENUM:
72     case G_IDL_NODE_FLAGS:
73       node = g_malloc0 (sizeof (GIdlNodeEnum));
74       break;
75
76     case G_IDL_NODE_BOXED:
77       node = g_malloc0 (sizeof (GIdlNodeBoxed));
78       break;
79
80     case G_IDL_NODE_STRUCT:
81       node = g_malloc0 (sizeof (GIdlNodeStruct));
82       break;
83
84     case G_IDL_NODE_VALUE:
85       node = g_malloc0 (sizeof (GIdlNodeValue));
86       break;
87
88     case G_IDL_NODE_CONSTANT:
89       node = g_malloc0 (sizeof (GIdlNodeConstant));
90       break;
91
92     case G_IDL_NODE_ERROR_DOMAIN:
93       node = g_malloc0 (sizeof (GIdlNodeErrorDomain));
94       break;
95
96     case G_IDL_NODE_XREF:
97       node = g_malloc0 (sizeof (GIdlNodeXRef));
98       break;
99
100     default:
101       g_error ("Unhandled node type %d\n", type);
102       break;
103     }
104
105   node->type = type;
106
107   return node;
108 }
109
110 void
111 g_idl_node_free (GIdlNode *node)
112 {
113   GList *l;
114
115   switch (node->type)
116     {
117     case G_IDL_NODE_FUNCTION:
118       {
119         GIdlNodeFunction *function = (GIdlNodeFunction *)node;
120         
121         g_free (node->name);
122         g_free (function->c_name);
123         g_idl_node_free ((GIdlNode *)function->result);
124         for (l = function->parameters; l; l = l->next)
125           g_idl_node_free ((GIdlNode *)l->data);
126         g_list_free (function->parameters);
127       }
128       break;
129
130     case G_IDL_NODE_TYPE:
131       {
132         GIdlNodeType *type = (GIdlNodeType *)node;
133         
134         g_free (node->name);
135         if (type->parameter_type1)
136           g_idl_node_free ((GIdlNode *)type->parameter_type1);
137         if (type->parameter_type2)
138           g_idl_node_free ((GIdlNode *)type->parameter_type2);
139
140         g_free (type->interface);
141         g_strfreev (type->errors);
142
143       }
144       break;
145
146     case G_IDL_NODE_PARAM:
147       {
148         GIdlNodeParam *param = (GIdlNodeParam *)node;
149         
150         g_free (node->name);
151         g_idl_node_free ((GIdlNode *)param->type);
152       }
153       break;
154
155     case G_IDL_NODE_PROPERTY:
156       {
157         GIdlNodeProperty *property = (GIdlNodeProperty *)node;
158         
159         g_free (node->name);
160         g_idl_node_free ((GIdlNode *)property->type);
161       }
162       break;
163
164     case G_IDL_NODE_SIGNAL:
165       {
166         GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
167         
168         g_free (node->name);
169         for (l = signal->parameters; l; l = l->next)
170           g_idl_node_free ((GIdlNode *)l->data);
171         g_list_free (signal->parameters);
172         g_idl_node_free ((GIdlNode *)signal->result);
173       }
174       break;
175
176     case G_IDL_NODE_VFUNC:
177       {
178         GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
179         
180         g_free (node->name);
181         for (l = vfunc->parameters; l; l = l->next)
182           g_idl_node_free ((GIdlNode *)l->data);
183         g_list_free (vfunc->parameters);
184         g_idl_node_free ((GIdlNode *)vfunc->result);
185       }
186       break;
187
188     case G_IDL_NODE_FIELD:
189       {
190         GIdlNodeField *field = (GIdlNodeField *)node;
191         
192         g_free (node->name);
193         g_free (field->c_name);
194         g_idl_node_free ((GIdlNode *)field->type);
195       }
196       break;
197
198     case G_IDL_NODE_OBJECT:
199     case G_IDL_NODE_INTERFACE:
200       {
201         GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
202         
203         g_free (node->name);
204         g_free (iface->c_name);
205         g_free (iface->init_func);
206         
207         g_free (iface->parent);
208
209         for (l = iface->interfaces; l; l = l->next)
210           g_free ((GIdlNode *)l->data);
211         g_list_free (iface->interfaces);
212
213         for (l = iface->members; l; l = l->next)
214           g_idl_node_free ((GIdlNode *)l->data);
215         g_list_free (iface->members);
216
217       }
218       break;
219  
220     case G_IDL_NODE_VALUE:
221       {
222         GIdlNodeValue *value = (GIdlNodeValue *)node;
223         
224         g_free (node->name);
225         g_free (value->c_name);
226       }
227       break;
228
229     case G_IDL_NODE_ENUM:
230     case G_IDL_NODE_FLAGS:
231       {
232         GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
233         
234         g_free (node->name);
235         for (l = enum_->values; l; l = l->next)
236           g_idl_node_free ((GIdlNode *)l->data);
237         g_list_free (enum_->values);
238       }
239       break;
240
241     case G_IDL_NODE_BOXED:
242       {
243         GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
244         
245         g_free (node->name);
246         g_free (boxed->c_name);
247         g_free (boxed->init_func);
248
249         for (l = boxed->members; l; l = l->next)
250           g_idl_node_free ((GIdlNode *)l->data);
251         g_list_free (boxed->members);
252       }
253       break;
254
255     case G_IDL_NODE_STRUCT:
256       {
257         GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
258
259         g_free (node->name);
260         for (l = struct_->members; l; l = l->next)
261           g_idl_node_free ((GIdlNode *)l->data);
262         g_list_free (struct_->members);
263       }
264       break;
265
266     case G_IDL_NODE_CONSTANT:
267       {
268         GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
269         
270         g_free (node->name);
271         g_free (constant->value);
272         g_idl_node_free ((GIdlNode *)constant->type);
273       }
274       break;
275
276     case G_IDL_NODE_ERROR_DOMAIN:
277       {
278         GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
279         
280         g_free (node->name);
281         g_free (domain->getquark);
282         g_free (domain->codes);
283       }
284       break;
285
286     case G_IDL_NODE_XREF:
287       {
288         GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
289         
290         g_free (node->name);
291         g_free (xref->namespace);
292       }
293       break;
294
295     default:
296       g_error ("Unhandled node type %d\n", node->type);
297       break;
298     } 
299
300   g_free (node);
301 }
302
303 /* returns the fixed size of the blob */
304 guint32
305 g_idl_node_get_size (GIdlNode *node)
306 {
307   GList *l;
308   gint size, n;
309
310   switch (node->type)
311     {
312     case G_IDL_NODE_CALLBACK:
313       size = 12; 
314       break;
315
316     case G_IDL_NODE_FUNCTION:
317       size = 16; 
318       break;
319
320     case G_IDL_NODE_PARAM:
321       size = 12;
322       break;
323
324     case G_IDL_NODE_TYPE:
325       size = 4;
326       break;
327
328     case G_IDL_NODE_OBJECT:
329       {
330         GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
331
332         n = g_list_length (iface->interfaces);
333         size = 32 + 2 * (n + (n % 2));
334
335         for (l = iface->members; l; l = l->next)
336           size += g_idl_node_get_size ((GIdlNode *)l->data);
337       }
338       break;
339
340     case G_IDL_NODE_INTERFACE:
341       {
342         GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
343
344         n = g_list_length (iface->prerequisites);
345         size = 28 + 2 * (n + (n % 2));
346
347         for (l = iface->members; l; l = l->next)
348           size += g_idl_node_get_size ((GIdlNode *)l->data);
349       }
350       break;
351
352     case G_IDL_NODE_ENUM:
353     case G_IDL_NODE_FLAGS:
354       {
355         GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
356         
357         n = g_list_length (enum_->values);
358         size = 20 + n * 16;
359       }
360       break;
361
362     case G_IDL_NODE_VALUE:
363       size = 16;
364       break;
365
366     case G_IDL_NODE_STRUCT:
367     case G_IDL_NODE_BOXED:
368       {
369         GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
370
371         size = 20;
372         for (l = boxed->members; l; l = l->next)
373           size += g_idl_node_get_size ((GIdlNode *)l->data);
374       }
375       break;
376
377     case G_IDL_NODE_PROPERTY:
378       size = 12;
379       break;
380
381     case G_IDL_NODE_SIGNAL:
382       size = 12;
383       break;
384
385     case G_IDL_NODE_VFUNC:
386       size = 16;
387       break;
388
389     case G_IDL_NODE_FIELD:
390       size = 12;
391       break;
392
393     case G_IDL_NODE_CONSTANT:
394       size = 20;
395       break;
396
397     case G_IDL_NODE_ERROR_DOMAIN:
398       size = 16;
399       break;
400
401     case G_IDL_NODE_XREF:
402       size = 0;
403       break;
404
405     default: 
406       g_error ("Unhandled node type %d\n", node->type);
407       size = 0;
408     }
409
410   return size;
411 }
412
413 /* returns the full size of the blob including variable-size parts */
414 guint32
415 g_idl_node_get_full_size (GIdlNode *node)
416 {
417   GList *l;
418   gint size, n;
419
420   switch (node->type)
421     {
422     case G_IDL_NODE_CALLBACK:
423       {
424         GIdlNodeFunction *function = (GIdlNodeFunction *)node;
425         size = 12; 
426         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
427         for (l = function->parameters; l; l = l->next)
428           size += g_idl_node_get_full_size ((GIdlNode *)l->data);
429         size += g_idl_node_get_full_size ((GIdlNode *)function->result);
430       }
431       break;
432
433     case G_IDL_NODE_FUNCTION:
434       {
435         GIdlNodeFunction *function = (GIdlNodeFunction *)node;
436         size = 16;
437         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
438         size += ALIGN_VALUE (strlen (function->c_name) + 1, 4);
439         for (l = function->parameters; l; l = l->next)
440           size += g_idl_node_get_full_size ((GIdlNode *)l->data);
441         size += g_idl_node_get_full_size ((GIdlNode *)function->result);
442       }
443       break;
444
445     case G_IDL_NODE_PARAM:
446       {
447         GIdlNodeParam *param = (GIdlNodeParam *)node;
448         
449         size = 12;
450         if (node->name)
451           size += ALIGN_VALUE (strlen (node->name) + 1, 4);
452         size += g_idl_node_get_full_size ((GIdlNode *)param->type);     
453       }
454       break;
455
456     case G_IDL_NODE_TYPE:
457       {
458         GIdlNodeType *type = (GIdlNodeType *)node;
459         if (type->tag < 20) 
460           size = 4;
461         else
462           {
463             switch (type->tag)
464               {
465               case 20:
466                 size = 4 + 4 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
467                 break;
468               case 21:
469                 size = 4 + 4;
470                 break;
471               case 22:
472               case 23:
473                 size = 4 + 4 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
474                 break;
475               case 24:
476                 size = 4 + 4
477                   + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1)
478                   + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type2);
479                 break;
480               case 25:
481                 {
482                   gint n = g_strv_length (type->errors);
483                   size = 4 + 4 + 2 * (n + n % 2);
484                 }
485                 break;
486               default:
487                 g_error ("Unknown type tag %d\n", type->tag);
488                 break;
489               }
490           }
491       }
492       break;
493
494     case G_IDL_NODE_OBJECT:
495       {
496         GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
497
498         n = g_list_length (iface->interfaces);
499         size = 32;
500         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
501         size += ALIGN_VALUE (strlen (iface->c_name) + 1, 4);
502         size += ALIGN_VALUE (strlen (iface->init_func) + 1, 4);
503         size += 2 * (n + (n % 2));
504
505         for (l = iface->members; l; l = l->next)
506           size += g_idl_node_get_full_size ((GIdlNode *)l->data);
507       }
508       break;
509
510     case G_IDL_NODE_INTERFACE:
511       {
512         GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
513
514         n = g_list_length (iface->prerequisites);
515         size = 28;
516         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
517         size += ALIGN_VALUE (strlen (iface->c_name) + 1, 4);
518         size += ALIGN_VALUE (strlen (iface->init_func) + 1, 4);
519         size += 2 * (n + (n % 2));
520
521         for (l = iface->members; l; l = l->next)
522           size += g_idl_node_get_full_size ((GIdlNode *)l->data);
523       }
524       break;
525
526     case G_IDL_NODE_ENUM:
527     case G_IDL_NODE_FLAGS:
528       {
529         GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
530         
531         size = 20;
532         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
533         size += ALIGN_VALUE (strlen (enum_->c_name) + 1, 4);
534         if (enum_->init_func)
535           size += ALIGN_VALUE (strlen (enum_->init_func) + 1, 4);
536
537         for (l = enum_->values; l; l = l->next)
538           size += g_idl_node_get_full_size ((GIdlNode *)l->data);       
539       }
540       break;
541
542     case G_IDL_NODE_VALUE:
543       {
544         GIdlNodeValue *value = (GIdlNodeValue *)node;
545         
546         size = 16;
547         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
548         size += ALIGN_VALUE (strlen (value->c_name) + 1, 4);
549       }
550       break;
551
552     case G_IDL_NODE_STRUCT:
553       {
554         GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
555
556         size = 20;
557         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
558         for (l = struct_->members; l; l = l->next)
559           size += g_idl_node_get_full_size ((GIdlNode *)l->data);
560       }
561       break;
562
563     case G_IDL_NODE_BOXED:
564       {
565         GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
566
567         size = 20;
568         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
569         if (boxed->c_name)
570           size += ALIGN_VALUE (strlen (boxed->c_name) + 1, 4);
571         if (boxed->init_func)
572           size += ALIGN_VALUE (strlen (boxed->init_func) + 1, 4);
573         for (l = boxed->members; l; l = l->next)
574           size += g_idl_node_get_full_size ((GIdlNode *)l->data);
575       }
576       break;
577
578     case G_IDL_NODE_PROPERTY:
579       {
580         GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
581         
582         size = 12;
583         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
584         size += g_idl_node_get_full_size ((GIdlNode *)prop->type);      
585       }
586       break;
587
588     case G_IDL_NODE_SIGNAL:
589       {
590         GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
591
592         size = 12;
593         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
594         for (l = signal->parameters; l; l = l->next)
595           size += g_idl_node_get_full_size ((GIdlNode *)l->data);
596         size += g_idl_node_get_full_size ((GIdlNode *)signal->result);
597       }
598       break;
599
600     case G_IDL_NODE_VFUNC:
601       {
602         GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
603
604         size = 16;
605         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
606         for (l = vfunc->parameters; l; l = l->next)
607           size += g_idl_node_get_full_size ((GIdlNode *)l->data);
608         size += g_idl_node_get_full_size ((GIdlNode *)vfunc->result);
609       }
610       break;
611
612     case G_IDL_NODE_FIELD:
613       {
614         GIdlNodeField *field = (GIdlNodeField *)node;
615
616         size = 12;
617         size += ALIGN_VALUE (strlen (field->c_name) + 1, 4);
618         size += g_idl_node_get_full_size ((GIdlNode *)field->type);     
619       }
620       break;
621
622     case G_IDL_NODE_CONSTANT:
623       {
624         GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
625
626         size = 20;
627         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
628         /* FIXME non-string values */
629         size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
630         size += g_idl_node_get_full_size ((GIdlNode *)constant->type);  
631       }
632       break;
633
634     case G_IDL_NODE_ERROR_DOMAIN:
635       {
636         GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
637
638         size = 16;
639         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
640         size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
641       }
642       break;
643
644     case G_IDL_NODE_XREF:
645       {
646         GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
647         
648         size = 0;
649         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
650         size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
651       }
652       break;
653
654     default: 
655       g_error ("Unknown type tag %d\n", node->type);
656       size = 0;
657     }
658
659   return size;
660 }
661
662 static gint64
663 parse_int_value (const gchar *str)
664 {
665   return strtoll (str, NULL, 0);
666 }
667
668 static guint64
669 parse_uint_value (const gchar *str)
670 {
671   return strtoull (str, NULL, 0);
672 }
673
674 static gdouble
675 parse_float_value (const gchar *str)
676 {
677   return strtod (str, NULL);
678 }
679
680 static gboolean
681 parse_boolean_value (const gchar *str)
682 {
683   if (strcmp (str, "TRUE") == 0)
684     return TRUE;
685   
686   if (strcmp (str, "FALSE") == 0)
687     return FALSE;
688
689   return parse_int_value (str) ? TRUE : FALSE;
690 }
691
692 static GIdlNode *
693 find_entry_node (GIdlModule  *module,
694                  GList       *modules,
695                  const gchar *name,
696                  guint16     *idx)
697 {
698   GList *l, *m;
699   gint i;
700
701   for (l = module->entries, i = 0; l; l = l->next, i++)
702     {
703       GIdlNode *node = (GIdlNode *)l->data;
704       
705       if (strcmp (node->name, name) == 0)
706         {
707           if (idx)
708             *idx = i;
709           return node;
710         }
711     }
712
713   for (m = modules; m; m = m->next)
714     {
715       GIdlModule *foreign = (GIdlModule *)m->data;
716
717       if (foreign == module)
718         continue;
719       
720       for (l = foreign->entries; l; l = l->next)
721         {
722           GIdlNode *node = (GIdlNode *)l->data;
723           
724           if (node->type == G_IDL_NODE_XREF)
725             continue;
726
727           if (strcmp (node->name, name) == 0)
728             {
729               GIdlNode *xref = g_idl_node_new (G_IDL_NODE_XREF);
730               xref->name = g_strdup (name);
731               ((GIdlNodeXRef *)xref)->namespace = g_strdup (foreign->name);
732
733               module->entries = g_list_append (module->entries, xref);
734               
735               if (idx)
736                 *idx = g_list_length (module->entries) - 1;
737
738               return xref;
739             }
740         }
741     }
742
743   g_warning ("No such entry: '%s'\n", name);
744
745   return NULL;
746 }
747
748 static guint16
749 find_entry (GIdlModule  *module,
750             GList       *modules,
751             const gchar *name)
752 {
753   guint16 idx;
754
755   find_entry_node (module, modules, name, &idx);
756
757   return idx;
758 }
759
760 static void
761 serialize_type (GIdlModule   *module, 
762                 GList        *modules,
763                 GIdlNodeType *node, 
764                 GString      *str)
765 {
766   gint i;
767   
768   const gchar* basic[] = {
769     "void", 
770     "gboolean", 
771     "gint8", 
772     "guint8", 
773     "gint16", 
774     "guint16", 
775     "gint32", 
776     "guint32", 
777     "gint64", 
778     "guint64", 
779     "gfloat", 
780     "gdouble", 
781     "gchar", 
782     "GString", 
783     "gint", 
784     "guint", 
785     "glong", 
786     "gulong"
787   };
788
789   if (node->tag < 20)
790     {
791       g_string_append_printf (str, "%s%s", 
792                               basic[node->tag], node->is_pointer ? "*" : "");
793     }
794   else if (node->tag == 20)
795     {
796       serialize_type (module, modules, node->parameter_type1, str);
797       g_string_append (str, "[");
798
799       if (node->has_length)
800         g_string_append_printf (str, "length=%d", node->length);
801       
802       if (node->zero_terminated)
803         g_string_append_printf (str, "%szero-terminated=1", 
804                                 node->has_length ? "," : "");
805       
806       g_string_append (str, "]");
807     }
808   else if (node->tag == 21)
809     {
810       GIdlNode *iface;
811
812       iface = find_entry_node (module, modules, node->interface, NULL);
813       g_string_append_printf (str, "%s%s", 
814                               iface->name, node->is_pointer ? "*" : "");
815     }
816   else if (node->tag == 22)
817     {
818       g_string_append (str, "GList<");
819       serialize_type (module, modules, node->parameter_type1, str);
820       g_string_append (str, ">"); 
821     }
822   else if (node->tag == 23)
823     {
824       g_string_append (str, "GSList<");
825       serialize_type (module, modules, node->parameter_type1, str);
826       g_string_append (str, ">"); 
827     }
828   else if (node->tag == 24)
829     {
830       g_string_append (str, "GHashTable<");
831       serialize_type (module, modules, node->parameter_type1, str);
832       g_string_append (str, ","); 
833       serialize_type (module, modules, node->parameter_type2, str);
834       g_string_append (str, ">"); 
835     }
836   else if (node->tag == 25) 
837     {
838       g_string_append (str, "GError<");
839       for (i = 0; node->errors[i]; i++)
840         {
841           if (i > 0)
842             g_string_append (str, ",");
843           g_string_append (str, node->errors[i]);
844         }
845       g_string_append (str, ">"); 
846     }
847 }
848
849 void
850 g_idl_node_build_metadata (GIdlNode   *node,
851                            GIdlModule *module,
852                            GList      *modules,
853                            GHashTable *strings,
854                            GHashTable *types,
855                            guchar     *data,
856                            guint32    *offset,
857                            guint32    *offset2)
858 {
859   GList *l;
860
861   switch (node->type)
862     {
863     case G_IDL_NODE_TYPE:
864       {
865         GIdlNodeType *type = (GIdlNodeType *)node;
866         SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
867
868         *offset += 4;
869         
870         if (type->tag < 20)
871           {
872             blob->reserved = 0;
873             blob->reserved2 = 0;
874             blob->pointer = type->is_pointer;
875             blob->reserved3 = 0;
876             blob->tag = type->tag;
877           }
878         else 
879           {
880             GString *str;
881             gchar *s;
882             gpointer value;
883             
884             str = g_string_new (0);
885             serialize_type (module, modules, type, str);
886             s = g_string_free (str, FALSE);
887             
888             value = g_hash_table_lookup (types, s);
889             if (value)
890               {
891                 blob->offset = GPOINTER_TO_INT (value);
892                 g_free (s);
893               }
894             else
895               {
896                 g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
897                                      
898                 blob->offset = *offset2;
899                 switch (type->tag)
900                   {
901                   case 20:
902                     {
903                       ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
904                       guint32 pos;
905                       
906                       array->pointer = 1;
907                       array->reserved = 0;
908                       array->tag = type->tag;
909                       array->zero_terminated = type->zero_terminated;
910                       array->has_length = type->has_length;
911                       array->reserved2 = 0;
912                       array->length = type->length;
913                       
914                       pos = *offset2 + 4;
915                       *offset2 += 8;
916                       
917                       g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1, 
918                                                  module, modules, strings, types, 
919                                                  data, &pos, offset2);
920                     }
921                     break;
922                     
923                   case 21:
924                     {
925                       InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
926                       gint i, interface;
927                       
928                       *offset2 += 4;
929                       
930                       iface->pointer = 1;
931                       iface->reserved = 0;
932                       iface->tag = type->tag;
933                       iface->reserved2 = 0;
934                       iface->interface = 0;
935                       iface->interface = find_entry (module, modules, type->interface);
936                     }
937                     break;
938                     
939                   case 22:
940                   case 23:
941                     {
942                       ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
943                       guint32 pos;
944                       
945                       param->pointer = 1;
946                       param->reserved = 0;
947                       param->tag = type->tag;
948                       param->reserved2 = 0;
949                       param->n_types = 1;
950                       
951                       pos = *offset2 + 4;
952                       *offset2 += 8;
953                       
954                       g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1, 
955                                                  module, modules, strings, types,
956                                                  data, &pos, offset2);
957                     }
958                     break;
959                     
960                   case 24:
961                     {
962                       ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
963                       guint32 pos;
964                       
965                       param->pointer = 1;
966                       param->reserved = 0;
967                       param->tag = type->tag;
968                       param->reserved2 = 0;
969                       param->n_types = 2;
970                       
971                       pos = *offset2 + 4;
972                       *offset2 += 12;
973                       
974                       g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1, 
975                                                  module, modules, strings, types, 
976                                                  data, &pos, offset2);
977                       g_idl_node_build_metadata ((GIdlNode *)type->parameter_type2, 
978                                                  module, modules, strings, types, 
979                                                  data, &pos, offset2);
980                     }
981                     break;
982                     
983                   case 25:
984                     {
985                       ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
986                       gint i, domain;
987                       
988                       blob->pointer = 1;
989                       blob->reserved = 0;
990                       blob->tag = type->tag;
991                       blob->reserved2 = 0;
992                       blob->n_domains = g_strv_length (type->errors);
993                       
994                       *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4);
995                       for (i = 0; type->errors[i]; i++)
996                         blob->domains[i] = find_entry (module, modules, type->errors[i]);
997                     }
998                     break;
999                     
1000                   default:
1001                     g_error ("Unknown type tag %d\n", type->tag);
1002                     break;
1003                   }
1004               }
1005           }
1006       }
1007       break;
1008
1009     case G_IDL_NODE_FIELD:
1010       {
1011         GIdlNodeField *field = (GIdlNodeField *)node;
1012         FieldBlob *blob;
1013
1014         blob = (FieldBlob *)&data[*offset];
1015         *offset += 8;
1016
1017         blob->name = write_string (field->c_name, strings, data, offset2);
1018         blob->readable = field->readable;
1019         blob->writable = field->writable;
1020         blob->reserved = 0;
1021         blob->bits = 0;
1022         blob->struct_offset = 0;
1023
1024         g_idl_node_build_metadata ((GIdlNode *)field->type, 
1025                                    module, modules, strings, types,
1026                                    data, offset, offset2);
1027       }
1028       break;
1029
1030     case G_IDL_NODE_PROPERTY:
1031       {
1032         GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
1033         PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1034         *offset += 8;
1035
1036         blob->name = write_string (node->name, strings, data, offset2);
1037         blob->deprecated = prop->deprecated;
1038         blob->readable = prop->readable;
1039         blob->writable = prop->writable;
1040         blob->construct = prop->construct;
1041         blob->construct_only = prop->construct_only;
1042         blob->reserved = 0;
1043
1044         g_idl_node_build_metadata ((GIdlNode *)prop->type, 
1045                                    module, modules, strings, types,
1046                                    data, offset, offset2);
1047       }
1048       break;
1049
1050     case G_IDL_NODE_FUNCTION:
1051       {
1052         FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1053         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1054         GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1055         guint32 signature, res;
1056         gint n;
1057
1058         signature = *offset2;
1059         n = g_list_length (function->parameters);
1060
1061         *offset += 16;
1062         *offset2 += 8 + n * 12;
1063
1064         blob->blob_type = BLOB_TYPE_FUNCTION;
1065         blob->deprecated = function->deprecated;
1066         blob->setter = function->is_setter;
1067         blob->getter = function->is_getter;
1068         blob->constructor = function->is_constructor;
1069         blob->wraps_vfunc = function->wraps_vfunc;
1070         blob->reserved = 0;
1071         blob->index = 0;
1072         blob->name = write_string (node->name, strings, data, offset2);
1073         blob->c_name = write_string (function->c_name, strings, data, offset2);
1074         blob->signature = signature;
1075         
1076         g_idl_node_build_metadata ((GIdlNode *)function->result->type, 
1077                                    module, modules, strings, types,
1078                                    data, &signature, offset2);
1079
1080         blob2->may_return_null = function->result->null_ok;
1081         blob2->caller_owns_return_value = function->result->transfer;
1082         blob2->caller_owns_return_container = function->result->shallow_transfer;
1083         blob2->reserved = 0;
1084         blob2->n_arguments = n;
1085
1086         signature += 4;
1087         
1088         for (l = function->parameters; l; l = l->next)
1089           {
1090             GIdlNode *param = (GIdlNode *)l->data;
1091
1092             g_idl_node_build_metadata (param, 
1093                                        module, modules, strings, types,
1094                                        data, &signature, offset2);
1095           }
1096       }
1097       break;
1098
1099     case G_IDL_NODE_CALLBACK:
1100       {
1101         CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1102         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1103         GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1104         guint32 signature, res;
1105         gint n;
1106
1107         signature = *offset2;
1108         n = g_list_length (function->parameters);
1109
1110         *offset += 12;
1111         *offset2 += 8 + n * 12;
1112
1113         blob->blob_type = BLOB_TYPE_CALLBACK;
1114         blob->deprecated = function->deprecated;
1115         blob->reserved = 0;
1116         blob->name = write_string (node->name, strings, data, offset2);
1117         blob->signature = signature;
1118         
1119         g_idl_node_build_metadata ((GIdlNode *)function->result->type, 
1120                                    module, modules, strings, types,
1121                                    data, &signature, offset2);
1122
1123         blob2->may_return_null = function->result->null_ok;
1124         blob2->caller_owns_return_value = function->result->transfer;
1125         blob2->caller_owns_return_container = function->result->shallow_transfer;
1126         blob2->reserved = 0;
1127         blob2->n_arguments = n;
1128
1129         signature += 4;
1130         
1131         for (l = function->parameters; l; l = l->next)
1132           {
1133             GIdlNode *param = (GIdlNode *)l->data;
1134
1135             g_idl_node_build_metadata (param, 
1136                                        module, modules, strings, types,
1137                                        data, &signature, offset2);
1138           }
1139       }
1140       break;
1141
1142     case G_IDL_NODE_SIGNAL:
1143       {
1144         SignalBlob *blob = (SignalBlob *)&data[*offset];
1145         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1146         GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
1147         guint32 signature, res;
1148         gint n;
1149
1150         signature = *offset2;
1151         n = g_list_length (signal->parameters);
1152
1153         *offset += 12;
1154         *offset2 += 8 + n * 12;
1155
1156         blob->deprecated = signal->deprecated;
1157         blob->run_first = signal->run_first;
1158         blob->run_last = signal->run_last;
1159         blob->run_cleanup = signal->run_cleanup;
1160         blob->no_recurse = signal->no_recurse;
1161         blob->detailed = signal->detailed;
1162         blob->action = signal->action;
1163         blob->no_hooks = signal->no_hooks;
1164         blob->has_class_closure = 0; /* FIXME */
1165         blob->true_stops_emit = 0; /* FIXME */
1166         blob->reserved = 0;
1167         blob->class_closure = 0; /* FIXME */
1168         blob->name = write_string (node->name, strings, data, offset2);
1169         blob->signature = signature;
1170         
1171         g_idl_node_build_metadata ((GIdlNode *)signal->result->type, 
1172                                    module, modules, strings, types,
1173                                    data, &signature, offset2);
1174
1175         blob2->may_return_null = signal->result->null_ok;
1176         blob2->caller_owns_return_value = signal->result->transfer;
1177         blob2->caller_owns_return_container = signal->result->shallow_transfer;
1178         blob2->reserved = 0;
1179         blob2->n_arguments = n;
1180
1181         signature += 4;
1182         
1183         for (l = signal->parameters; l; l = l->next)
1184           {
1185             GIdlNode *param = (GIdlNode *)l->data;
1186
1187             g_idl_node_build_metadata (param, module, modules, strings, types,
1188                                        data, &signature, offset2);
1189           }
1190       }
1191       break;
1192
1193     case G_IDL_NODE_VFUNC:
1194       {
1195         VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1196         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1197         GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
1198         guint32 signature, res;
1199         gint n;
1200
1201         signature = *offset2;
1202         n = g_list_length (vfunc->parameters);
1203
1204         *offset += 16;
1205         *offset2 += 8 + n * 12;
1206
1207         blob->name = write_string (node->name, strings, data, offset2);
1208         blob->must_chain_up = 0; /* FIXME */
1209         blob->must_be_implemented = 0; /* FIXME */
1210         blob->must_not_be_implemented = 0; /* FIXME */
1211         blob->class_closure = 0; /* FIXME */
1212         blob->reserved = 0;
1213
1214         blob->struct_offset = 0; /* FIXME */
1215         blob->reserved2 = 0;
1216         blob->signature = signature;
1217         
1218         g_idl_node_build_metadata ((GIdlNode *)vfunc->result->type, 
1219                                    module, modules, strings, types,
1220                                    data, &signature, offset2);
1221
1222         blob2->may_return_null = vfunc->result->null_ok;
1223         blob2->caller_owns_return_value = vfunc->result->transfer;
1224         blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1225         blob2->reserved = 0;
1226         blob2->n_arguments = n;
1227
1228         signature += 4;
1229         
1230         for (l = vfunc->parameters; l; l = l->next)
1231           {
1232             GIdlNode *param = (GIdlNode *)l->data;
1233
1234             g_idl_node_build_metadata (param, module, modules, strings, 
1235                                        types, data, &signature, offset2);
1236           }
1237       }
1238       break;
1239
1240     case G_IDL_NODE_PARAM:
1241       {
1242         ArgBlob *blob = (ArgBlob *)&data[*offset];
1243         GIdlNodeParam *param = (GIdlNodeParam *)node;
1244         guint32 res;
1245
1246         *offset += 8;
1247
1248         blob->name = write_string (node->name, strings, data, offset2);
1249         blob->in = param->in;
1250         blob->out = param->out;
1251         blob->dipper = param->dipper;
1252         blob->null_ok = param->null_ok;
1253         blob->optional = param->optional;
1254         blob->transfer_ownership = param->transfer;
1255         blob->transfer_container_ownership = param->shallow_transfer;
1256         blob->return_value = param->retval;
1257         blob->reserved = 0;
1258
1259         g_idl_node_build_metadata ((GIdlNode *)param->type, module, modules, 
1260                                    types, strings, data, offset, offset2);
1261       }
1262       break;
1263
1264     case G_IDL_NODE_STRUCT:
1265       {
1266         StructBlob *blob = (StructBlob *)&data[*offset];
1267         GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
1268         guint32 pos;
1269         
1270         blob->blob_type = BLOB_TYPE_STRUCT;
1271         blob->deprecated = struct_->deprecated;
1272         blob->unregistered = TRUE;
1273         blob->reserved = 0;
1274         blob->name = write_string (node->name, strings, data, offset2);
1275         blob->gtype_name = 0;
1276         blob->gtype_init = 0;
1277
1278         blob->n_fields = 0;
1279         blob->n_methods = 0;
1280
1281         *offset += 20; 
1282         for (l = struct_->members; l; l = l->next)
1283           {
1284             GIdlNode *member = (GIdlNode *)l->data;
1285
1286             if (member->type == G_IDL_NODE_FIELD)
1287               {
1288                 blob->n_fields++;
1289                 g_idl_node_build_metadata (member, module, modules, strings, 
1290                                            types, data, offset, offset2);
1291               }
1292           }
1293
1294         for (l = struct_->members; l; l = l->next)
1295           {
1296             GIdlNode *member = (GIdlNode *)l->data;
1297             
1298             if (member->type == G_IDL_NODE_FUNCTION)
1299               {
1300                 blob->n_methods++;
1301                 g_idl_node_build_metadata (member, module, modules, strings, 
1302                                            types, data, offset, offset2);
1303               }
1304           }
1305       }
1306       break;
1307
1308     case G_IDL_NODE_BOXED:
1309       {
1310         StructBlob *blob = (StructBlob *)&data[*offset];
1311         GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
1312
1313         blob->blob_type = BLOB_TYPE_BOXED;
1314         blob->deprecated = boxed->deprecated;
1315         blob->unregistered = FALSE;
1316         blob->reserved = 0;
1317         blob->name = write_string (node->name, strings, data, offset2);
1318         blob->gtype_name = write_string (boxed->c_name, strings, data, offset2);
1319         blob->gtype_init = write_string (boxed->init_func, strings, data, offset2);
1320
1321         blob->n_fields = 0;
1322         blob->n_methods = 0;
1323
1324         *offset += 20; 
1325         for (l = boxed->members; l; l = l->next)
1326           {
1327             GIdlNode *member = (GIdlNode *)l->data;
1328
1329             if (member->type == G_IDL_NODE_FIELD)
1330               {
1331                 blob->n_fields++;
1332                 g_idl_node_build_metadata (member, module, modules, strings, 
1333                                            types, data, offset, offset2);
1334               }
1335           }
1336
1337         for (l = boxed->members; l; l = l->next)
1338           {
1339             GIdlNode *member = (GIdlNode *)l->data;
1340
1341             if (member->type == G_IDL_NODE_FUNCTION)
1342               {
1343                 blob->n_methods++;
1344                 g_idl_node_build_metadata (member, module, modules, strings, 
1345                                            types, data, offset, offset2);
1346               }
1347           }
1348       }
1349       break;
1350
1351     case G_IDL_NODE_ENUM:
1352     case G_IDL_NODE_FLAGS:
1353       {
1354         EnumBlob *blob = (EnumBlob *)&data[*offset];
1355         GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
1356
1357         *offset += 20; 
1358         
1359         if (node->type == G_IDL_NODE_ENUM)
1360           blob->blob_type = BLOB_TYPE_ENUM;
1361         else
1362           blob->blob_type = BLOB_TYPE_FLAGS;
1363           
1364         blob->deprecated = enum_->deprecated;
1365         blob->reserved = 0;
1366         blob->name = write_string (node->name, strings, data, offset2);
1367         blob->gtype_name = write_string (enum_->c_name, strings, data, offset2);
1368         if (enum_->init_func)
1369           {
1370             blob->unregistered = FALSE;
1371             blob->gtype_init = write_string (enum_->init_func, strings, data, offset2);
1372           }
1373         else
1374           {
1375             blob->unregistered = TRUE;
1376             blob->gtype_init = 0;
1377           }
1378
1379         blob->n_values = 0;
1380         blob->reserved2 = 0;
1381
1382         for (l = enum_->values; l; l = l->next)
1383           {
1384             GIdlNode *value = (GIdlNode *)l->data;
1385
1386             blob->n_values++;
1387             g_idl_node_build_metadata (value, module, modules, strings, types,
1388                                        data, offset, offset2);
1389           }
1390       }
1391       break;
1392       
1393     case G_IDL_NODE_OBJECT:
1394       {
1395         ObjectBlob *blob = (ObjectBlob *)&data[*offset];
1396         GIdlNodeInterface *object = (GIdlNodeInterface *)node;
1397         gint parent;
1398
1399         blob->blob_type = BLOB_TYPE_OBJECT;
1400         blob->deprecated = object->deprecated;
1401         blob->reserved = 0;
1402         blob->name = write_string (node->name, strings, data, offset2);
1403         blob->gtype_name = write_string (object->c_name, strings, data, offset2);
1404         blob->gtype_init = write_string (object->init_func, strings, data, offset2);
1405         if (object->parent)
1406           blob->parent = find_entry (module, modules, object->parent);
1407         else
1408           blob->parent = 0;
1409
1410         blob->n_interfaces = 0;
1411         blob->n_fields = 0;
1412         blob->n_properties = 0;
1413         blob->n_methods = 0;
1414         blob->n_signals = 0;
1415         blob->n_vfuncs = 0;
1416         blob->n_constants = 0;
1417         
1418         *offset += 32;
1419         for (l = object->interfaces; l; l = l->next)
1420           {
1421             blob->n_interfaces++;
1422             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1423             *offset += 2;
1424           }
1425         
1426         *offset = ALIGN_VALUE (*offset, 4);
1427         for (l = object->members; l; l = l->next)
1428           {
1429             GIdlNode *member = (GIdlNode *)l->data;
1430
1431             if (member->type == G_IDL_NODE_FIELD)
1432               {
1433                 blob->n_fields++;
1434                 g_idl_node_build_metadata (member, module, modules, strings, 
1435                                            types, data, offset, offset2);
1436               }
1437           }
1438
1439         *offset = ALIGN_VALUE (*offset, 4);
1440         for (l = object->members; l; l = l->next)
1441           {
1442             GIdlNode *member = (GIdlNode *)l->data;
1443
1444             if (member->type == G_IDL_NODE_PROPERTY)
1445               {
1446                 blob->n_properties++;
1447                 g_idl_node_build_metadata (member, module, modules, strings, 
1448                                            types, data, offset, offset2);
1449               }
1450           }
1451
1452         *offset = ALIGN_VALUE (*offset, 4);
1453         for (l = object->members; l; l = l->next)
1454           {
1455             GIdlNode *member = (GIdlNode *)l->data;
1456
1457             if (member->type == G_IDL_NODE_FUNCTION)
1458               {
1459                 blob->n_methods++;
1460                 g_idl_node_build_metadata (member, module, modules, strings, 
1461                                            types, data, offset, offset2);
1462               }
1463           }
1464
1465         *offset = ALIGN_VALUE (*offset, 4);
1466         for (l = object->members; l; l = l->next)
1467           {
1468             GIdlNode *member = (GIdlNode *)l->data;
1469
1470             if (member->type == G_IDL_NODE_SIGNAL)
1471               {
1472                 blob->n_signals++;
1473                 g_idl_node_build_metadata (member, module, modules, strings, 
1474                                            types, data, offset, offset2);
1475               }
1476           }
1477
1478         *offset = ALIGN_VALUE (*offset, 4);
1479         for (l = object->members; l; l = l->next)
1480           {
1481             GIdlNode *member = (GIdlNode *)l->data;
1482
1483             if (member->type == G_IDL_NODE_VFUNC)
1484               {
1485                 blob->n_vfuncs++;
1486                 g_idl_node_build_metadata (member, module, modules, strings, 
1487                                            types, data, offset, offset2);
1488               }
1489           }
1490
1491         *offset = ALIGN_VALUE (*offset, 4);
1492         for (l = object->members; l; l = l->next)
1493           {
1494             GIdlNode *member = (GIdlNode *)l->data;
1495
1496             if (member->type == G_IDL_NODE_CONSTANT)
1497               {
1498                 blob->n_constants++;
1499                 g_idl_node_build_metadata (member, module, modules, strings, 
1500                                            types, data, offset, offset2);
1501               }
1502           }
1503       }
1504       break;
1505
1506     case G_IDL_NODE_INTERFACE:
1507       {
1508         InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
1509         GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
1510         gint parent;
1511
1512         blob->blob_type = BLOB_TYPE_INTERFACE;
1513         blob->deprecated = iface->deprecated;
1514         blob->reserved = 0;
1515         blob->name = write_string (node->name, strings, data, offset2);
1516         blob->gtype_name = write_string (iface->c_name, strings, data, offset2);
1517         blob->gtype_init = write_string (iface->init_func, strings, data, offset2);
1518         blob->n_prerequisites = 0;
1519         blob->n_properties = 0;
1520         blob->n_methods = 0;
1521         blob->n_signals = 0;
1522         blob->n_vfuncs = 0;
1523         blob->n_constants = 0;
1524         
1525         *offset += 28;
1526         for (l = iface->prerequisites; l; l = l->next)
1527           {
1528             blob->n_prerequisites++;
1529             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1530             *offset += 2;
1531           }
1532         
1533         *offset = ALIGN_VALUE (*offset, 4);
1534         for (l = iface->members; l; l = l->next)
1535           {
1536             GIdlNode *member = (GIdlNode *)l->data;
1537
1538             if (member->type == G_IDL_NODE_PROPERTY)
1539               {
1540                 blob->n_properties++;
1541                 g_idl_node_build_metadata (member, module, modules, strings, 
1542                                            types, data, offset, offset2);
1543               }
1544           }
1545
1546         *offset = ALIGN_VALUE (*offset, 4);
1547         for (l = iface->members; l; l = l->next)
1548           {
1549             GIdlNode *member = (GIdlNode *)l->data;
1550
1551             if (member->type == G_IDL_NODE_FUNCTION)
1552               {
1553                 blob->n_methods++;
1554                 g_idl_node_build_metadata (member, module, modules, strings, 
1555                                            types, data, offset, offset2);
1556               }
1557           }
1558
1559         *offset = ALIGN_VALUE (*offset, 4);
1560         for (l = iface->members; l; l = l->next)
1561           {
1562             GIdlNode *member = (GIdlNode *)l->data;
1563
1564             if (member->type == G_IDL_NODE_SIGNAL)
1565               {
1566                 blob->n_signals++;
1567                 g_idl_node_build_metadata (member, module, modules, strings, 
1568                                            types, data, offset, offset2);
1569               }
1570           }
1571
1572         *offset = ALIGN_VALUE (*offset, 4);
1573         for (l = iface->members; l; l = l->next)
1574           {
1575             GIdlNode *member = (GIdlNode *)l->data;
1576
1577             if (member->type == G_IDL_NODE_VFUNC)
1578               {
1579                 blob->n_vfuncs++;
1580                 g_idl_node_build_metadata (member, module, modules, strings, 
1581                                            types, data, offset, offset2);
1582               }
1583           }
1584
1585         *offset = ALIGN_VALUE (*offset, 4);
1586         for (l = iface->members; l; l = l->next)
1587           {
1588             GIdlNode *member = (GIdlNode *)l->data;
1589
1590             if (member->type == G_IDL_NODE_CONSTANT)
1591               {
1592                 blob->n_constants++;
1593                 g_idl_node_build_metadata (member, module, modules, strings, 
1594                                            types, data, offset, offset2);
1595               }
1596           }
1597       }
1598       break;
1599
1600
1601     case G_IDL_NODE_VALUE:
1602       {
1603         GIdlNodeValue *value = (GIdlNodeValue *)node;
1604         ValueBlob *blob = (ValueBlob *)&data[*offset];
1605         *offset += 16;
1606
1607         blob->deprecated = value->deprecated;
1608         blob->reserved = 0;
1609         blob->name = write_string (node->name, strings, data, offset2);
1610         blob->short_name = write_string (value->c_name, strings, data, offset2);
1611         blob->value = value->value;
1612       }
1613       break;
1614
1615     case G_IDL_NODE_ERROR_DOMAIN:
1616       {
1617         GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
1618         ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
1619         *offset += 16;
1620
1621         blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
1622         blob->deprecated = domain->deprecated;
1623         blob->reserved = 0;
1624         blob->name = write_string (node->name, strings, data, offset2);
1625         blob->get_quark = write_string (domain->getquark, strings, data, offset2);
1626         blob->error_codes = find_entry (module, modules, domain->codes);
1627         blob->reserved2 = 0;
1628       }
1629       break;
1630
1631     case G_IDL_NODE_CONSTANT:
1632       {
1633         GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
1634         ConstantBlob *blob = (ConstantBlob *)&data[*offset];
1635         gint pos;
1636
1637         pos = *offset + 8;
1638         *offset += 20;
1639
1640         blob->blob_type = BLOB_TYPE_CONSTANT;
1641         blob->deprecated = constant->deprecated;
1642         blob->reserved = 0;
1643         blob->name = write_string (node->name, strings, data, offset2);
1644
1645         blob->offset = *offset2;
1646         switch (constant->type->tag)
1647           {
1648           case 1:
1649             blob->size = 4;
1650             *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
1651             break;
1652             case 2:
1653             blob->size = 1;
1654               *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
1655             break;
1656           case 3:
1657             blob->size = 1;
1658             *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
1659             break;
1660           case 4:
1661             blob->size = 2;
1662             *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
1663             break;
1664           case 5:
1665             blob->size = 2;
1666             *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
1667             break;
1668           case 6:
1669             blob->size = 4;
1670             *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
1671             break;
1672           case 7:
1673             blob->size = 4;
1674             *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
1675             break;
1676           case 8:
1677             blob->size = 8;
1678             *(gint32*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
1679             break;
1680           case 9:
1681             blob->size = 8;
1682             *(guint32*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
1683             break;
1684           case 10:
1685             blob->size = sizeof (gfloat);
1686             *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
1687             break;
1688           case 11:
1689             blob->size = sizeof (gdouble);
1690             *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
1691             break;
1692           case 12:
1693             blob->size = strlen (constant->value) + 1;
1694             memcpy (&data[blob->offset], constant->value, blob->size);
1695             break;
1696           case 14:
1697             blob->size = sizeof (gint);
1698             *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
1699             break;
1700           case 15:
1701             blob->size = sizeof (guint);
1702             *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
1703             break;
1704           case 16:
1705             blob->size = sizeof (glong);
1706             *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
1707             break;
1708           case 17:
1709             blob->size = sizeof (gulong);
1710             *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
1711             break;
1712           }
1713         *offset2 += ALIGN_VALUE (blob->size, 4);
1714         
1715         g_idl_node_build_metadata ((GIdlNode *)constant->type, module, modules, 
1716                                    strings, types, data, &pos, offset2);
1717       }
1718       break;
1719     }
1720 }
1721
1722
1723 /* if str is already in the pool, return previous location, otherwise write str
1724  * to the metadata at offset, put it in the pool and update offset. If the 
1725  * metadata is not large enough to hold the string, reallocate it.
1726  */
1727 guint32 
1728 write_string (const gchar *str,
1729               GHashTable  *strings, 
1730               guchar      *data,
1731               guint32     *offset)
1732 {
1733   gpointer value;
1734   guint32 start;
1735
1736   value = g_hash_table_lookup (strings, str);
1737   
1738   if (value)
1739       return GPOINTER_TO_INT (value);
1740   
1741   g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
1742
1743   start = *offset;
1744   *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
1745
1746   strcpy (&data[start], str);
1747   
1748   return start;
1749 }