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