Add a parent parmeter to g_ir_node_build_typelib
[gnome.gobject-introspection] / girepository / girnode.c
1 /* GObject introspection: Typelib 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 #include <stdlib.h>
23 #include <string.h>
24
25 #include "girmodule.h"
26 #include "girnode.h"
27 #include "gtypelib.h"
28
29 static gulong string_count = 0;
30 static gulong unique_string_count = 0;
31 static gulong string_size = 0;
32 static gulong unique_string_size = 0;
33 static gulong types_count = 0;
34 static gulong unique_types_count = 0;
35
36 void
37 _g_irnode_init_stats (void)
38 {
39   string_count = 0;
40   unique_string_count = 0;
41   string_size = 0;
42   unique_string_size = 0;
43   types_count = 0;
44   unique_types_count = 0;
45 }
46
47 void
48 _g_irnode_dump_stats (void)
49 {
50   g_message ("%lu strings (%lu before sharing), %lu bytes (%lu before sharing)",
51              unique_string_count, string_count, unique_string_size, string_size);
52   g_message ("%lu types (%lu before sharing)", unique_types_count, types_count);
53 }
54
55 #define ALIGN_VALUE(this, boundary) \
56   (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
57
58
59 const gchar *
60 g_ir_node_type_to_string (GIrNodeTypeId type)
61 {
62   switch (type)
63     {
64     case G_IR_NODE_FUNCTION:
65       return "function";
66     case G_IR_NODE_CALLBACK:
67       return "callback";
68     case G_IR_NODE_PARAM:
69       return "param";
70     case G_IR_NODE_TYPE:
71       return "type";
72     case G_IR_NODE_OBJECT:
73       return "object";
74     case G_IR_NODE_INTERFACE:
75       return "interface";
76     case G_IR_NODE_SIGNAL:
77       return "signal";
78     case G_IR_NODE_PROPERTY:
79       return "property";
80     case G_IR_NODE_VFUNC:
81       return "vfunc";
82     case G_IR_NODE_FIELD:
83       return "field";
84     case G_IR_NODE_ENUM:
85       return "enum";
86     case G_IR_NODE_FLAGS:
87       return "flags";
88     case G_IR_NODE_BOXED:
89       return "boxed";
90     case G_IR_NODE_STRUCT:
91       return "struct";
92     case G_IR_NODE_VALUE:
93       return "value";
94     case G_IR_NODE_CONSTANT:
95       return "constant";
96     case G_IR_NODE_ERROR_DOMAIN:
97       return "error-domain";
98     case G_IR_NODE_XREF:
99       return "xref";
100     case G_IR_NODE_UNION:
101       return "union";
102     default:
103       return "unknown";
104     }
105 }
106
107 GIrNode *
108 g_ir_node_new (GIrNodeTypeId type)
109 {
110   GIrNode *node = NULL;
111
112   switch (type)
113     {
114    case G_IR_NODE_FUNCTION:
115    case G_IR_NODE_CALLBACK:
116       node = g_malloc0 (sizeof (GIrNodeFunction));
117       break;
118
119    case G_IR_NODE_PARAM:
120       node = g_malloc0 (sizeof (GIrNodeParam));
121       break;
122
123    case G_IR_NODE_TYPE:
124       node = g_malloc0 (sizeof (GIrNodeType));
125       break;
126
127     case G_IR_NODE_OBJECT:
128     case G_IR_NODE_INTERFACE:
129       node = g_malloc0 (sizeof (GIrNodeInterface));
130       break;
131
132     case G_IR_NODE_SIGNAL:
133       node = g_malloc0 (sizeof (GIrNodeSignal));
134       break;
135
136     case G_IR_NODE_PROPERTY:
137       node = g_malloc0 (sizeof (GIrNodeProperty));
138       break;
139
140     case G_IR_NODE_VFUNC:
141       node = g_malloc0 (sizeof (GIrNodeFunction));
142       break;
143
144     case G_IR_NODE_FIELD:
145       node = g_malloc0 (sizeof (GIrNodeField));
146       break;
147
148     case G_IR_NODE_ENUM:
149     case G_IR_NODE_FLAGS:
150       node = g_malloc0 (sizeof (GIrNodeEnum));
151       break;
152
153     case G_IR_NODE_BOXED:
154       node = g_malloc0 (sizeof (GIrNodeBoxed));
155       break;
156
157     case G_IR_NODE_STRUCT:
158       node = g_malloc0 (sizeof (GIrNodeStruct));
159       break;
160
161     case G_IR_NODE_VALUE:
162       node = g_malloc0 (sizeof (GIrNodeValue));
163       break;
164
165     case G_IR_NODE_CONSTANT:
166       node = g_malloc0 (sizeof (GIrNodeConstant));
167       break;
168
169     case G_IR_NODE_ERROR_DOMAIN:
170       node = g_malloc0 (sizeof (GIrNodeErrorDomain));
171       break;
172
173     case G_IR_NODE_XREF:
174       node = g_malloc0 (sizeof (GIrNodeXRef));
175       break;
176
177     case G_IR_NODE_UNION:
178       node = g_malloc0 (sizeof (GIrNodeUnion));
179       break;
180
181     default:
182       g_error ("Unhandled node type %d\n", type);
183       break;
184     }
185
186   node->type = type;
187
188   return node;
189 }
190
191 void
192 g_ir_node_free (GIrNode *node)
193 {
194   GList *l;
195
196   if (node == NULL)
197     return;
198
199   switch (node->type)
200     {
201     case G_IR_NODE_FUNCTION:
202     case G_IR_NODE_CALLBACK:
203       {
204         GIrNodeFunction *function = (GIrNodeFunction *)node;
205         
206         g_free (node->name);
207         g_free (function->symbol);
208         g_ir_node_free ((GIrNode *)function->result);
209         for (l = function->parameters; l; l = l->next)
210           g_ir_node_free ((GIrNode *)l->data);
211         g_list_free (function->parameters);
212       }
213       break;
214
215     case G_IR_NODE_TYPE:
216       {
217         GIrNodeType *type = (GIrNodeType *)node;
218         
219         g_free (node->name);
220         g_ir_node_free ((GIrNode *)type->parameter_type1);
221         g_ir_node_free ((GIrNode *)type->parameter_type2);
222
223         g_free (type->interface);
224         g_strfreev (type->errors);
225
226       }
227       break;
228
229     case G_IR_NODE_PARAM:
230       {
231         GIrNodeParam *param = (GIrNodeParam *)node;
232         
233         g_free (node->name);
234         g_ir_node_free ((GIrNode *)param->type);
235       }
236       break;
237
238     case G_IR_NODE_PROPERTY:
239       {
240         GIrNodeProperty *property = (GIrNodeProperty *)node;
241         
242         g_free (node->name);
243         g_ir_node_free ((GIrNode *)property->type);
244       }
245       break;
246
247     case G_IR_NODE_SIGNAL:
248       {
249         GIrNodeSignal *signal = (GIrNodeSignal *)node;
250         
251         g_free (node->name);
252         for (l = signal->parameters; l; l = l->next)
253           g_ir_node_free ((GIrNode *)l->data);
254         g_list_free (signal->parameters);
255         g_ir_node_free ((GIrNode *)signal->result);
256       }
257       break;
258
259     case G_IR_NODE_VFUNC:
260       {
261         GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
262         
263         g_free (node->name);
264         for (l = vfunc->parameters; l; l = l->next)
265           g_ir_node_free ((GIrNode *)l->data);
266         g_list_free (vfunc->parameters);
267         g_ir_node_free ((GIrNode *)vfunc->result);
268       }
269       break;
270
271     case G_IR_NODE_FIELD:
272       {
273         GIrNodeField *field = (GIrNodeField *)node;
274         
275         g_free (node->name);
276         g_ir_node_free ((GIrNode *)field->type);
277       }
278       break;
279
280     case G_IR_NODE_OBJECT:
281     case G_IR_NODE_INTERFACE:
282       {
283         GIrNodeInterface *iface = (GIrNodeInterface *)node;
284         
285         g_free (node->name);
286         g_free (iface->gtype_name);
287         g_free (iface->gtype_init);
288
289
290         g_free (iface->glib_type_struct);
291         g_free (iface->parent);
292
293         for (l = iface->interfaces; l; l = l->next)
294           g_free ((GIrNode *)l->data);
295         g_list_free (iface->interfaces);
296
297         for (l = iface->members; l; l = l->next)
298           g_ir_node_free ((GIrNode *)l->data);
299         g_list_free (iface->members);
300
301       }
302       break;
303  
304     case G_IR_NODE_VALUE:
305       {
306         g_free (node->name);
307       }
308       break;
309
310     case G_IR_NODE_ENUM:
311     case G_IR_NODE_FLAGS:
312       {
313         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
314         
315         g_free (node->name);
316         g_free (enum_->gtype_name);
317         g_free (enum_->gtype_init);
318
319         for (l = enum_->values; l; l = l->next)
320           g_ir_node_free ((GIrNode *)l->data);
321         g_list_free (enum_->values);
322       }
323       break;
324
325     case G_IR_NODE_BOXED:
326       {
327         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
328         
329         g_free (node->name);
330         g_free (boxed->gtype_name);
331         g_free (boxed->gtype_init);
332
333         for (l = boxed->members; l; l = l->next)
334           g_ir_node_free ((GIrNode *)l->data);
335         g_list_free (boxed->members);
336       }
337       break;
338
339     case G_IR_NODE_STRUCT:
340       {
341         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
342
343         g_free (node->name);
344         g_free (struct_->gtype_name);
345         g_free (struct_->gtype_init);
346
347         for (l = struct_->members; l; l = l->next)
348           g_ir_node_free ((GIrNode *)l->data);
349         g_list_free (struct_->members);
350       }
351       break;
352
353     case G_IR_NODE_CONSTANT:
354       {
355         GIrNodeConstant *constant = (GIrNodeConstant *)node;
356         
357         g_free (node->name);
358         g_free (constant->value);
359         g_ir_node_free ((GIrNode *)constant->type);
360       }
361       break;
362
363     case G_IR_NODE_ERROR_DOMAIN:
364       {
365         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
366         
367         g_free (node->name);
368         g_free (domain->getquark);
369         g_free (domain->codes);
370       }
371       break;
372
373     case G_IR_NODE_XREF:
374       {
375         GIrNodeXRef *xref = (GIrNodeXRef *)node;
376         
377         g_free (node->name);
378         g_free (xref->namespace);
379       }
380       break;
381
382     case G_IR_NODE_UNION:
383       {
384         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
385         
386         g_free (node->name);
387         g_free (union_->gtype_name);
388         g_free (union_->gtype_init);
389
390         g_ir_node_free ((GIrNode *)union_->discriminator_type);
391         for (l = union_->members; l; l = l->next)
392           g_ir_node_free ((GIrNode *)l->data);
393         for (l = union_->discriminators; l; l = l->next)
394           g_ir_node_free ((GIrNode *)l->data);
395       }
396       break;
397
398     default:
399       g_error ("Unhandled node type %d\n", node->type);
400       break;
401     } 
402
403   g_free (node);
404 }
405
406 /* returns the fixed size of the blob */
407 guint32
408 g_ir_node_get_size (GIrNode *node)
409 {
410   GList *l;
411   gint size, n;
412
413   switch (node->type)
414     {
415     case G_IR_NODE_CALLBACK:
416       size = sizeof (CallbackBlob);
417       break;
418
419     case G_IR_NODE_FUNCTION:
420       size = sizeof (FunctionBlob);
421       break;
422
423     case G_IR_NODE_PARAM:
424       /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
425       size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
426       break;
427
428     case G_IR_NODE_TYPE:
429       size = sizeof (SimpleTypeBlob);
430       break;
431
432     case G_IR_NODE_OBJECT:
433       {
434         GIrNodeInterface *iface = (GIrNodeInterface *)node;
435
436         n = g_list_length (iface->interfaces);
437         size = sizeof (ObjectBlob) + 2 * (n + (n % 2));
438
439         for (l = iface->members; l; l = l->next)
440           size += g_ir_node_get_size ((GIrNode *)l->data);
441       }
442       break;
443
444     case G_IR_NODE_INTERFACE:
445       {
446         GIrNodeInterface *iface = (GIrNodeInterface *)node;
447
448         n = g_list_length (iface->prerequisites);
449         size = sizeof (InterfaceBlob) + 2 * (n + (n % 2));
450
451         for (l = iface->members; l; l = l->next)
452           size += g_ir_node_get_size ((GIrNode *)l->data);
453       }
454       break;
455
456     case G_IR_NODE_ENUM:
457     case G_IR_NODE_FLAGS:
458       {
459         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
460         
461         size = sizeof (EnumBlob);
462         for (l = enum_->values; l; l = l->next)
463           size += g_ir_node_get_size ((GIrNode *)l->data);
464       }
465       break;
466
467     case G_IR_NODE_VALUE:
468       size = sizeof (ValueBlob);
469       break;
470
471     case G_IR_NODE_STRUCT:
472       {
473         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
474
475         size = sizeof (StructBlob);
476         for (l = struct_->members; l; l = l->next)
477           size += g_ir_node_get_size ((GIrNode *)l->data);
478       }
479       break;
480
481     case G_IR_NODE_BOXED:
482       {
483         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
484
485         size = sizeof (StructBlob);
486         for (l = boxed->members; l; l = l->next)
487           size += g_ir_node_get_size ((GIrNode *)l->data);
488       }
489       break;
490
491     case G_IR_NODE_PROPERTY:
492       size = sizeof (PropertyBlob);
493       break;
494
495     case G_IR_NODE_SIGNAL:
496       size = sizeof (SignalBlob);
497       break;
498
499     case G_IR_NODE_VFUNC:
500       size = sizeof (VFuncBlob);
501       break;
502
503     case G_IR_NODE_FIELD:
504       size = sizeof (FieldBlob);
505       break;
506
507     case G_IR_NODE_CONSTANT:
508       size = sizeof (ConstantBlob);
509       break;
510
511     case G_IR_NODE_ERROR_DOMAIN:
512       size = sizeof (ErrorDomainBlob);
513       break;
514
515     case G_IR_NODE_XREF:
516       size = 0;
517       break;
518
519     case G_IR_NODE_UNION:
520       {
521         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
522
523         size = sizeof (UnionBlob);
524         for (l = union_->members; l; l = l->next)
525           size += g_ir_node_get_size ((GIrNode *)l->data);
526         for (l = union_->discriminators; l; l = l->next)
527           size += g_ir_node_get_size ((GIrNode *)l->data);
528       }
529       break;
530
531     default: 
532       g_error ("Unhandled node type '%s'\n",
533                g_ir_node_type_to_string (node->type));
534       size = 0;
535     }
536
537   g_debug ("node %p type '%s' size %d", node,
538            g_ir_node_type_to_string (node->type), size);
539
540   return size;
541 }
542
543 /* returns the full size of the blob including variable-size parts */
544 static guint32
545 g_ir_node_get_full_size_internal (GIrNode *parent,
546                                   GIrNode *node)
547 {
548   GList *l;
549   gint size, n;
550
551   if (node == NULL && parent != NULL)
552     g_error ("Caught NULL node, parent=%s", parent->name);
553
554   g_debug ("node %p type '%s'", node,
555            g_ir_node_type_to_string (node->type));
556
557   switch (node->type)
558     {
559     case G_IR_NODE_CALLBACK:
560       {
561         GIrNodeFunction *function = (GIrNodeFunction *)node;
562         size = sizeof (CallbackBlob);
563         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
564         for (l = function->parameters; l; l = l->next)
565           {
566             size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
567           }
568         size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
569       }
570       break;
571
572     case G_IR_NODE_FUNCTION:
573       {
574         GIrNodeFunction *function = (GIrNodeFunction *)node;
575         size = sizeof (FunctionBlob);
576         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
577         size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
578         for (l = function->parameters; l; l = l->next)
579           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
580         size += g_ir_node_get_full_size_internal (node, (GIrNode *)function->result);
581       }
582       break;
583
584     case G_IR_NODE_PARAM:
585       {
586         GIrNodeParam *param = (GIrNodeParam *)node;
587         
588         /* See the comment in the G_IR_NODE_PARAM/ArgBlob writing below */
589         size = sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
590         if (node->name)
591           size += ALIGN_VALUE (strlen (node->name) + 1, 4);
592         size += g_ir_node_get_full_size_internal (node, (GIrNode *)param->type);        
593       }
594       break;
595
596     case G_IR_NODE_TYPE:
597       {
598         GIrNodeType *type = (GIrNodeType *)node;
599         size = sizeof (SimpleTypeBlob);
600         if (type->tag >= GI_TYPE_TAG_ARRAY)
601           {
602             g_debug ("node %p type tag '%s'", node,
603                      g_type_tag_to_string (type->tag));
604
605             switch (type->tag)
606               {
607               case GI_TYPE_TAG_ARRAY:
608                 size = sizeof (ArrayTypeBlob);
609                 if (type->parameter_type1)
610                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
611                 break;
612               case GI_TYPE_TAG_INTERFACE:
613                 size += sizeof (InterfaceTypeBlob);
614                 break;
615               case GI_TYPE_TAG_GLIST:
616               case GI_TYPE_TAG_GSLIST:
617                 size += sizeof (ParamTypeBlob);
618                 if (type->parameter_type1)
619                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
620                 break;
621               case GI_TYPE_TAG_GHASH:
622                 size += sizeof (ParamTypeBlob) * 2;
623                 if (type->parameter_type1)
624                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type1);
625                 if (type->parameter_type2)
626                   size += g_ir_node_get_full_size_internal (node, (GIrNode *)type->parameter_type2);
627                 break;
628               case GI_TYPE_TAG_ERROR:
629                 {
630                   gint n;
631                   
632                   if (type->errors)
633                     n = g_strv_length (type->errors);
634                   else
635                     n = 0;
636
637                   size += sizeof (ErrorTypeBlob) + 2 * (n + n % 2);
638                 }
639                 break;
640               default:
641                 g_error ("Unknown type tag %d\n", type->tag);
642                 break;
643               }
644           }
645       }
646       break;
647
648     case G_IR_NODE_OBJECT:
649       {
650         GIrNodeInterface *iface = (GIrNodeInterface *)node;
651
652         n = g_list_length (iface->interfaces);
653         size = sizeof(ObjectBlob);
654         if (iface->parent)
655           size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
656         if (iface->glib_type_struct)
657           size += ALIGN_VALUE (strlen (iface->glib_type_struct) + 1, 4);
658         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
659         size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
660         if (iface->gtype_init)
661           size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
662         size += 2 * (n + (n % 2));
663
664         for (l = iface->members; l; l = l->next)
665           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
666       }
667       break;
668
669     case G_IR_NODE_INTERFACE:
670       {
671         GIrNodeInterface *iface = (GIrNodeInterface *)node;
672
673         n = g_list_length (iface->prerequisites);
674         size = sizeof (InterfaceBlob);
675         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
676         size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
677         size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
678         size += 2 * (n + (n % 2));
679
680         for (l = iface->members; l; l = l->next)
681           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
682       }
683       break;
684
685     case G_IR_NODE_ENUM:
686     case G_IR_NODE_FLAGS:
687       {
688         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
689         
690         size = sizeof (EnumBlob);
691         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
692         if (enum_->gtype_name)
693           {
694             size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
695             size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
696           }
697
698         for (l = enum_->values; l; l = l->next)
699           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);  
700       }
701       break;
702
703     case G_IR_NODE_VALUE:
704       {
705         size = sizeof (ValueBlob);
706         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
707       }
708       break;
709
710     case G_IR_NODE_STRUCT:
711       {
712         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
713
714         size = sizeof (StructBlob);
715         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
716         if (struct_->gtype_name)
717           size += ALIGN_VALUE (strlen (struct_->gtype_name) + 1, 4);
718         if (struct_->gtype_init)
719           size += ALIGN_VALUE (strlen (struct_->gtype_init) + 1, 4);
720         for (l = struct_->members; l; l = l->next)
721           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
722       }
723       break;
724
725     case G_IR_NODE_BOXED:
726       {
727         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
728
729         size = sizeof (StructBlob);
730         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
731         if (boxed->gtype_name)
732           {
733             size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
734             size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
735           }
736         for (l = boxed->members; l; l = l->next)
737           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
738       }
739       break;
740
741     case G_IR_NODE_PROPERTY:
742       {
743         GIrNodeProperty *prop = (GIrNodeProperty *)node;
744         
745         size = sizeof (PropertyBlob);
746         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
747         size += g_ir_node_get_full_size_internal (node, (GIrNode *)prop->type); 
748       }
749       break;
750
751     case G_IR_NODE_SIGNAL:
752       {
753         GIrNodeSignal *signal = (GIrNodeSignal *)node;
754
755         size = sizeof (SignalBlob);
756         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
757         for (l = signal->parameters; l; l = l->next)
758           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
759         size += g_ir_node_get_full_size_internal (node, (GIrNode *)signal->result);
760       }
761       break;
762
763     case G_IR_NODE_VFUNC:
764       {
765         GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
766
767         size = sizeof (VFuncBlob);
768         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
769         for (l = vfunc->parameters; l; l = l->next)
770           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
771         size += g_ir_node_get_full_size_internal (node, (GIrNode *)vfunc->result);
772       }
773       break;
774
775     case G_IR_NODE_FIELD:
776       {
777         GIrNodeField *field = (GIrNodeField *)node;
778
779         size = sizeof (FieldBlob);
780         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
781         size += g_ir_node_get_full_size_internal (node, (GIrNode *)field->type);        
782       }
783       break;
784
785     case G_IR_NODE_CONSTANT:
786       {
787         GIrNodeConstant *constant = (GIrNodeConstant *)node;
788
789         size = sizeof (ConstantBlob);
790         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
791         /* FIXME non-string values */
792         size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
793         size += g_ir_node_get_full_size_internal (node, (GIrNode *)constant->type);     
794       }
795       break;
796
797     case G_IR_NODE_ERROR_DOMAIN:
798       {
799         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
800
801         size = sizeof (ErrorDomainBlob);
802         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
803         size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
804       }
805       break;
806
807     case G_IR_NODE_XREF:
808       {
809         GIrNodeXRef *xref = (GIrNodeXRef *)node;
810         
811         size = 0;
812         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
813         size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
814       }
815       break;
816
817     case G_IR_NODE_UNION:
818       {
819         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
820
821         size = sizeof (UnionBlob);
822         size += ALIGN_VALUE (strlen (node->name) + 1, 4);
823         if (union_->gtype_name)
824           size += ALIGN_VALUE (strlen (union_->gtype_name) + 1, 4);
825         if (union_->gtype_init)
826           size += ALIGN_VALUE (strlen (union_->gtype_init) + 1, 4);
827         for (l = union_->members; l; l = l->next)
828           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
829         for (l = union_->discriminators; l; l = l->next)
830           size += g_ir_node_get_full_size_internal (node, (GIrNode *)l->data);
831       }
832       break;
833
834     default: 
835       g_error ("Unknown type tag %d\n", node->type);
836       size = 0;
837     }
838
839   g_debug ("node %s%s%s%p type '%s' full size %d",
840            node->name ? "'" : "",
841            node->name ? node->name : "",
842            node->name ? "' " : "",
843            node, g_ir_node_type_to_string (node->type), size);
844
845   return size;
846 }
847
848 guint32
849 g_ir_node_get_full_size (GIrNode *node)
850 {
851   return g_ir_node_get_full_size_internal (NULL, node);
852 }
853
854 int
855 g_ir_node_cmp (GIrNode *node,
856                 GIrNode *other)
857 {
858   if (node->type < other->type)
859     return -1;
860   else if (node->type > other->type)
861     return 1;
862   else
863     return strcmp (node->name, other->name);
864 }
865
866 gboolean
867 g_ir_node_can_have_member (GIrNode    *node)
868 {
869   switch (node->type)
870     {
871     case G_IR_NODE_OBJECT:
872     case G_IR_NODE_INTERFACE:
873     case G_IR_NODE_BOXED:
874     case G_IR_NODE_STRUCT:
875     case G_IR_NODE_UNION:
876       return TRUE;
877     /* list others individually rather than with default: so that compiler
878      * warns if new node types are added without adding them to the switch
879      */
880     case G_IR_NODE_INVALID:
881     case G_IR_NODE_FUNCTION:
882     case G_IR_NODE_CALLBACK:
883     case G_IR_NODE_ENUM:
884     case G_IR_NODE_FLAGS:
885     case G_IR_NODE_CONSTANT:
886     case G_IR_NODE_ERROR_DOMAIN:
887     case G_IR_NODE_PARAM:
888     case G_IR_NODE_TYPE:
889     case G_IR_NODE_PROPERTY:
890     case G_IR_NODE_SIGNAL:
891     case G_IR_NODE_VALUE:
892     case G_IR_NODE_VFUNC:
893     case G_IR_NODE_FIELD:
894     case G_IR_NODE_XREF:
895       return FALSE;
896     };
897   return FALSE;
898 }
899
900 void
901 g_ir_node_add_member (GIrNode         *node,
902                       GIrNodeFunction *member)
903 {
904   g_return_if_fail (node != NULL);
905   g_return_if_fail (member != NULL);
906                     
907   switch (node->type)
908     {
909     case G_IR_NODE_OBJECT:
910     case G_IR_NODE_INTERFACE:
911       {
912         GIrNodeInterface *iface = (GIrNodeInterface *)node;
913         iface->members =
914           g_list_insert_sorted (iface->members, member,
915                                 (GCompareFunc) g_ir_node_cmp);
916         break;
917       }
918     case G_IR_NODE_BOXED:
919       {
920         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
921         boxed->members =
922           g_list_insert_sorted (boxed->members, member,
923                                 (GCompareFunc) g_ir_node_cmp);
924         break;
925       }
926     case G_IR_NODE_STRUCT:
927       {
928         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
929         struct_->members =
930           g_list_insert_sorted (struct_->members, member,
931                                 (GCompareFunc) g_ir_node_cmp);
932         break;
933       }
934     case G_IR_NODE_UNION:
935       {
936         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
937         union_->members =
938           g_list_insert_sorted (union_->members, member,
939                                 (GCompareFunc) g_ir_node_cmp);
940         break;
941       }
942     default:
943       g_error ("Cannot add a member to unknown type tag type %d\n",
944                node->type);
945       break;
946     }
947 }
948
949 const gchar *
950 g_ir_node_param_direction_string (GIrNodeParam * node)
951 {
952   if (node->out)
953     {
954       if (node->in)
955         return "in-out";
956       else
957         return "out";
958     }
959   return "in";
960 }
961
962 static gint64
963 parse_int_value (const gchar *str)
964 {
965   return strtoll (str, NULL, 0);
966 }
967
968 static guint64
969 parse_uint_value (const gchar *str)
970 {
971   return strtoull (str, NULL, 0);
972 }
973
974 static gdouble
975 parse_float_value (const gchar *str)
976 {
977   return strtod (str, NULL);
978 }
979
980 static gboolean
981 parse_boolean_value (const gchar *str)
982 {
983   if (strcmp (str, "TRUE") == 0)
984     return TRUE;
985   
986   if (strcmp (str, "FALSE") == 0)
987     return FALSE;
988
989   return parse_int_value (str) ? TRUE : FALSE;
990 }
991
992 static GIrNode *
993 find_entry_node (GIrModule   *module,
994                  GList       *modules,
995                  const gchar *name,
996                  guint16     *idx)
997
998 {
999   GList *l;
1000   gint i;
1001   gchar **names;
1002   gint n_names;
1003   GIrNode *result = NULL;
1004
1005   g_assert (name != NULL);
1006   g_assert (strlen (name) > 0);
1007   
1008   names = g_strsplit (name, ".", 0);
1009   n_names = g_strv_length (names);
1010   if (n_names > 2)
1011     g_error ("Too many name parts");
1012   
1013   for (l = module->entries, i = 1; l; l = l->next, i++)
1014     {
1015       GIrNode *node = (GIrNode *)l->data;
1016       
1017       if (n_names > 1)
1018         {
1019           if (node->type != G_IR_NODE_XREF)
1020             continue;
1021           
1022           if (((GIrNodeXRef *)node)->namespace == NULL ||
1023               strcmp (((GIrNodeXRef *)node)->namespace, names[0]) != 0)
1024             continue;
1025         }
1026          
1027       if (strcmp (node->name, names[n_names - 1]) == 0)
1028         {
1029           if (idx)
1030             *idx = i;
1031           
1032           result = node;
1033           goto out;
1034         }
1035     }
1036
1037   if (n_names > 1)
1038     {
1039       GIrNode *node = g_ir_node_new (G_IR_NODE_XREF);
1040
1041       ((GIrNodeXRef *)node)->namespace = g_strdup (names[0]);
1042       node->name = g_strdup (names[1]);
1043   
1044       module->entries = g_list_append (module->entries, node);
1045   
1046       if (idx)
1047         *idx = g_list_length (module->entries);
1048
1049       result = node;
1050
1051       g_debug ("Creating XREF: %s %s", names[0], names[1]);
1052
1053       goto out;
1054     }
1055
1056   g_warning ("Entry '%s' not found", name);
1057
1058  out:
1059
1060   g_strfreev (names);
1061
1062   return result;
1063 }
1064
1065 static guint16
1066 find_entry (GIrModule   *module,
1067             GList       *modules,
1068             const gchar *name)
1069 {
1070   guint16 idx = 0;
1071
1072   find_entry_node (module, modules, name, &idx);
1073
1074   return idx;
1075 }
1076
1077 static GIrNode *
1078 find_name_in_module (GIrModule   *module,
1079                      const gchar *name)
1080 {
1081   GList *l;
1082
1083   for (l = module->entries; l; l = l->next)
1084     {
1085       GIrNode *node = (GIrNode *)l->data;
1086
1087       if (strcmp (node->name, name) == 0)
1088         return node;
1089     }
1090
1091   return NULL;
1092 }
1093
1094 gboolean
1095 g_ir_find_node (GIrModule  *module,
1096                 GList      *modules,
1097                 const char *name,
1098                 GIrNode   **node_out,
1099                 GIrModule **module_out)
1100 {
1101   char **names = g_strsplit (name, ".", 0);
1102   gint n_names = g_strv_length (names);
1103   GIrNode *node = NULL;
1104   GList *l;
1105
1106   if (n_names == 0)
1107     {
1108       g_warning ("Name can't be empty");
1109       goto out;
1110     }
1111
1112   if (n_names > 2)
1113     {
1114       g_warning ("Too many name parts in '%s'", name);
1115       goto out;
1116     }
1117
1118   if (n_names == 1)
1119     {
1120       *module_out = module;
1121       node = find_name_in_module (module, names[0]);
1122     }
1123   else if (strcmp (names[0], module->name) == 0)
1124     {
1125       *module_out = module;
1126       node = find_name_in_module (module, names[1]);
1127     }
1128   else
1129     {
1130       for (l = module->include_modules; l; l = l->next)
1131         {
1132           GIrModule *m = l->data;
1133
1134           if (strcmp (names[0], m->name) == 0)
1135             {
1136               *module_out = m;
1137               node = find_name_in_module (m, names[1]);
1138               goto out;
1139             }
1140         }
1141
1142       for (l = modules; l; l = l->next)
1143         {
1144           GIrModule *m = l->data;
1145
1146           if (strcmp (names[0], m->name) == 0)
1147             {
1148               *module_out = m;
1149               node = find_name_in_module (m, names[1]);
1150               goto out;
1151             }
1152         }
1153     }
1154
1155  out:
1156   g_strfreev (names);
1157
1158   *node_out = node;
1159
1160   return node != NULL;
1161 }
1162
1163 static void
1164 serialize_type (GIrModule    *module, 
1165                 GList        *modules,
1166                 GIrNodeType  *node, 
1167                 GString      *str)
1168 {
1169   gint i;
1170   const gchar* basic[] = {
1171     "void", 
1172     "boolean", 
1173     "int8", 
1174     "uint8", 
1175     "int16", 
1176     "uint16", 
1177     "int32", 
1178     "uint32", 
1179     "int64", 
1180     "uint64", 
1181     "int",
1182     "uint",
1183     "long",
1184     "ulong",
1185     "ssize",
1186     "size",
1187     "float", 
1188     "double",
1189     "utf8", 
1190     "filename",
1191     "string",
1192     "sequence",
1193     "any"
1194   };
1195   
1196   if (node->tag < GI_TYPE_TAG_ARRAY)
1197     {
1198       g_string_append_printf (str, "%s%s", basic[node->tag],
1199                               node->is_pointer ? "*" : "");
1200     }
1201   else if (node->tag == GI_TYPE_TAG_ARRAY)
1202     {
1203       serialize_type (module, modules, node->parameter_type1, str);
1204       g_string_append (str, "[");
1205
1206       if (node->has_length)
1207         g_string_append_printf (str, "length=%d", node->length);
1208       else if (node->has_size)
1209         g_string_append_printf (str, "fixed-size=%d", node->size);
1210       
1211       if (node->zero_terminated)
1212         g_string_append_printf (str, "%szero-terminated=1", 
1213                                 node->has_length ? "," : "");
1214       
1215       g_string_append (str, "]");
1216     }
1217   else if (node->tag == GI_TYPE_TAG_INTERFACE)
1218     {
1219       GIrNode *iface;
1220       gchar *name;
1221
1222       iface = find_entry_node (module, modules, node->interface, NULL);
1223       if (iface)
1224         {
1225           if (iface->type == G_IR_NODE_XREF)
1226             g_string_append_printf (str, "%s.", ((GIrNodeXRef *)iface)->namespace);
1227           name = iface->name;
1228         }
1229       else
1230         {
1231           g_warning ("Interface for type reference %s not found", node->interface);
1232           name = node->interface;
1233         }
1234
1235       g_string_append_printf (str, "%s%s", name,
1236                               node->is_pointer ? "*" : "");
1237     }
1238   else if (node->tag == GI_TYPE_TAG_GLIST)
1239     {
1240       g_string_append (str, "GList");
1241       if (node->parameter_type1)
1242         {
1243           g_string_append (str, "<"); 
1244           serialize_type (module, modules, node->parameter_type1, str);
1245           g_string_append (str, ">"); 
1246         }
1247     }
1248   else if (node->tag == GI_TYPE_TAG_GSLIST)
1249     {
1250       g_string_append (str, "GSList");
1251       if (node->parameter_type1)
1252         {
1253           g_string_append (str, "<"); 
1254           serialize_type (module, modules, node->parameter_type1, str);
1255           g_string_append (str, ">"); 
1256         }
1257     }
1258   else if (node->tag == GI_TYPE_TAG_GHASH)
1259     {
1260       g_string_append (str, "GHashTable<");
1261       if (node->parameter_type1)
1262         {
1263           g_string_append (str, "<"); 
1264           serialize_type (module, modules, node->parameter_type1, str);
1265           g_string_append (str, ","); 
1266           serialize_type (module, modules, node->parameter_type2, str);
1267           g_string_append (str, ">"); 
1268         }
1269     }
1270   else if (node->tag == GI_TYPE_TAG_ERROR)
1271     {
1272       g_string_append (str, "GError");
1273       if (node->errors)
1274         {
1275           g_string_append (str, "<"); 
1276           for (i = 0; node->errors[i]; i++)
1277             {
1278               if (i > 0)
1279                 g_string_append (str, ",");
1280               g_string_append (str, node->errors[i]);
1281             }
1282           g_string_append (str, ">"); 
1283         }
1284     }
1285 }
1286
1287 static void
1288 g_ir_node_build_members (GList         **members,
1289                          GIrNodeTypeId   type,
1290                          guint16        *count,
1291                          GIrNode        *parent,
1292                          GIrTypelibBuild *build,
1293                          guint32        *offset,
1294                          guint32        *offset2)
1295 {
1296   GList *l = *members;
1297
1298   while (l)
1299     {
1300       GIrNode *member = (GIrNode *)l->data;
1301       GList *next = l->next;
1302
1303       if (member->type == type)
1304         {
1305           (*count)++;
1306           g_ir_node_build_typelib (member, parent, build, offset, offset2);
1307           *members = g_list_delete_link (*members, l);
1308         }
1309       l = next;
1310     }
1311 }
1312
1313 static void
1314 g_ir_node_check_unhandled_members (GList         **members,
1315                                    GIrNodeTypeId   container_type)
1316 {
1317 #if 0
1318   if (*members)
1319     {
1320       GList *l;
1321
1322       for (l = *members; l; l = l->next)
1323         {
1324           GIrNode *member = (GIrNode *)l->data;
1325           g_printerr ("Unhandled '%s' member '%s' type '%s'\n",
1326                       g_ir_node_type_to_string (container_type),
1327                       member->name,
1328                       g_ir_node_type_to_string (member->type));
1329         }
1330
1331       g_list_free (*members);
1332       *members = NULL;
1333
1334       g_error ("Unhandled members. Aborting.");
1335     }
1336 #else
1337   g_list_free (*members);
1338   *members = NULL;
1339 #endif
1340 }
1341
1342 void
1343 g_ir_node_build_typelib (GIrNode         *node,
1344                          GIrNode         *parent,
1345                          GIrTypelibBuild *build,
1346                          guint32         *offset,
1347                          guint32         *offset2)
1348 {
1349   GIrModule *module = build->module;
1350   GList *modules = build->modules;
1351   GHashTable *strings = build->strings;
1352   GHashTable *types = build->types;
1353   guchar *data = build->data;
1354   GList *l;
1355   guint32 old_offset = *offset;
1356   guint32 old_offset2 = *offset2;
1357
1358   g_assert (node != NULL);
1359
1360   g_debug ("build_typelib: %s%s(%s)",
1361            node->name ? node->name : "",
1362            node->name ? " " : "",
1363            g_ir_node_type_to_string (node->type));
1364
1365   g_ir_node_compute_offsets (node, module, modules);
1366
1367   switch (node->type)
1368     {
1369     case G_IR_NODE_TYPE:
1370       {
1371         GIrNodeType *type = (GIrNodeType *)node;
1372         SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
1373
1374         *offset += sizeof (SimpleTypeBlob);
1375         
1376         if (type->tag < GI_TYPE_TAG_ARRAY ||
1377             type->tag == GI_TYPE_TAG_UTF8 ||
1378             type->tag == GI_TYPE_TAG_FILENAME)
1379           { 
1380             blob->reserved = 0;
1381             blob->reserved2 = 0;
1382             blob->pointer = type->is_pointer;
1383             blob->reserved3 = 0;
1384             blob->tag = type->tag;
1385           }
1386         else 
1387           {
1388             GString *str;
1389             gchar *s;
1390             gpointer value;
1391             
1392             str = g_string_new (0);
1393             serialize_type (module, modules, type, str);
1394             s = g_string_free (str, FALSE);
1395             
1396             types_count += 1;
1397             value = g_hash_table_lookup (types, s);
1398             if (value)
1399               {
1400                 blob->offset = GPOINTER_TO_UINT (value);
1401                 g_free (s);
1402               }
1403             else
1404               {
1405                 unique_types_count += 1;
1406                 g_hash_table_insert (types, s, GUINT_TO_POINTER(*offset2));
1407                                      
1408                 blob->offset = *offset2;
1409                 switch (type->tag)
1410                   {
1411                   case GI_TYPE_TAG_ARRAY:
1412                     {
1413                       ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
1414                       guint32 pos;
1415                       
1416                       array->pointer = 1;
1417                       array->reserved = 0;
1418                       array->tag = type->tag;
1419                       array->zero_terminated = type->zero_terminated;
1420                       array->has_length = type->has_length;
1421                       array->has_size = type->has_size;
1422                       array->reserved2 = 0;
1423                       if (array->has_length)
1424                         array->length = type->length;
1425                       else if (array->has_size)
1426                         array->size  = type->size;
1427                       else
1428                         array->length = -1;
1429                       
1430                       pos = *offset2 + G_STRUCT_OFFSET (ArrayTypeBlob, type);
1431                       *offset2 += sizeof (ArrayTypeBlob);
1432                       
1433                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type1,
1434                                                node, build, &pos, offset2);
1435                     }
1436                     break;
1437                     
1438                   case GI_TYPE_TAG_INTERFACE:
1439                     {
1440                       InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
1441                       *offset2 += sizeof (InterfaceTypeBlob);
1442
1443                       iface->pointer = type->is_pointer;
1444                       iface->reserved = 0;
1445                       iface->tag = type->tag;
1446                       iface->reserved2 = 0;
1447                       iface->interface = find_entry (module, modules, type->interface);
1448
1449                     }
1450                     break;
1451                     
1452                   case GI_TYPE_TAG_GLIST:
1453                   case GI_TYPE_TAG_GSLIST:
1454                     {
1455                       ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1456                       guint32 pos;
1457                       
1458                       param->pointer = 1;
1459                       param->reserved = 0;
1460                       param->tag = type->tag;
1461                       param->reserved2 = 0;
1462                       param->n_types = 1;
1463                       
1464                       pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
1465                       *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob);
1466                       
1467                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
1468                                                node, build, &pos, offset2);
1469                     }
1470                     break;
1471                     
1472                   case GI_TYPE_TAG_GHASH:
1473                     {
1474                       ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1475                       guint32 pos;
1476                       
1477                       param->pointer = 1;
1478                       param->reserved = 0;
1479                       param->tag = type->tag;
1480                       param->reserved2 = 0;
1481                       param->n_types = 2;
1482                       
1483                       pos = *offset2 + G_STRUCT_OFFSET (ParamTypeBlob, type);
1484                       *offset2 += sizeof (ParamTypeBlob) + sizeof (SimpleTypeBlob)*2;
1485                       
1486                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type1, 
1487                                                node, build, &pos, offset2);
1488                       g_ir_node_build_typelib ((GIrNode *)type->parameter_type2, 
1489                                                node, build, &pos, offset2);
1490                     }
1491                     break;
1492                     
1493                   case GI_TYPE_TAG_ERROR:
1494                     {
1495                       ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
1496                       gint i;
1497                       
1498                       blob->pointer = 1;
1499                       blob->reserved = 0;
1500                       blob->tag = type->tag;
1501                       blob->reserved2 = 0;
1502                       if (type->errors) 
1503                         blob->n_domains = g_strv_length (type->errors);
1504                       else
1505                         blob->n_domains = 0;
1506                       
1507                       *offset2 = ALIGN_VALUE (*offset2 + G_STRUCT_OFFSET (ErrorTypeBlob, domains)
1508                                               + 2 * blob->n_domains, 4);
1509                       for (i = 0; i < blob->n_domains; i++)
1510                         blob->domains[i] = find_entry (module, modules, type->errors[i]);
1511                     }
1512                     break;
1513                     
1514                   default:
1515                     g_error ("Unknown type tag %d\n", type->tag);
1516                     break;
1517                   }
1518               }
1519           }
1520       }
1521       break;
1522
1523     case G_IR_NODE_FIELD:
1524       {
1525         GIrNodeField *field = (GIrNodeField *)node;
1526         FieldBlob *blob;
1527
1528         blob = (FieldBlob *)&data[*offset];
1529         /* We handle the size member specially below, so subtract it */
1530         *offset += sizeof (FieldBlob) - sizeof (SimpleTypeBlob);
1531
1532         blob->name = write_string (node->name, strings, data, offset2);
1533         blob->readable = field->readable;
1534         blob->writable = field->writable;
1535         blob->reserved = 0;
1536         blob->bits = 0;
1537         if (field->offset >= 0)
1538           blob->struct_offset = field->offset;
1539         else
1540           blob->struct_offset = 0xFFFF; /* mark as unknown */
1541
1542         g_ir_node_build_typelib ((GIrNode *)field->type, 
1543                                  node, build, offset, offset2);
1544       }
1545       break;
1546
1547     case G_IR_NODE_PROPERTY:
1548       {
1549         GIrNodeProperty *prop = (GIrNodeProperty *)node;
1550         PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1551         /* We handle the size member specially below, so subtract it */
1552         *offset += sizeof (PropertyBlob) - sizeof (SimpleTypeBlob);
1553
1554         blob->name = write_string (node->name, strings, data, offset2);
1555         blob->deprecated = prop->deprecated;
1556         blob->readable = prop->readable;
1557         blob->writable = prop->writable;
1558         blob->construct = prop->construct;
1559         blob->construct_only = prop->construct_only;
1560         blob->reserved = 0;
1561
1562         g_ir_node_build_typelib ((GIrNode *)prop->type, 
1563                                  node, build, offset, offset2);
1564       }
1565       break;
1566
1567     case G_IR_NODE_FUNCTION:
1568       {
1569         FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1570         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1571         GIrNodeFunction *function = (GIrNodeFunction *)node;
1572         guint32 signature;
1573         gint n;
1574
1575         signature = *offset2;
1576         n = g_list_length (function->parameters);
1577
1578         *offset += sizeof (FunctionBlob);
1579         *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1580
1581         blob->blob_type = BLOB_TYPE_FUNCTION;
1582         blob->deprecated = function->deprecated;
1583         blob->is_static = !function->is_method;
1584         blob->setter = function->is_setter;
1585         blob->getter = function->is_getter;
1586         blob->constructor = function->is_constructor;
1587         blob->wraps_vfunc = function->wraps_vfunc;
1588         blob->throws = function->throws;
1589         blob->index = 0;
1590         blob->name = write_string (node->name, strings, data, offset2);
1591         blob->symbol = write_string (function->symbol, strings, data, offset2);
1592         blob->signature = signature;
1593
1594         g_debug ("building function '%s'", function->symbol);
1595
1596         g_ir_node_build_typelib ((GIrNode *)function->result->type, 
1597                                  node, build, &signature, offset2);
1598
1599         blob2->may_return_null = function->result->allow_none;
1600         blob2->caller_owns_return_value = function->result->transfer;
1601         blob2->caller_owns_return_container = function->result->shallow_transfer;
1602         blob2->reserved = 0;
1603         blob2->n_arguments = n;
1604
1605         signature += 4;
1606         
1607         for (l = function->parameters; l; l = l->next)
1608           {
1609             GIrNode *param = (GIrNode *)l->data;
1610
1611             g_ir_node_build_typelib (param, node, build, &signature, offset2);
1612           }
1613
1614       }
1615       break;
1616
1617     case G_IR_NODE_CALLBACK:
1618       {
1619         CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1620         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1621         GIrNodeFunction *function = (GIrNodeFunction *)node;
1622         guint32 signature;
1623         gint n;
1624
1625         signature = *offset2;
1626         n = g_list_length (function->parameters);
1627
1628         *offset += sizeof (CallbackBlob);
1629         *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1630
1631         blob->blob_type = BLOB_TYPE_CALLBACK;
1632         blob->deprecated = function->deprecated;
1633         blob->reserved = 0;
1634         blob->name = write_string (node->name, strings, data, offset2);
1635         blob->signature = signature;
1636         
1637         g_ir_node_build_typelib ((GIrNode *)function->result->type, 
1638                                  node, build, &signature, offset2);
1639
1640         blob2->may_return_null = function->result->allow_none;
1641         blob2->caller_owns_return_value = function->result->transfer;
1642         blob2->caller_owns_return_container = function->result->shallow_transfer;
1643         blob2->reserved = 0;
1644         blob2->n_arguments = n;
1645
1646         signature += 4;
1647         
1648         for (l = function->parameters; l; l = l->next)
1649           {
1650             GIrNode *param = (GIrNode *)l->data;
1651
1652             g_ir_node_build_typelib (param, node, build, &signature, offset2);
1653           }
1654       }
1655       break;
1656
1657     case G_IR_NODE_SIGNAL:
1658       {
1659         SignalBlob *blob = (SignalBlob *)&data[*offset];
1660         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1661         GIrNodeSignal *signal = (GIrNodeSignal *)node;
1662         guint32 signature;
1663         gint n;
1664
1665         signature = *offset2;
1666         n = g_list_length (signal->parameters);
1667
1668         *offset += sizeof (SignalBlob);
1669         *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1670
1671         blob->deprecated = signal->deprecated;
1672         blob->run_first = signal->run_first;
1673         blob->run_last = signal->run_last;
1674         blob->run_cleanup = signal->run_cleanup;
1675         blob->no_recurse = signal->no_recurse;
1676         blob->detailed = signal->detailed;
1677         blob->action = signal->action;
1678         blob->no_hooks = signal->no_hooks;
1679         blob->has_class_closure = 0; /* FIXME */
1680         blob->true_stops_emit = 0; /* FIXME */
1681         blob->reserved = 0;
1682         blob->class_closure = 0; /* FIXME */
1683         blob->name = write_string (node->name, strings, data, offset2);
1684         blob->signature = signature;
1685         
1686         g_ir_node_build_typelib ((GIrNode *)signal->result->type, 
1687                                  node, build, &signature, offset2);
1688
1689         blob2->may_return_null = signal->result->allow_none;
1690         blob2->caller_owns_return_value = signal->result->transfer;
1691         blob2->caller_owns_return_container = signal->result->shallow_transfer;
1692         blob2->reserved = 0;
1693         blob2->n_arguments = n;
1694
1695         signature += 4;
1696         
1697         for (l = signal->parameters; l; l = l->next)
1698           {
1699             GIrNode *param = (GIrNode *)l->data;
1700
1701             g_ir_node_build_typelib (param, node, build, &signature, offset2);
1702           }
1703       }
1704       break;
1705
1706     case G_IR_NODE_VFUNC:
1707       {
1708         VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1709         SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1710         GIrNodeVFunc *vfunc = (GIrNodeVFunc *)node;
1711         guint32 signature;
1712         gint n;
1713
1714         signature = *offset2;
1715         n = g_list_length (vfunc->parameters);
1716
1717         *offset += sizeof (VFuncBlob);
1718         *offset2 += sizeof (SignatureBlob) + n * sizeof (ArgBlob);
1719
1720         blob->name = write_string (node->name, strings, data, offset2);
1721         blob->must_chain_up = 0; /* FIXME */
1722         blob->must_be_implemented = 0; /* FIXME */
1723         blob->must_not_be_implemented = 0; /* FIXME */
1724         blob->class_closure = 0; /* FIXME */
1725         blob->reserved = 0;
1726
1727         blob->struct_offset = vfunc->offset;
1728         blob->reserved2 = 0;
1729         blob->signature = signature;
1730         
1731         g_ir_node_build_typelib ((GIrNode *)vfunc->result->type, 
1732                                  node, build, &signature, offset2);
1733
1734         blob2->may_return_null = vfunc->result->allow_none;
1735         blob2->caller_owns_return_value = vfunc->result->transfer;
1736         blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1737         blob2->reserved = 0;
1738         blob2->n_arguments = n;
1739
1740         signature += 4;
1741         
1742         for (l = vfunc->parameters; l; l = l->next)
1743           {
1744             GIrNode *param = (GIrNode *)l->data;
1745
1746             g_ir_node_build_typelib (param, node, build, &signature, offset2);
1747           }
1748       }
1749       break;
1750
1751     case G_IR_NODE_PARAM:
1752       {
1753         ArgBlob *blob = (ArgBlob *)&data[*offset];
1754         GIrNodeParam *param = (GIrNodeParam *)node;
1755
1756         /* The offset for this one is smaller than the struct because
1757          * we recursively build the simple type inline here below.
1758          */
1759         *offset += sizeof (ArgBlob) - sizeof (SimpleTypeBlob);
1760
1761         blob->name = write_string (node->name, strings, data, offset2);
1762         blob->in = param->in;
1763         blob->out = param->out;
1764         blob->dipper = param->dipper;
1765         blob->allow_none = param->allow_none;
1766         blob->optional = param->optional;
1767         blob->transfer_ownership = param->transfer;
1768         blob->transfer_container_ownership = param->shallow_transfer;
1769         blob->return_value = param->retval;
1770         blob->scope = param->scope;
1771         blob->reserved = 0;
1772         blob->closure = param->closure;
1773         blob->destroy = param->destroy;
1774         
1775         g_ir_node_build_typelib ((GIrNode *)param->type, node, build, offset, offset2);
1776       }
1777       break;
1778
1779     case G_IR_NODE_STRUCT:
1780       {
1781         StructBlob *blob = (StructBlob *)&data[*offset];
1782         GIrNodeStruct *struct_ = (GIrNodeStruct *)node;
1783         GList *members;
1784         
1785         blob->blob_type = BLOB_TYPE_STRUCT;
1786         blob->deprecated = struct_->deprecated;
1787         blob->is_gtype_struct = struct_->is_gtype_struct;
1788         blob->reserved = 0;
1789         blob->name = write_string (node->name, strings, data, offset2);
1790         blob->alignment = struct_->alignment;
1791         blob->size = struct_->size;
1792
1793         if (struct_->gtype_name)
1794           {
1795             blob->unregistered = FALSE;
1796             blob->gtype_name = write_string (struct_->gtype_name, strings, data, offset2);
1797             blob->gtype_init = write_string (struct_->gtype_init, strings, data, offset2);
1798           }
1799         else
1800           {
1801             blob->unregistered = TRUE;
1802             blob->gtype_name = 0;
1803             blob->gtype_init = 0;
1804           }
1805
1806         blob->n_fields = 0;
1807         blob->n_methods = 0;
1808
1809         *offset += sizeof (StructBlob);
1810
1811         members = g_list_copy (struct_->members);
1812
1813         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1814                                  node, build, offset, offset2);
1815
1816         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
1817                                  node, build, offset, offset2);
1818
1819         g_ir_node_check_unhandled_members (&members, node->type);
1820
1821         g_assert (members == NULL);
1822       }
1823       break;
1824
1825     case G_IR_NODE_BOXED:
1826       {
1827         StructBlob *blob = (StructBlob *)&data[*offset];
1828         GIrNodeBoxed *boxed = (GIrNodeBoxed *)node;
1829         GList *members;
1830
1831         blob->blob_type = BLOB_TYPE_BOXED;
1832         blob->deprecated = boxed->deprecated;
1833         blob->unregistered = FALSE;
1834         blob->reserved = 0;
1835         blob->name = write_string (node->name, strings, data, offset2);
1836         blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
1837         blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
1838         blob->alignment = boxed->alignment;
1839         blob->size = boxed->size;
1840
1841         blob->n_fields = 0;
1842         blob->n_methods = 0;
1843
1844         *offset += sizeof (StructBlob);
1845
1846         members = g_list_copy (boxed->members);
1847
1848         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1849                                  node, build, offset, offset2);
1850
1851         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
1852                                  node, build, offset, offset2);
1853
1854         g_ir_node_check_unhandled_members (&members, node->type);
1855
1856         g_assert (members == NULL);
1857       }
1858       break;
1859
1860     case G_IR_NODE_UNION:
1861       {
1862         UnionBlob *blob = (UnionBlob *)&data[*offset];
1863         GIrNodeUnion *union_ = (GIrNodeUnion *)node;
1864         GList *members;
1865
1866         blob->blob_type = BLOB_TYPE_UNION;
1867         blob->deprecated = union_->deprecated;
1868         blob->reserved = 0;
1869         blob->name = write_string (node->name, strings, data, offset2);
1870         blob->alignment = union_->alignment;
1871         blob->size = union_->size;
1872         if (union_->gtype_name)
1873           {
1874             blob->unregistered = FALSE;
1875             blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2);
1876             blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2);
1877           }
1878         else
1879           {
1880             blob->unregistered = TRUE;
1881             blob->gtype_name = 0;
1882             blob->gtype_init = 0;
1883           }
1884
1885         blob->n_fields = 0;
1886         blob->n_functions = 0;
1887
1888         blob->discriminator_offset = union_->discriminator_offset;
1889
1890         /* We don't support Union discriminators right now. */
1891         /*
1892         if (union_->discriminator_type)
1893           {
1894             *offset += 28;
1895             blob->discriminated = TRUE;
1896             g_ir_node_build_typelib ((GIrNode *)union_->discriminator_type, 
1897                                      build, offset, offset2);
1898           }
1899         else
1900           {
1901         */
1902         *offset += sizeof (UnionBlob);
1903         blob->discriminated = FALSE;
1904         blob->discriminator_type.offset = 0;
1905         
1906         members = g_list_copy (union_->members);
1907
1908         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
1909                                  node, build, offset, offset2);
1910
1911         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_functions,
1912                                  node, build, offset, offset2);
1913
1914         g_ir_node_check_unhandled_members (&members, node->type);
1915
1916         g_assert (members == NULL);
1917
1918         if (union_->discriminator_type)
1919           {
1920             for (l = union_->discriminators; l; l = l->next)
1921               {
1922                 GIrNode *member = (GIrNode *)l->data;
1923                 
1924                 g_ir_node_build_typelib (member, node, build, offset, offset2);
1925               }
1926           }
1927       }
1928       break;
1929
1930     case G_IR_NODE_ENUM:
1931     case G_IR_NODE_FLAGS:
1932       {
1933         EnumBlob *blob = (EnumBlob *)&data[*offset];
1934         GIrNodeEnum *enum_ = (GIrNodeEnum *)node;
1935
1936         *offset += sizeof (EnumBlob); 
1937
1938         if (node->type == G_IR_NODE_ENUM)
1939           blob->blob_type = BLOB_TYPE_ENUM;
1940         else
1941           blob->blob_type = BLOB_TYPE_FLAGS;
1942           
1943         blob->deprecated = enum_->deprecated;
1944         blob->reserved = 0;
1945         blob->storage_type = enum_->storage_type;
1946         blob->name = write_string (node->name, strings, data, offset2);
1947         if (enum_->gtype_name)
1948           {
1949             blob->unregistered = FALSE;
1950             blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2);
1951             blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2);
1952           }
1953         else
1954           {
1955             blob->unregistered = TRUE;
1956             blob->gtype_name = 0;
1957             blob->gtype_init = 0;
1958           }
1959
1960         blob->n_values = 0;
1961         blob->reserved2 = 0;
1962
1963         for (l = enum_->values; l; l = l->next)
1964           {
1965             GIrNode *value = (GIrNode *)l->data;
1966
1967             blob->n_values++;
1968             g_ir_node_build_typelib (value, node, build, offset, offset2);
1969           }
1970       }
1971       break;
1972       
1973     case G_IR_NODE_OBJECT:
1974       {
1975         ObjectBlob *blob = (ObjectBlob *)&data[*offset];
1976         GIrNodeInterface *object = (GIrNodeInterface *)node;
1977         GList *members;
1978
1979         blob->blob_type = BLOB_TYPE_OBJECT;
1980         blob->abstract = object->abstract;
1981         blob->deprecated = object->deprecated;
1982         blob->reserved = 0;
1983         blob->name = write_string (node->name, strings, data, offset2);
1984         blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
1985         blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
1986         if (object->parent)
1987           blob->parent = find_entry (module, modules, object->parent);
1988         else
1989           blob->parent = 0;
1990         if (object->glib_type_struct)
1991           blob->gtype_struct = find_entry (module, modules, object->glib_type_struct);
1992         else
1993           blob->gtype_struct = 0;
1994
1995         blob->n_interfaces = 0;
1996         blob->n_fields = 0;
1997         blob->n_properties = 0;
1998         blob->n_methods = 0;
1999         blob->n_signals = 0;
2000         blob->n_vfuncs = 0;
2001         blob->n_constants = 0;
2002         
2003         *offset += sizeof(ObjectBlob);
2004         for (l = object->interfaces; l; l = l->next)
2005           {
2006             blob->n_interfaces++;
2007             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
2008             *offset += 2;
2009           }
2010         
2011         members = g_list_copy (object->members);
2012
2013         *offset = ALIGN_VALUE (*offset, 4);
2014         g_ir_node_build_members (&members, G_IR_NODE_FIELD, &blob->n_fields,
2015                                  node, build, offset, offset2);
2016
2017         *offset = ALIGN_VALUE (*offset, 4);
2018         g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
2019                                  node, build, offset, offset2);
2020
2021         *offset = ALIGN_VALUE (*offset, 4);
2022         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
2023                                  node, build, offset, offset2);
2024
2025         *offset = ALIGN_VALUE (*offset, 4);
2026         g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
2027                                  node, build, offset, offset2);
2028
2029         *offset = ALIGN_VALUE (*offset, 4);
2030         g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
2031                                  node, build, offset, offset2);
2032
2033         *offset = ALIGN_VALUE (*offset, 4);
2034         g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
2035                                  node, build, offset, offset2);
2036
2037         g_ir_node_check_unhandled_members (&members, node->type);
2038
2039         g_assert (members == NULL);
2040       }
2041       break;
2042
2043     case G_IR_NODE_INTERFACE:
2044       {
2045         InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
2046         GIrNodeInterface *iface = (GIrNodeInterface *)node;
2047         GList *members;
2048
2049         blob->blob_type = BLOB_TYPE_INTERFACE;
2050         blob->deprecated = iface->deprecated;
2051         blob->reserved = 0;
2052         blob->name = write_string (node->name, strings, data, offset2);
2053         blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
2054         blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
2055         if (iface->glib_type_struct)
2056           blob->gtype_struct = find_entry (module, modules, iface->glib_type_struct);
2057         else
2058           blob->gtype_struct = 0;
2059         blob->n_prerequisites = 0;
2060         blob->n_properties = 0;
2061         blob->n_methods = 0;
2062         blob->n_signals = 0;
2063         blob->n_vfuncs = 0;
2064         blob->n_constants = 0;
2065         
2066         *offset += sizeof (InterfaceBlob);
2067         for (l = iface->prerequisites; l; l = l->next)
2068           {
2069             blob->n_prerequisites++;
2070             *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
2071             *offset += 2;
2072           }
2073         
2074         members = g_list_copy (iface->members);
2075
2076         *offset = ALIGN_VALUE (*offset, 4);
2077         g_ir_node_build_members (&members, G_IR_NODE_PROPERTY, &blob->n_properties,
2078                                  node, build, offset, offset2);
2079
2080         *offset = ALIGN_VALUE (*offset, 4);
2081         g_ir_node_build_members (&members, G_IR_NODE_FUNCTION, &blob->n_methods,
2082                                  node, build, offset, offset2);
2083
2084         *offset = ALIGN_VALUE (*offset, 4);
2085         g_ir_node_build_members (&members, G_IR_NODE_SIGNAL, &blob->n_signals,
2086                                  node, build, offset, offset2);
2087
2088         *offset = ALIGN_VALUE (*offset, 4);
2089         g_ir_node_build_members (&members, G_IR_NODE_VFUNC, &blob->n_vfuncs,
2090                                  node, build, offset, offset2);
2091
2092         *offset = ALIGN_VALUE (*offset, 4);
2093         g_ir_node_build_members (&members, G_IR_NODE_CONSTANT, &blob->n_constants,
2094                                  node, build, offset, offset2);
2095
2096         g_ir_node_check_unhandled_members (&members, node->type);
2097
2098         g_assert (members == NULL);
2099       }
2100       break;
2101
2102
2103     case G_IR_NODE_VALUE:
2104       {
2105         GIrNodeValue *value = (GIrNodeValue *)node;
2106         ValueBlob *blob = (ValueBlob *)&data[*offset];
2107         *offset += sizeof (ValueBlob);
2108
2109         blob->deprecated = value->deprecated;
2110         blob->reserved = 0;
2111         blob->name = write_string (node->name, strings, data, offset2);
2112         blob->value = value->value;
2113       }
2114       break;
2115
2116     case G_IR_NODE_ERROR_DOMAIN:
2117       {
2118         GIrNodeErrorDomain *domain = (GIrNodeErrorDomain *)node;
2119         ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
2120         *offset += sizeof (ErrorDomainBlob);
2121
2122         blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
2123         blob->deprecated = domain->deprecated;
2124         blob->reserved = 0;
2125         blob->name = write_string (node->name, strings, data, offset2);
2126         blob->get_quark = write_string (domain->getquark, strings, data, offset2);
2127         blob->error_codes = find_entry (module, modules, domain->codes);
2128         blob->reserved2 = 0;
2129       }
2130       break;
2131
2132     case G_IR_NODE_CONSTANT:
2133       {
2134         GIrNodeConstant *constant = (GIrNodeConstant *)node;
2135         ConstantBlob *blob = (ConstantBlob *)&data[*offset];
2136         guint32 pos;
2137
2138         pos = *offset + G_STRUCT_OFFSET (ConstantBlob, type);
2139         *offset += sizeof (ConstantBlob);
2140
2141         blob->blob_type = BLOB_TYPE_CONSTANT;
2142         blob->deprecated = constant->deprecated;
2143         blob->reserved = 0;
2144         blob->name = write_string (node->name, strings, data, offset2);
2145
2146         blob->offset = *offset2;
2147         switch (constant->type->tag)
2148           {
2149           case GI_TYPE_TAG_BOOLEAN:
2150             blob->size = 4;
2151             *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
2152             break;
2153             case GI_TYPE_TAG_INT8:
2154             blob->size = 1;
2155               *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
2156             break;
2157           case GI_TYPE_TAG_UINT8:
2158             blob->size = 1;
2159             *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
2160             break;
2161           case GI_TYPE_TAG_INT16:
2162             blob->size = 2;
2163             *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
2164             break;
2165           case GI_TYPE_TAG_UINT16:
2166             blob->size = 2;
2167             *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
2168             break;
2169           case GI_TYPE_TAG_INT32:
2170             blob->size = 4;
2171             *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
2172             break;
2173           case GI_TYPE_TAG_UINT32:
2174             blob->size = 4;
2175             *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
2176             break;
2177           case GI_TYPE_TAG_INT64:
2178             blob->size = 8;
2179             *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
2180             break;
2181           case GI_TYPE_TAG_UINT64:
2182             blob->size = 8;
2183             *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
2184             break;
2185           case GI_TYPE_TAG_INT:
2186             blob->size = sizeof (gint);
2187             *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
2188             break;
2189           case GI_TYPE_TAG_UINT:
2190             blob->size = sizeof (guint);
2191             *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
2192             break;
2193           case GI_TYPE_TAG_SSIZE: /* FIXME */
2194           case GI_TYPE_TAG_LONG:
2195             blob->size = sizeof (glong);
2196             *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
2197             break;
2198           case GI_TYPE_TAG_SIZE: /* FIXME */
2199           case GI_TYPE_TAG_TIME_T: 
2200           case GI_TYPE_TAG_ULONG:
2201             blob->size = sizeof (gulong);
2202             *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
2203             break;
2204           case GI_TYPE_TAG_FLOAT:
2205             blob->size = sizeof (gfloat);
2206             *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
2207             break;
2208           case GI_TYPE_TAG_DOUBLE:
2209             blob->size = sizeof (gdouble);
2210             *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
2211             break;
2212           case GI_TYPE_TAG_UTF8:
2213           case GI_TYPE_TAG_FILENAME:
2214             blob->size = strlen (constant->value) + 1;
2215             memcpy (&data[blob->offset], constant->value, blob->size);
2216             break;
2217           }
2218         *offset2 += ALIGN_VALUE (blob->size, 4);
2219         
2220         g_ir_node_build_typelib ((GIrNode *)constant->type, node, build, &pos, offset2);
2221       }
2222       break;
2223     default:
2224       g_assert_not_reached ();
2225     }
2226   
2227   g_debug ("node %s%s%s%p type '%s', offset %d -> %d, offset2 %d -> %d",
2228            node->name ? "'" : "",
2229            node->name ? node->name : "",
2230            node->name ? "' " : "",
2231            node, g_ir_node_type_to_string (node->type),
2232            old_offset, *offset, old_offset2, *offset2);
2233
2234   if (*offset2 - old_offset2 + *offset - old_offset > g_ir_node_get_full_size (node))
2235     g_error ("exceeding space reservation !!");
2236 }
2237
2238 /* if str is already in the pool, return previous location, otherwise write str
2239  * to the typelib at offset, put it in the pool and update offset. If the 
2240  * typelib is not large enough to hold the string, reallocate it.
2241  */
2242 guint32 
2243 write_string (const gchar *str,
2244               GHashTable  *strings, 
2245               guchar      *data,
2246               guint32     *offset)
2247 {
2248   gpointer value;
2249   guint32 start;
2250
2251   string_count += 1;
2252   string_size += strlen (str);
2253
2254   value = g_hash_table_lookup (strings, str);
2255   
2256   if (value)
2257     return GPOINTER_TO_UINT (value);
2258
2259   unique_string_count += 1;
2260   unique_string_size += strlen (str);
2261
2262   g_hash_table_insert (strings, (gpointer)str, GUINT_TO_POINTER (*offset));
2263
2264   start = *offset;
2265   *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
2266
2267   strcpy ((gchar*)&data[start], str);
2268   
2269   return start;
2270 }
2271