Fix error handling in try statements nested across method boundaries
[vala-lang.git] / gobject-introspection / gidlnode.c
blob623836641a8a6a04e118e094dd32410d771c9b79
1 /* GObject introspection: Metadata creation
3 * Copyright (C) 2005 Matthias Clasen
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.
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.
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.
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
25 #include "gidlmodule.h"
26 #include "gidlnode.h"
27 #include "gmetadata.h"
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;
36 void
37 init_stats (void)
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;
47 void
48 dump_stats (void)
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);
55 #define ALIGN_VALUE(this, boundary) \
56 (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
59 GIdlNode *
60 g_idl_node_new (GIdlNodeTypeId type)
62 GIdlNode *node = NULL;
64 switch (type)
66 case G_IDL_NODE_FUNCTION:
67 case G_IDL_NODE_CALLBACK:
68 node = g_malloc0 (sizeof (GIdlNodeFunction));
69 break;
71 case G_IDL_NODE_PARAM:
72 node = g_malloc0 (sizeof (GIdlNodeParam));
73 break;
75 case G_IDL_NODE_TYPE:
76 node = g_malloc0 (sizeof (GIdlNodeType));
77 break;
79 case G_IDL_NODE_OBJECT:
80 case G_IDL_NODE_INTERFACE:
81 node = g_malloc0 (sizeof (GIdlNodeInterface));
82 break;
84 case G_IDL_NODE_SIGNAL:
85 node = g_malloc0 (sizeof (GIdlNodeSignal));
86 break;
88 case G_IDL_NODE_PROPERTY:
89 node = g_malloc0 (sizeof (GIdlNodeProperty));
90 break;
92 case G_IDL_NODE_VFUNC:
93 node = g_malloc0 (sizeof (GIdlNodeFunction));
94 break;
96 case G_IDL_NODE_FIELD:
97 node = g_malloc0 (sizeof (GIdlNodeField));
98 break;
100 case G_IDL_NODE_ENUM:
101 case G_IDL_NODE_FLAGS:
102 node = g_malloc0 (sizeof (GIdlNodeEnum));
103 break;
105 case G_IDL_NODE_BOXED:
106 node = g_malloc0 (sizeof (GIdlNodeBoxed));
107 break;
109 case G_IDL_NODE_STRUCT:
110 node = g_malloc0 (sizeof (GIdlNodeStruct));
111 break;
113 case G_IDL_NODE_VALUE:
114 node = g_malloc0 (sizeof (GIdlNodeValue));
115 break;
117 case G_IDL_NODE_CONSTANT:
118 node = g_malloc0 (sizeof (GIdlNodeConstant));
119 break;
121 case G_IDL_NODE_ERROR_DOMAIN:
122 node = g_malloc0 (sizeof (GIdlNodeErrorDomain));
123 break;
125 case G_IDL_NODE_XREF:
126 node = g_malloc0 (sizeof (GIdlNodeXRef));
127 break;
129 case G_IDL_NODE_UNION:
130 node = g_malloc0 (sizeof (GIdlNodeUnion));
131 break;
133 default:
134 g_error ("Unhandled node type %d\n", type);
135 break;
138 node->type = type;
140 return node;
143 void
144 g_idl_node_free (GIdlNode *node)
146 GList *l;
148 if (node == NULL)
149 return;
151 switch (node->type)
153 case G_IDL_NODE_FUNCTION:
154 case G_IDL_NODE_CALLBACK:
156 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
158 g_free (node->name);
159 g_free (function->symbol);
160 g_idl_node_free ((GIdlNode *)function->result);
161 for (l = function->parameters; l; l = l->next)
162 g_idl_node_free ((GIdlNode *)l->data);
163 g_list_free (function->parameters);
165 break;
167 case G_IDL_NODE_TYPE:
169 GIdlNodeType *type = (GIdlNodeType *)node;
171 g_free (node->name);
172 g_idl_node_free ((GIdlNode *)type->parameter_type1);
173 g_idl_node_free ((GIdlNode *)type->parameter_type2);
175 g_free (type->interface);
176 g_strfreev (type->errors);
179 break;
181 case G_IDL_NODE_PARAM:
183 GIdlNodeParam *param = (GIdlNodeParam *)node;
185 g_free (node->name);
186 g_idl_node_free ((GIdlNode *)param->type);
188 break;
190 case G_IDL_NODE_PROPERTY:
192 GIdlNodeProperty *property = (GIdlNodeProperty *)node;
194 g_free (node->name);
195 g_idl_node_free ((GIdlNode *)property->type);
197 break;
199 case G_IDL_NODE_SIGNAL:
201 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
203 g_free (node->name);
204 for (l = signal->parameters; l; l = l->next)
205 g_idl_node_free ((GIdlNode *)l->data);
206 g_list_free (signal->parameters);
207 g_idl_node_free ((GIdlNode *)signal->result);
209 break;
211 case G_IDL_NODE_VFUNC:
213 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
215 g_free (node->name);
216 for (l = vfunc->parameters; l; l = l->next)
217 g_idl_node_free ((GIdlNode *)l->data);
218 g_list_free (vfunc->parameters);
219 g_idl_node_free ((GIdlNode *)vfunc->result);
221 break;
223 case G_IDL_NODE_FIELD:
225 GIdlNodeField *field = (GIdlNodeField *)node;
227 g_free (node->name);
228 g_idl_node_free ((GIdlNode *)field->type);
230 break;
232 case G_IDL_NODE_OBJECT:
233 case G_IDL_NODE_INTERFACE:
235 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
237 g_free (node->name);
238 g_free (iface->gtype_name);
239 g_free (iface->gtype_init);
241 g_free (iface->parent);
243 for (l = iface->interfaces; l; l = l->next)
244 g_free ((GIdlNode *)l->data);
245 g_list_free (iface->interfaces);
247 for (l = iface->members; l; l = l->next)
248 g_idl_node_free ((GIdlNode *)l->data);
249 g_list_free (iface->members);
252 break;
254 case G_IDL_NODE_VALUE:
256 g_free (node->name);
258 break;
260 case G_IDL_NODE_ENUM:
261 case G_IDL_NODE_FLAGS:
263 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
265 g_free (node->name);
266 g_free (enum_->gtype_name);
267 g_free (enum_->gtype_init);
269 for (l = enum_->values; l; l = l->next)
270 g_idl_node_free ((GIdlNode *)l->data);
271 g_list_free (enum_->values);
273 break;
275 case G_IDL_NODE_BOXED:
277 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
279 g_free (node->name);
280 g_free (boxed->gtype_name);
281 g_free (boxed->gtype_init);
283 for (l = boxed->members; l; l = l->next)
284 g_idl_node_free ((GIdlNode *)l->data);
285 g_list_free (boxed->members);
287 break;
289 case G_IDL_NODE_STRUCT:
291 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
293 g_free (node->name);
294 for (l = struct_->members; l; l = l->next)
295 g_idl_node_free ((GIdlNode *)l->data);
296 g_list_free (struct_->members);
298 break;
300 case G_IDL_NODE_CONSTANT:
302 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
304 g_free (node->name);
305 g_free (constant->value);
306 g_idl_node_free ((GIdlNode *)constant->type);
308 break;
310 case G_IDL_NODE_ERROR_DOMAIN:
312 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
314 g_free (node->name);
315 g_free (domain->getquark);
316 g_free (domain->codes);
318 break;
320 case G_IDL_NODE_XREF:
322 GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
324 g_free (node->name);
325 g_free (xref->namespace);
327 break;
329 case G_IDL_NODE_UNION:
331 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
333 g_free (node->name);
334 g_free (union_->gtype_name);
335 g_free (union_->gtype_init);
337 g_idl_node_free ((GIdlNode *)union_->discriminator_type);
338 for (l = union_->members; l; l = l->next)
339 g_idl_node_free ((GIdlNode *)l->data);
340 for (l = union_->discriminators; l; l = l->next)
341 g_idl_node_free ((GIdlNode *)l->data);
343 break;
345 default:
346 g_error ("Unhandled node type %d\n", node->type);
347 break;
350 g_free (node);
353 /* returns the fixed size of the blob */
354 guint32
355 g_idl_node_get_size (GIdlNode *node)
357 GList *l;
358 gint size, n;
360 switch (node->type)
362 case G_IDL_NODE_CALLBACK:
363 size = 12;
364 break;
366 case G_IDL_NODE_FUNCTION:
367 size = 16;
368 break;
370 case G_IDL_NODE_PARAM:
371 size = 12;
372 break;
374 case G_IDL_NODE_TYPE:
375 size = 4;
376 break;
378 case G_IDL_NODE_OBJECT:
380 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
382 n = g_list_length (iface->interfaces);
383 size = 32 + 2 * (n + (n % 2));
385 for (l = iface->members; l; l = l->next)
386 size += g_idl_node_get_size ((GIdlNode *)l->data);
388 break;
390 case G_IDL_NODE_INTERFACE:
392 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
394 n = g_list_length (iface->prerequisites);
395 size = 28 + 2 * (n + (n % 2));
397 for (l = iface->members; l; l = l->next)
398 size += g_idl_node_get_size ((GIdlNode *)l->data);
400 break;
402 case G_IDL_NODE_ENUM:
403 case G_IDL_NODE_FLAGS:
405 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
407 size = 20;
408 for (l = enum_->values; l; l = l->next)
409 size += g_idl_node_get_size ((GIdlNode *)l->data);
411 break;
413 case G_IDL_NODE_VALUE:
414 size = 12;
415 break;
417 case G_IDL_NODE_STRUCT:
419 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
421 size = 20;
422 for (l = struct_->members; l; l = l->next)
423 size += g_idl_node_get_size ((GIdlNode *)l->data);
425 break;
427 case G_IDL_NODE_BOXED:
429 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
431 size = 20;
432 for (l = boxed->members; l; l = l->next)
433 size += g_idl_node_get_size ((GIdlNode *)l->data);
435 break;
437 case G_IDL_NODE_PROPERTY:
438 size = 12;
439 break;
441 case G_IDL_NODE_SIGNAL:
442 size = 12;
443 break;
445 case G_IDL_NODE_VFUNC:
446 size = 16;
447 break;
449 case G_IDL_NODE_FIELD:
450 size = 12;
451 break;
453 case G_IDL_NODE_CONSTANT:
454 size = 20;
455 break;
457 case G_IDL_NODE_ERROR_DOMAIN:
458 size = 16;
459 break;
461 case G_IDL_NODE_XREF:
462 size = 0;
463 break;
465 case G_IDL_NODE_UNION:
467 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
469 size = 28;
470 for (l = union_->members; l; l = l->next)
471 size += g_idl_node_get_size ((GIdlNode *)l->data);
472 for (l = union_->discriminators; l; l = l->next)
473 size += g_idl_node_get_size ((GIdlNode *)l->data);
475 break;
477 default:
478 g_error ("Unhandled node type %d\n", node->type);
479 size = 0;
482 g_debug ("node %p type %d size %d", node, node->type, size);
484 return size;
487 /* returns the full size of the blob including variable-size parts */
488 guint32
489 g_idl_node_get_full_size (GIdlNode *node)
491 GList *l;
492 gint size, n;
494 g_assert (node != NULL);
496 switch (node->type)
498 case G_IDL_NODE_CALLBACK:
500 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
501 size = 12;
502 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
503 for (l = function->parameters; l; l = l->next)
504 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
505 size += g_idl_node_get_full_size ((GIdlNode *)function->result);
507 break;
509 case G_IDL_NODE_FUNCTION:
511 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
512 size = 24;
513 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
514 size += ALIGN_VALUE (strlen (function->symbol) + 1, 4);
515 for (l = function->parameters; l; l = l->next)
516 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
517 size += g_idl_node_get_full_size ((GIdlNode *)function->result);
519 break;
521 case G_IDL_NODE_PARAM:
523 GIdlNodeParam *param = (GIdlNodeParam *)node;
525 size = 12;
526 if (node->name)
527 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
528 size += g_idl_node_get_full_size ((GIdlNode *)param->type);
530 break;
532 case G_IDL_NODE_TYPE:
534 GIdlNodeType *type = (GIdlNodeType *)node;
535 if (type->tag < TYPE_TAG_ARRAY)
536 size = 4;
537 else
539 switch (type->tag)
541 case TYPE_TAG_ARRAY:
542 size = 4 + 4;
543 if (type->parameter_type1)
544 size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
545 break;
546 case TYPE_TAG_INTERFACE:
547 size = 4 + 4;
548 break;
549 case TYPE_TAG_LIST:
550 case TYPE_TAG_SLIST:
551 size = 4 + 4;
552 if (type->parameter_type1)
553 size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
554 break;
555 case TYPE_TAG_HASH:
556 size = 4 + 4 + 4;
557 if (type->parameter_type1)
558 size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
559 if (type->parameter_type2)
560 size += g_idl_node_get_full_size ((GIdlNode *)type->parameter_type2);
561 break;
562 case TYPE_TAG_ERROR:
564 gint n;
566 if (type->errors)
567 n = g_strv_length (type->errors);
568 else
569 n = 0;
571 size = 4 + 4 + 2 * (n + n % 2);
573 break;
574 default:
575 g_error ("Unknown type tag %d\n", type->tag);
576 break;
580 break;
582 case G_IDL_NODE_OBJECT:
584 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
586 n = g_list_length (iface->interfaces);
587 size = 32;
588 if (iface->parent)
589 size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
590 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
591 size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
592 size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
593 size += 2 * (n + (n % 2));
595 for (l = iface->members; l; l = l->next)
596 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
598 break;
600 case G_IDL_NODE_INTERFACE:
602 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
604 n = g_list_length (iface->prerequisites);
605 size = 28;
606 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
607 size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
608 size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
609 size += 2 * (n + (n % 2));
611 for (l = iface->members; l; l = l->next)
612 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
614 break;
616 case G_IDL_NODE_ENUM:
617 case G_IDL_NODE_FLAGS:
619 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
621 size = 20;
622 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
623 if (enum_->gtype_name)
625 size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
626 size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
629 for (l = enum_->values; l; l = l->next)
630 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
632 break;
634 case G_IDL_NODE_VALUE:
636 size = 12;
637 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
639 break;
641 case G_IDL_NODE_STRUCT:
643 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
645 size = 20;
646 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
647 for (l = struct_->members; l; l = l->next)
648 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
650 break;
652 case G_IDL_NODE_BOXED:
654 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
656 size = 20;
657 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
658 if (boxed->gtype_name)
660 size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
661 size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
663 for (l = boxed->members; l; l = l->next)
664 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
666 break;
668 case G_IDL_NODE_PROPERTY:
670 GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
672 size = 12;
673 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
674 size += g_idl_node_get_full_size ((GIdlNode *)prop->type);
676 break;
678 case G_IDL_NODE_SIGNAL:
680 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
682 size = 12;
683 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
684 for (l = signal->parameters; l; l = l->next)
685 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
686 size += g_idl_node_get_full_size ((GIdlNode *)signal->result);
688 break;
690 case G_IDL_NODE_VFUNC:
692 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
694 size = 16;
695 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
696 for (l = vfunc->parameters; l; l = l->next)
697 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
698 size += g_idl_node_get_full_size ((GIdlNode *)vfunc->result);
700 break;
702 case G_IDL_NODE_FIELD:
704 GIdlNodeField *field = (GIdlNodeField *)node;
706 size = 12;
707 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
708 size += g_idl_node_get_full_size ((GIdlNode *)field->type);
710 break;
712 case G_IDL_NODE_CONSTANT:
714 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
716 size = 20;
717 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
718 /* FIXME non-string values */
719 size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
720 size += g_idl_node_get_full_size ((GIdlNode *)constant->type);
722 break;
724 case G_IDL_NODE_ERROR_DOMAIN:
726 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
728 size = 16;
729 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
730 size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
732 break;
734 case G_IDL_NODE_XREF:
736 GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
738 size = 0;
739 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
740 size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
742 break;
744 case G_IDL_NODE_UNION:
746 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
748 size = 28;
749 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
750 for (l = union_->members; l; l = l->next)
751 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
752 for (l = union_->discriminators; l; l = l->next)
753 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
755 break;
757 default:
758 g_error ("Unknown type tag %d\n", node->type);
759 size = 0;
762 g_debug ("node %p type %d full size %d", node, node->type, size);
764 return size;
768 g_idl_node_cmp (GIdlNode *node,
769 GIdlNode *other)
771 if (node->type < other->type)
772 return -1;
773 else if (node->type > other->type)
774 return 1;
775 else
776 return strcmp (node->name, other->name);
779 gboolean
780 g_idl_node_can_have_member (GIdlNode *node)
782 switch (node->type)
784 case G_IDL_NODE_OBJECT:
785 case G_IDL_NODE_INTERFACE:
786 case G_IDL_NODE_BOXED:
787 case G_IDL_NODE_STRUCT:
788 case G_IDL_NODE_UNION:
789 return TRUE;
791 return FALSE;
794 void
795 g_idl_node_add_member (GIdlNode *node,
796 GIdlNodeFunction *member)
798 g_return_if_fail (node != NULL);
799 g_return_if_fail (member != NULL);
801 switch (node->type)
803 case G_IDL_NODE_OBJECT:
804 case G_IDL_NODE_INTERFACE:
806 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
807 iface->members =
808 g_list_insert_sorted (iface->members, member,
809 (GCompareFunc) g_idl_node_cmp);
810 break;
812 case G_IDL_NODE_BOXED:
814 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
815 boxed->members =
816 g_list_insert_sorted (boxed->members, member,
817 (GCompareFunc) g_idl_node_cmp);
818 break;
820 case G_IDL_NODE_STRUCT:
822 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
823 struct_->members =
824 g_list_insert_sorted (struct_->members, member,
825 (GCompareFunc) g_idl_node_cmp);
826 break;
828 case G_IDL_NODE_UNION:
830 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
831 union_->members =
832 g_list_insert_sorted (union_->members, member,
833 (GCompareFunc) g_idl_node_cmp);
834 break;
836 default:
837 g_error ("Cannot add a member to unknown type tag type %d\n",
838 node->type);
839 break;
843 static gint64
844 parse_int_value (const gchar *str)
846 return strtoll (str, NULL, 0);
849 static guint64
850 parse_uint_value (const gchar *str)
852 return strtoull (str, NULL, 0);
855 static gdouble
856 parse_float_value (const gchar *str)
858 return strtod (str, NULL);
861 static gboolean
862 parse_boolean_value (const gchar *str)
864 if (strcmp (str, "TRUE") == 0)
865 return TRUE;
867 if (strcmp (str, "FALSE") == 0)
868 return FALSE;
870 return parse_int_value (str) ? TRUE : FALSE;
873 static GIdlNode *
874 find_entry_node (GIdlModule *module,
875 GList *modules,
876 const gchar *name,
877 guint16 *idx)
880 GList *l;
881 gint i;
882 gchar **names;
883 gint n_names;
884 GIdlNode *result = NULL;
886 names = g_strsplit (name, ".", 0);
887 n_names = g_strv_length (names);
888 if (n_names > 2)
889 g_error ("Too many name parts");
891 for (l = module->entries, i = 1; l; l = l->next, i++)
893 GIdlNode *node = (GIdlNode *)l->data;
895 if (n_names > 1)
897 if (node->type != G_IDL_NODE_XREF)
898 continue;
900 if (((GIdlNodeXRef *)node)->namespace == NULL ||
901 strcmp (((GIdlNodeXRef *)node)->namespace, names[0]) != 0)
902 continue;
905 if (strcmp (node->name, names[n_names - 1]) == 0)
907 if (idx)
908 *idx = i;
910 result = node;
911 goto out;
915 if (n_names > 1)
917 GIdlNode *node = g_idl_node_new (G_IDL_NODE_XREF);
919 ((GIdlNodeXRef *)node)->namespace = g_strdup (names[0]);
920 node->name = g_strdup (names[1]);
922 module->entries = g_list_append (module->entries, node);
924 if (idx)
925 *idx = g_list_length (module->entries);
927 result = node;
929 goto out;
932 g_warning ("Entry %s not found", name);
934 out:
936 g_strfreev (names);
938 return result;
941 static guint16
942 find_entry (GIdlModule *module,
943 GList *modules,
944 const gchar *name)
946 guint16 idx = 0;
948 find_entry_node (module, modules, name, &idx);
950 return idx;
953 static void
954 serialize_type (GIdlModule *module,
955 GList *modules,
956 GIdlNodeType *node,
957 GString *str)
959 gint i;
960 const gchar* basic[] = {
961 "void",
962 "gboolean",
963 "gint8",
964 "guint8",
965 "gint16",
966 "guint16",
967 "gint32",
968 "guint32",
969 "gint64",
970 "guint64",
971 "gint",
972 "guint",
973 "glong",
974 "gulong",
975 "gssize",
976 "gsize",
977 "gfloat",
978 "gdouble",
979 "utf8",
980 "filename"
983 if (node->tag < 20)
985 g_string_append_printf (str, "%s%s",
986 basic[node->tag], node->is_pointer ? "*" : "");
988 else if (node->tag == 20)
990 serialize_type (module, modules, node->parameter_type1, str);
991 g_string_append (str, "[");
993 if (node->has_length)
994 g_string_append_printf (str, "length=%d", node->length);
996 if (node->zero_terminated)
997 g_string_append_printf (str, "%szero-terminated=1",
998 node->has_length ? "," : "");
1000 g_string_append (str, "]");
1002 else if (node->tag == 21)
1004 GIdlNode *iface;
1005 gchar *name;
1007 iface = find_entry_node (module, modules, node->interface, NULL);
1008 if (iface)
1009 name = iface->name;
1010 else
1012 g_warning ("Interface for type reference %s not found", node->interface);
1013 name = node->interface;
1016 g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : "");
1018 else if (node->tag == 22)
1020 g_string_append (str, "GList");
1021 if (node->parameter_type1)
1023 g_string_append (str, "<");
1024 serialize_type (module, modules, node->parameter_type1, str);
1025 g_string_append (str, ">");
1028 else if (node->tag == 23)
1030 g_string_append (str, "GSList");
1031 if (node->parameter_type1)
1033 g_string_append (str, "<");
1034 serialize_type (module, modules, node->parameter_type1, str);
1035 g_string_append (str, ">");
1038 else if (node->tag == 24)
1040 g_string_append (str, "GHashTable<");
1041 if (node->parameter_type1)
1043 g_string_append (str, "<");
1044 serialize_type (module, modules, node->parameter_type1, str);
1045 g_string_append (str, ",");
1046 serialize_type (module, modules, node->parameter_type2, str);
1047 g_string_append (str, ">");
1050 else if (node->tag == 25)
1052 g_string_append (str, "GError");
1053 if (node->errors)
1055 g_string_append (str, "<");
1056 for (i = 0; node->errors[i]; i++)
1058 if (i > 0)
1059 g_string_append (str, ",");
1060 g_string_append (str, node->errors[i]);
1062 g_string_append (str, ">");
1067 void
1068 g_idl_node_build_metadata (GIdlNode *node,
1069 GIdlModule *module,
1070 GList *modules,
1071 GHashTable *strings,
1072 GHashTable *types,
1073 guchar *data,
1074 guint32 *offset,
1075 guint32 *offset2)
1077 GList *l;
1078 guint32 old_offset = *offset;
1079 guint32 old_offset2 = *offset2;
1081 switch (node->type)
1083 case G_IDL_NODE_TYPE:
1085 GIdlNodeType *type = (GIdlNodeType *)node;
1086 SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
1088 *offset += 4;
1090 if (type->tag < TYPE_TAG_ARRAY)
1092 blob->reserved = 0;
1093 blob->reserved2 = 0;
1094 blob->pointer = type->is_pointer;
1095 blob->reserved3 = 0;
1096 blob->tag = type->tag;
1098 else
1100 GString *str;
1101 gchar *s;
1102 gpointer value;
1104 str = g_string_new (0);
1105 serialize_type (module, modules, type, str);
1106 s = g_string_free (str, FALSE);
1108 types_count += 1;
1109 value = g_hash_table_lookup (types, s);
1110 if (value)
1112 blob->offset = GPOINTER_TO_INT (value);
1113 g_free (s);
1115 else
1117 unique_types_count += 1;
1118 g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
1120 blob->offset = *offset2;
1121 switch (type->tag)
1123 case TYPE_TAG_ARRAY:
1125 ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
1126 guint32 pos;
1128 array->pointer = 1;
1129 array->reserved = 0;
1130 array->tag = type->tag;
1131 array->zero_terminated = type->zero_terminated;
1132 array->has_length = type->has_length;
1133 array->reserved2 = 0;
1134 array->length = type->length;
1136 pos = *offset2 + 4;
1137 *offset2 += 8;
1139 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1140 module, modules, strings, types,
1141 data, &pos, offset2);
1143 break;
1145 case TYPE_TAG_INTERFACE:
1147 InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
1148 *offset2 += 4;
1150 iface->pointer = type->is_pointer;
1151 iface->reserved = 0;
1152 iface->tag = type->tag;
1153 iface->reserved2 = 0;
1154 iface->interface = find_entry (module, modules, type->interface);
1157 break;
1159 case TYPE_TAG_LIST:
1160 case TYPE_TAG_SLIST:
1162 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1163 guint32 pos;
1165 param->pointer = 1;
1166 param->reserved = 0;
1167 param->tag = type->tag;
1168 param->reserved2 = 0;
1169 param->n_types = 1;
1171 pos = *offset2 + 4;
1172 *offset2 += 8;
1174 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1175 module, modules, strings, types,
1176 data, &pos, offset2);
1178 break;
1180 case TYPE_TAG_HASH:
1182 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1183 guint32 pos;
1185 param->pointer = 1;
1186 param->reserved = 0;
1187 param->tag = type->tag;
1188 param->reserved2 = 0;
1189 param->n_types = 2;
1191 pos = *offset2 + 4;
1192 *offset2 += 12;
1194 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1195 module, modules, strings, types,
1196 data, &pos, offset2);
1197 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type2,
1198 module, modules, strings, types,
1199 data, &pos, offset2);
1201 break;
1203 case TYPE_TAG_ERROR:
1205 ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
1206 gint i;
1208 blob->pointer = 1;
1209 blob->reserved = 0;
1210 blob->tag = type->tag;
1211 blob->reserved2 = 0;
1212 if (type->errors)
1213 blob->n_domains = g_strv_length (type->errors);
1214 else
1215 blob->n_domains = 0;
1217 *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4);
1218 for (i = 0; i < blob->n_domains; i++)
1219 blob->domains[i] = find_entry (module, modules, type->errors[i]);
1221 break;
1223 default:
1224 g_error ("Unknown type tag %d\n", type->tag);
1225 break;
1230 break;
1232 case G_IDL_NODE_FIELD:
1234 GIdlNodeField *field = (GIdlNodeField *)node;
1235 FieldBlob *blob;
1237 blob = (FieldBlob *)&data[*offset];
1238 *offset += 8;
1240 blob->name = write_string (node->name, strings, data, offset2);
1241 blob->readable = field->readable;
1242 blob->writable = field->writable;
1243 blob->reserved = 0;
1244 blob->bits = 0;
1245 blob->struct_offset = field->offset;
1247 g_idl_node_build_metadata ((GIdlNode *)field->type,
1248 module, modules, strings, types,
1249 data, offset, offset2);
1251 break;
1253 case G_IDL_NODE_PROPERTY:
1255 GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
1256 PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1257 *offset += 8;
1259 blob->name = write_string (node->name, strings, data, offset2);
1260 blob->deprecated = prop->deprecated;
1261 blob->readable = prop->readable;
1262 blob->writable = prop->writable;
1263 blob->construct = prop->construct;
1264 blob->construct_only = prop->construct_only;
1265 blob->reserved = 0;
1267 g_idl_node_build_metadata ((GIdlNode *)prop->type,
1268 module, modules, strings, types,
1269 data, offset, offset2);
1271 break;
1273 case G_IDL_NODE_FUNCTION:
1275 FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1276 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1277 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1278 guint32 signature;
1279 gint n;
1281 signature = *offset2;
1282 n = g_list_length (function->parameters);
1284 *offset += 16;
1285 *offset2 += 8 + n * 12;
1287 blob->blob_type = BLOB_TYPE_FUNCTION;
1288 blob->deprecated = function->deprecated;
1289 blob->setter = function->is_setter;
1290 blob->getter = function->is_getter;
1291 blob->constructor = function->is_constructor;
1292 blob->wraps_vfunc = function->wraps_vfunc;
1293 blob->reserved = 0;
1294 blob->index = 0;
1295 blob->name = write_string (node->name, strings, data, offset2);
1296 blob->symbol = write_string (function->symbol, strings, data, offset2);
1297 blob->signature = signature;
1299 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1300 module, modules, strings, types,
1301 data, &signature, offset2);
1303 blob2->may_return_null = function->result->null_ok;
1304 blob2->caller_owns_return_value = function->result->transfer;
1305 blob2->caller_owns_return_container = function->result->shallow_transfer;
1306 blob2->reserved = 0;
1307 blob2->n_arguments = n;
1309 signature += 4;
1311 for (l = function->parameters; l; l = l->next)
1313 GIdlNode *param = (GIdlNode *)l->data;
1315 g_idl_node_build_metadata (param,
1316 module, modules, strings, types,
1317 data, &signature, offset2);
1320 break;
1322 case G_IDL_NODE_CALLBACK:
1324 CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1325 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1326 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1327 guint32 signature;
1328 gint n;
1330 signature = *offset2;
1331 n = g_list_length (function->parameters);
1333 *offset += 12;
1334 *offset2 += 8 + n * 12;
1336 blob->blob_type = BLOB_TYPE_CALLBACK;
1337 blob->deprecated = function->deprecated;
1338 blob->reserved = 0;
1339 blob->name = write_string (node->name, strings, data, offset2);
1340 blob->signature = signature;
1342 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1343 module, modules, strings, types,
1344 data, &signature, offset2);
1346 blob2->may_return_null = function->result->null_ok;
1347 blob2->caller_owns_return_value = function->result->transfer;
1348 blob2->caller_owns_return_container = function->result->shallow_transfer;
1349 blob2->reserved = 0;
1350 blob2->n_arguments = n;
1352 signature += 4;
1354 for (l = function->parameters; l; l = l->next)
1356 GIdlNode *param = (GIdlNode *)l->data;
1358 g_idl_node_build_metadata (param,
1359 module, modules, strings, types,
1360 data, &signature, offset2);
1363 break;
1365 case G_IDL_NODE_SIGNAL:
1367 SignalBlob *blob = (SignalBlob *)&data[*offset];
1368 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1369 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
1370 guint32 signature;
1371 gint n;
1373 signature = *offset2;
1374 n = g_list_length (signal->parameters);
1376 *offset += 12;
1377 *offset2 += 8 + n * 12;
1379 blob->deprecated = signal->deprecated;
1380 blob->run_first = signal->run_first;
1381 blob->run_last = signal->run_last;
1382 blob->run_cleanup = signal->run_cleanup;
1383 blob->no_recurse = signal->no_recurse;
1384 blob->detailed = signal->detailed;
1385 blob->action = signal->action;
1386 blob->no_hooks = signal->no_hooks;
1387 blob->has_class_closure = 0; /* FIXME */
1388 blob->true_stops_emit = 0; /* FIXME */
1389 blob->reserved = 0;
1390 blob->class_closure = 0; /* FIXME */
1391 blob->name = write_string (node->name, strings, data, offset2);
1392 blob->signature = signature;
1394 g_idl_node_build_metadata ((GIdlNode *)signal->result->type,
1395 module, modules, strings, types,
1396 data, &signature, offset2);
1398 blob2->may_return_null = signal->result->null_ok;
1399 blob2->caller_owns_return_value = signal->result->transfer;
1400 blob2->caller_owns_return_container = signal->result->shallow_transfer;
1401 blob2->reserved = 0;
1402 blob2->n_arguments = n;
1404 signature += 4;
1406 for (l = signal->parameters; l; l = l->next)
1408 GIdlNode *param = (GIdlNode *)l->data;
1410 g_idl_node_build_metadata (param, module, modules, strings, types,
1411 data, &signature, offset2);
1414 break;
1416 case G_IDL_NODE_VFUNC:
1418 VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1419 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1420 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
1421 guint32 signature;
1422 gint n;
1424 signature = *offset2;
1425 n = g_list_length (vfunc->parameters);
1427 *offset += 16;
1428 *offset2 += 8 + n * 12;
1430 blob->name = write_string (node->name, strings, data, offset2);
1431 blob->must_chain_up = 0; /* FIXME */
1432 blob->must_be_implemented = 0; /* FIXME */
1433 blob->must_not_be_implemented = 0; /* FIXME */
1434 blob->class_closure = 0; /* FIXME */
1435 blob->reserved = 0;
1437 blob->struct_offset = vfunc->offset;
1438 blob->reserved2 = 0;
1439 blob->signature = signature;
1441 g_idl_node_build_metadata ((GIdlNode *)vfunc->result->type,
1442 module, modules, strings, types,
1443 data, &signature, offset2);
1445 blob2->may_return_null = vfunc->result->null_ok;
1446 blob2->caller_owns_return_value = vfunc->result->transfer;
1447 blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1448 blob2->reserved = 0;
1449 blob2->n_arguments = n;
1451 signature += 4;
1453 for (l = vfunc->parameters; l; l = l->next)
1455 GIdlNode *param = (GIdlNode *)l->data;
1457 g_idl_node_build_metadata (param, module, modules, strings,
1458 types, data, &signature, offset2);
1461 break;
1463 case G_IDL_NODE_PARAM:
1465 ArgBlob *blob = (ArgBlob *)&data[*offset];
1466 GIdlNodeParam *param = (GIdlNodeParam *)node;
1468 *offset += 8;
1470 blob->name = write_string (node->name, strings, data, offset2);
1471 blob->in = param->in;
1472 blob->out = param->out;
1473 blob->dipper = param->dipper;
1474 blob->null_ok = param->null_ok;
1475 blob->optional = param->optional;
1476 blob->transfer_ownership = param->transfer;
1477 blob->transfer_container_ownership = param->shallow_transfer;
1478 blob->return_value = param->retval;
1479 blob->reserved = 0;
1481 g_idl_node_build_metadata ((GIdlNode *)param->type, module, modules,
1482 strings, types, data, offset, offset2);
1484 break;
1486 case G_IDL_NODE_STRUCT:
1488 StructBlob *blob = (StructBlob *)&data[*offset];
1489 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
1491 blob->blob_type = BLOB_TYPE_STRUCT;
1492 blob->deprecated = struct_->deprecated;
1493 blob->unregistered = TRUE;
1494 blob->reserved = 0;
1495 blob->name = write_string (node->name, strings, data, offset2);
1496 blob->gtype_name = 0;
1497 blob->gtype_init = 0;
1499 blob->n_fields = 0;
1500 blob->n_methods = 0;
1502 *offset += 20;
1503 for (l = struct_->members; l; l = l->next)
1505 GIdlNode *member = (GIdlNode *)l->data;
1507 if (member->type == G_IDL_NODE_FIELD)
1509 blob->n_fields++;
1510 g_idl_node_build_metadata (member, module, modules, strings,
1511 types, data, offset, offset2);
1515 for (l = struct_->members; l; l = l->next)
1517 GIdlNode *member = (GIdlNode *)l->data;
1519 if (member->type == G_IDL_NODE_FUNCTION)
1521 blob->n_methods++;
1522 g_idl_node_build_metadata (member, module, modules, strings,
1523 types, data, offset, offset2);
1527 break;
1529 case G_IDL_NODE_BOXED:
1531 StructBlob *blob = (StructBlob *)&data[*offset];
1532 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
1534 blob->blob_type = BLOB_TYPE_BOXED;
1535 blob->deprecated = boxed->deprecated;
1536 blob->unregistered = FALSE;
1537 blob->reserved = 0;
1538 blob->name = write_string (node->name, strings, data, offset2);
1539 blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
1540 blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
1542 blob->n_fields = 0;
1543 blob->n_methods = 0;
1545 *offset += 20;
1546 for (l = boxed->members; l; l = l->next)
1548 GIdlNode *member = (GIdlNode *)l->data;
1550 if (member->type == G_IDL_NODE_FIELD)
1552 blob->n_fields++;
1553 g_idl_node_build_metadata (member, module, modules, strings,
1554 types, data, offset, offset2);
1558 for (l = boxed->members; l; l = l->next)
1560 GIdlNode *member = (GIdlNode *)l->data;
1562 if (member->type == G_IDL_NODE_FUNCTION)
1564 blob->n_methods++;
1565 g_idl_node_build_metadata (member, module, modules, strings,
1566 types, data, offset, offset2);
1570 break;
1572 case G_IDL_NODE_UNION:
1574 UnionBlob *blob = (UnionBlob *)&data[*offset];
1575 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
1577 blob->blob_type = BLOB_TYPE_UNION;
1578 blob->deprecated = union_->deprecated;
1579 blob->reserved = 0;
1580 blob->name = write_string (node->name, strings, data, offset2);
1581 if (union_->gtype_name)
1583 blob->unregistered = FALSE;
1584 blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2);
1585 blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2);
1587 else
1589 blob->unregistered = TRUE;
1590 blob->gtype_name = 0;
1591 blob->gtype_init = 0;
1594 blob->n_fields = 0;
1595 blob->n_functions = 0;
1597 blob->discriminator_offset = union_->discriminator_offset;
1599 if (union_->discriminator_type)
1601 *offset += 24;
1602 blob->discriminated = TRUE;
1603 g_idl_node_build_metadata ((GIdlNode *)union_->discriminator_type,
1604 module, modules, strings, types,
1605 data, offset, offset2);
1607 else
1609 *offset += 28;
1610 blob->discriminated = FALSE;
1611 blob->discriminator_type.offset = 0;
1615 for (l = union_->members; l; l = l->next)
1617 GIdlNode *member = (GIdlNode *)l->data;
1619 if (member->type == G_IDL_NODE_FIELD)
1621 blob->n_fields++;
1622 g_idl_node_build_metadata (member, module, modules, strings,
1623 types, data, offset, offset2);
1627 for (l = union_->members; l; l = l->next)
1629 GIdlNode *member = (GIdlNode *)l->data;
1631 if (member->type == G_IDL_NODE_FUNCTION)
1633 blob->n_functions++;
1634 g_idl_node_build_metadata (member, module, modules, strings,
1635 types, data, offset, offset2);
1639 if (union_->discriminator_type)
1641 for (l = union_->discriminators; l; l = l->next)
1643 GIdlNode *member = (GIdlNode *)l->data;
1645 g_idl_node_build_metadata (member, module, modules, strings,
1646 types, data, offset, offset2);
1650 break;
1652 case G_IDL_NODE_ENUM:
1653 case G_IDL_NODE_FLAGS:
1655 EnumBlob *blob = (EnumBlob *)&data[*offset];
1656 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
1658 *offset += 20;
1660 if (node->type == G_IDL_NODE_ENUM)
1661 blob->blob_type = BLOB_TYPE_ENUM;
1662 else
1663 blob->blob_type = BLOB_TYPE_FLAGS;
1665 blob->deprecated = enum_->deprecated;
1666 blob->reserved = 0;
1667 blob->name = write_string (node->name, strings, data, offset2);
1668 if (enum_->gtype_name)
1670 blob->unregistered = FALSE;
1671 blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2);
1672 blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2);
1674 else
1676 blob->unregistered = TRUE;
1677 blob->gtype_name = 0;
1678 blob->gtype_init = 0;
1681 blob->n_values = 0;
1682 blob->reserved2 = 0;
1684 for (l = enum_->values; l; l = l->next)
1686 GIdlNode *value = (GIdlNode *)l->data;
1688 blob->n_values++;
1689 g_idl_node_build_metadata (value, module, modules, strings, types,
1690 data, offset, offset2);
1693 break;
1695 case G_IDL_NODE_OBJECT:
1697 ObjectBlob *blob = (ObjectBlob *)&data[*offset];
1698 GIdlNodeInterface *object = (GIdlNodeInterface *)node;
1700 blob->blob_type = BLOB_TYPE_OBJECT;
1701 blob->deprecated = object->deprecated;
1702 blob->reserved = 0;
1703 blob->name = write_string (node->name, strings, data, offset2);
1704 blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
1705 blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
1706 if (object->parent)
1707 blob->parent = find_entry (module, modules, object->parent);
1708 else
1709 blob->parent = 0;
1711 blob->n_interfaces = 0;
1712 blob->n_fields = 0;
1713 blob->n_properties = 0;
1714 blob->n_methods = 0;
1715 blob->n_signals = 0;
1716 blob->n_vfuncs = 0;
1717 blob->n_constants = 0;
1719 *offset += 32;
1720 for (l = object->interfaces; l; l = l->next)
1722 blob->n_interfaces++;
1723 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1724 *offset += 2;
1727 *offset = ALIGN_VALUE (*offset, 4);
1728 for (l = object->members; l; l = l->next)
1730 GIdlNode *member = (GIdlNode *)l->data;
1732 if (member->type == G_IDL_NODE_FIELD)
1734 blob->n_fields++;
1735 g_idl_node_build_metadata (member, module, modules, strings,
1736 types, data, offset, offset2);
1740 *offset = ALIGN_VALUE (*offset, 4);
1741 for (l = object->members; l; l = l->next)
1743 GIdlNode *member = (GIdlNode *)l->data;
1745 if (member->type == G_IDL_NODE_PROPERTY)
1747 blob->n_properties++;
1748 g_idl_node_build_metadata (member, module, modules, strings,
1749 types, data, offset, offset2);
1753 *offset = ALIGN_VALUE (*offset, 4);
1754 for (l = object->members; l; l = l->next)
1756 GIdlNode *member = (GIdlNode *)l->data;
1758 if (member->type == G_IDL_NODE_FUNCTION)
1760 blob->n_methods++;
1761 g_idl_node_build_metadata (member, module, modules, strings,
1762 types, data, offset, offset2);
1766 *offset = ALIGN_VALUE (*offset, 4);
1767 for (l = object->members; l; l = l->next)
1769 GIdlNode *member = (GIdlNode *)l->data;
1771 if (member->type == G_IDL_NODE_SIGNAL)
1773 blob->n_signals++;
1774 g_idl_node_build_metadata (member, module, modules, strings,
1775 types, data, offset, offset2);
1779 *offset = ALIGN_VALUE (*offset, 4);
1780 for (l = object->members; l; l = l->next)
1782 GIdlNode *member = (GIdlNode *)l->data;
1784 if (member->type == G_IDL_NODE_VFUNC)
1786 blob->n_vfuncs++;
1787 g_idl_node_build_metadata (member, module, modules, strings,
1788 types, data, offset, offset2);
1792 *offset = ALIGN_VALUE (*offset, 4);
1793 for (l = object->members; l; l = l->next)
1795 GIdlNode *member = (GIdlNode *)l->data;
1797 if (member->type == G_IDL_NODE_CONSTANT)
1799 blob->n_constants++;
1800 g_idl_node_build_metadata (member, module, modules, strings,
1801 types, data, offset, offset2);
1805 break;
1807 case G_IDL_NODE_INTERFACE:
1809 InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
1810 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
1812 blob->blob_type = BLOB_TYPE_INTERFACE;
1813 blob->deprecated = iface->deprecated;
1814 blob->reserved = 0;
1815 blob->name = write_string (node->name, strings, data, offset2);
1816 blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
1817 blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
1818 blob->n_prerequisites = 0;
1819 blob->n_properties = 0;
1820 blob->n_methods = 0;
1821 blob->n_signals = 0;
1822 blob->n_vfuncs = 0;
1823 blob->n_constants = 0;
1825 *offset += 28;
1826 for (l = iface->prerequisites; l; l = l->next)
1828 blob->n_prerequisites++;
1829 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1830 *offset += 2;
1833 *offset = ALIGN_VALUE (*offset, 4);
1834 for (l = iface->members; l; l = l->next)
1836 GIdlNode *member = (GIdlNode *)l->data;
1838 if (member->type == G_IDL_NODE_PROPERTY)
1840 blob->n_properties++;
1841 g_idl_node_build_metadata (member, module, modules, strings,
1842 types, data, offset, offset2);
1846 *offset = ALIGN_VALUE (*offset, 4);
1847 for (l = iface->members; l; l = l->next)
1849 GIdlNode *member = (GIdlNode *)l->data;
1851 if (member->type == G_IDL_NODE_FUNCTION)
1853 blob->n_methods++;
1854 g_idl_node_build_metadata (member, module, modules, strings,
1855 types, data, offset, offset2);
1859 *offset = ALIGN_VALUE (*offset, 4);
1860 for (l = iface->members; l; l = l->next)
1862 GIdlNode *member = (GIdlNode *)l->data;
1864 if (member->type == G_IDL_NODE_SIGNAL)
1866 blob->n_signals++;
1867 g_idl_node_build_metadata (member, module, modules, strings,
1868 types, data, offset, offset2);
1872 *offset = ALIGN_VALUE (*offset, 4);
1873 for (l = iface->members; l; l = l->next)
1875 GIdlNode *member = (GIdlNode *)l->data;
1877 if (member->type == G_IDL_NODE_VFUNC)
1879 blob->n_vfuncs++;
1880 g_idl_node_build_metadata (member, module, modules, strings,
1881 types, data, offset, offset2);
1885 *offset = ALIGN_VALUE (*offset, 4);
1886 for (l = iface->members; l; l = l->next)
1888 GIdlNode *member = (GIdlNode *)l->data;
1890 if (member->type == G_IDL_NODE_CONSTANT)
1892 blob->n_constants++;
1893 g_idl_node_build_metadata (member, module, modules, strings,
1894 types, data, offset, offset2);
1898 break;
1901 case G_IDL_NODE_VALUE:
1903 GIdlNodeValue *value = (GIdlNodeValue *)node;
1904 ValueBlob *blob = (ValueBlob *)&data[*offset];
1905 *offset += 12;
1907 blob->deprecated = value->deprecated;
1908 blob->reserved = 0;
1909 blob->name = write_string (node->name, strings, data, offset2);
1910 blob->value = value->value;
1912 break;
1914 case G_IDL_NODE_ERROR_DOMAIN:
1916 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
1917 ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
1918 *offset += 16;
1920 blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
1921 blob->deprecated = domain->deprecated;
1922 blob->reserved = 0;
1923 blob->name = write_string (node->name, strings, data, offset2);
1924 blob->get_quark = write_string (domain->getquark, strings, data, offset2);
1925 blob->error_codes = find_entry (module, modules, domain->codes);
1926 blob->reserved2 = 0;
1928 break;
1930 case G_IDL_NODE_CONSTANT:
1932 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
1933 ConstantBlob *blob = (ConstantBlob *)&data[*offset];
1934 guint32 pos;
1936 pos = *offset + 8;
1937 *offset += 20;
1939 blob->blob_type = BLOB_TYPE_CONSTANT;
1940 blob->deprecated = constant->deprecated;
1941 blob->reserved = 0;
1942 blob->name = write_string (node->name, strings, data, offset2);
1944 blob->offset = *offset2;
1945 switch (constant->type->tag)
1947 case TYPE_TAG_BOOLEAN:
1948 blob->size = 4;
1949 *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
1950 break;
1951 case TYPE_TAG_INT8:
1952 blob->size = 1;
1953 *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
1954 break;
1955 case TYPE_TAG_UINT8:
1956 blob->size = 1;
1957 *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
1958 break;
1959 case TYPE_TAG_INT16:
1960 blob->size = 2;
1961 *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
1962 break;
1963 case TYPE_TAG_UINT16:
1964 blob->size = 2;
1965 *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
1966 break;
1967 case TYPE_TAG_INT32:
1968 blob->size = 4;
1969 *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
1970 break;
1971 case TYPE_TAG_UINT32:
1972 blob->size = 4;
1973 *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
1974 break;
1975 case TYPE_TAG_INT64:
1976 blob->size = 8;
1977 *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
1978 break;
1979 case TYPE_TAG_UINT64:
1980 blob->size = 8;
1981 *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
1982 break;
1983 case TYPE_TAG_INT:
1984 blob->size = sizeof (gint);
1985 *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
1986 break;
1987 case TYPE_TAG_UINT:
1988 blob->size = sizeof (guint);
1989 *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
1990 break;
1991 case TYPE_TAG_SSIZE: /* FIXME */
1992 case TYPE_TAG_LONG:
1993 blob->size = sizeof (glong);
1994 *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
1995 break;
1996 case TYPE_TAG_SIZE: /* FIXME */
1997 case TYPE_TAG_ULONG:
1998 blob->size = sizeof (gulong);
1999 *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
2000 break;
2001 case TYPE_TAG_FLOAT:
2002 blob->size = sizeof (gfloat);
2003 *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
2004 break;
2005 case TYPE_TAG_DOUBLE:
2006 blob->size = sizeof (gdouble);
2007 *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
2008 break;
2009 case TYPE_TAG_UTF8:
2010 case TYPE_TAG_FILENAME:
2011 blob->size = strlen (constant->value) + 1;
2012 memcpy (&data[blob->offset], constant->value, blob->size);
2013 break;
2015 *offset2 += ALIGN_VALUE (blob->size, 4);
2017 g_idl_node_build_metadata ((GIdlNode *)constant->type, module, modules,
2018 strings, types, data, &pos, offset2);
2020 break;
2021 default:
2022 g_assert_not_reached ();
2025 g_debug ("node %p type %d, offset %d -> %d, offset2 %d -> %d",
2026 node, node->type, old_offset, *offset, old_offset2, *offset2);
2028 if (*offset2 - old_offset2 + *offset - old_offset > g_idl_node_get_full_size (node))
2029 g_error ("exceeding space reservation !!");
2032 /* if str is already in the pool, return previous location, otherwise write str
2033 * to the metadata at offset, put it in the pool and update offset. If the
2034 * metadata is not large enough to hold the string, reallocate it.
2036 guint32
2037 write_string (const gchar *str,
2038 GHashTable *strings,
2039 guchar *data,
2040 guint32 *offset)
2042 gpointer value;
2043 guint32 start;
2045 string_count += 1;
2046 string_size += strlen (str);
2048 value = g_hash_table_lookup (strings, str);
2050 if (value)
2051 return GPOINTER_TO_INT (value);
2053 unique_string_count += 1;
2054 unique_string_size += strlen (str);
2056 g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
2058 start = *offset;
2059 *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
2061 strcpy ((gchar*)&data[start], str);
2063 return start;