Release 0.41.92
[vala-gnome.git] / gobject-introspection / gidlnode.c
blob8ad5c965b204505768664230031c349be3357c87
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;
790 default:
791 break;
793 return FALSE;
796 void
797 g_idl_node_add_member (GIdlNode *node,
798 GIdlNodeFunction *member)
800 g_return_if_fail (node != NULL);
801 g_return_if_fail (member != NULL);
803 switch (node->type)
805 case G_IDL_NODE_OBJECT:
806 case G_IDL_NODE_INTERFACE:
808 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
809 iface->members =
810 g_list_insert_sorted (iface->members, member,
811 (GCompareFunc) g_idl_node_cmp);
812 break;
814 case G_IDL_NODE_BOXED:
816 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
817 boxed->members =
818 g_list_insert_sorted (boxed->members, member,
819 (GCompareFunc) g_idl_node_cmp);
820 break;
822 case G_IDL_NODE_STRUCT:
824 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
825 struct_->members =
826 g_list_insert_sorted (struct_->members, member,
827 (GCompareFunc) g_idl_node_cmp);
828 break;
830 case G_IDL_NODE_UNION:
832 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
833 union_->members =
834 g_list_insert_sorted (union_->members, member,
835 (GCompareFunc) g_idl_node_cmp);
836 break;
838 default:
839 g_error ("Cannot add a member to unknown type tag type %d\n",
840 node->type);
841 break;
845 static gint64
846 parse_int_value (const gchar *str)
848 return strtoll (str, NULL, 0);
851 static guint64
852 parse_uint_value (const gchar *str)
854 return strtoull (str, NULL, 0);
857 static gdouble
858 parse_float_value (const gchar *str)
860 return strtod (str, NULL);
863 static gboolean
864 parse_boolean_value (const gchar *str)
866 if (strcmp (str, "TRUE") == 0)
867 return TRUE;
869 if (strcmp (str, "FALSE") == 0)
870 return FALSE;
872 return parse_int_value (str) ? TRUE : FALSE;
875 static GIdlNode *
876 find_entry_node (GIdlModule *module,
877 GList *modules,
878 const gchar *name,
879 guint16 *idx)
882 GList *l;
883 gint i;
884 gchar **names;
885 gint n_names;
886 GIdlNode *result = NULL;
888 names = g_strsplit (name, ".", 0);
889 n_names = g_strv_length (names);
890 if (n_names > 2)
891 g_error ("Too many name parts");
893 for (l = module->entries, i = 1; l; l = l->next, i++)
895 GIdlNode *node = (GIdlNode *)l->data;
897 if (n_names > 1)
899 if (node->type != G_IDL_NODE_XREF)
900 continue;
902 if (((GIdlNodeXRef *)node)->namespace == NULL ||
903 strcmp (((GIdlNodeXRef *)node)->namespace, names[0]) != 0)
904 continue;
907 if (strcmp (node->name, names[n_names - 1]) == 0)
909 if (idx)
910 *idx = i;
912 result = node;
913 goto out;
917 if (n_names > 1)
919 GIdlNode *node = g_idl_node_new (G_IDL_NODE_XREF);
921 ((GIdlNodeXRef *)node)->namespace = g_strdup (names[0]);
922 node->name = g_strdup (names[1]);
924 module->entries = g_list_append (module->entries, node);
926 if (idx)
927 *idx = g_list_length (module->entries);
929 result = node;
931 goto out;
934 g_warning ("Entry %s not found", name);
936 out:
938 g_strfreev (names);
940 return result;
943 static guint16
944 find_entry (GIdlModule *module,
945 GList *modules,
946 const gchar *name)
948 guint16 idx = 0;
950 find_entry_node (module, modules, name, &idx);
952 return idx;
955 static void
956 serialize_type (GIdlModule *module,
957 GList *modules,
958 GIdlNodeType *node,
959 GString *str)
961 gint i;
962 const gchar* basic[] = {
963 "void",
964 "gboolean",
965 "gint8",
966 "guint8",
967 "gint16",
968 "guint16",
969 "gint32",
970 "guint32",
971 "gint64",
972 "guint64",
973 "gint",
974 "guint",
975 "glong",
976 "gulong",
977 "gssize",
978 "gsize",
979 "gfloat",
980 "gdouble",
981 "utf8",
982 "filename"
985 if (node->tag < 20)
987 g_string_append_printf (str, "%s%s",
988 basic[node->tag], node->is_pointer ? "*" : "");
990 else if (node->tag == 20)
992 serialize_type (module, modules, node->parameter_type1, str);
993 g_string_append (str, "[");
995 if (node->has_length)
996 g_string_append_printf (str, "length=%d", node->length);
998 if (node->zero_terminated)
999 g_string_append_printf (str, "%szero-terminated=1",
1000 node->has_length ? "," : "");
1002 g_string_append (str, "]");
1004 else if (node->tag == 21)
1006 GIdlNode *iface;
1007 gchar *name;
1009 iface = find_entry_node (module, modules, node->interface, NULL);
1010 if (iface)
1011 name = iface->name;
1012 else
1014 g_warning ("Interface for type reference %s not found", node->interface);
1015 name = node->interface;
1018 g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : "");
1020 else if (node->tag == 22)
1022 g_string_append (str, "GList");
1023 if (node->parameter_type1)
1025 g_string_append (str, "<");
1026 serialize_type (module, modules, node->parameter_type1, str);
1027 g_string_append (str, ">");
1030 else if (node->tag == 23)
1032 g_string_append (str, "GSList");
1033 if (node->parameter_type1)
1035 g_string_append (str, "<");
1036 serialize_type (module, modules, node->parameter_type1, str);
1037 g_string_append (str, ">");
1040 else if (node->tag == 24)
1042 g_string_append (str, "GHashTable<");
1043 if (node->parameter_type1)
1045 g_string_append (str, "<");
1046 serialize_type (module, modules, node->parameter_type1, str);
1047 g_string_append (str, ",");
1048 serialize_type (module, modules, node->parameter_type2, str);
1049 g_string_append (str, ">");
1052 else if (node->tag == 25)
1054 g_string_append (str, "GError");
1055 if (node->errors)
1057 g_string_append (str, "<");
1058 for (i = 0; node->errors[i]; i++)
1060 if (i > 0)
1061 g_string_append (str, ",");
1062 g_string_append (str, node->errors[i]);
1064 g_string_append (str, ">");
1069 void
1070 g_idl_node_build_metadata (GIdlNode *node,
1071 GIdlModule *module,
1072 GList *modules,
1073 GHashTable *strings,
1074 GHashTable *types,
1075 guchar *data,
1076 guint32 *offset,
1077 guint32 *offset2)
1079 GList *l;
1080 guint32 old_offset = *offset;
1081 guint32 old_offset2 = *offset2;
1083 switch (node->type)
1085 case G_IDL_NODE_TYPE:
1087 GIdlNodeType *type = (GIdlNodeType *)node;
1088 SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
1090 *offset += 4;
1092 if (type->tag < TYPE_TAG_ARRAY)
1094 blob->reserved = 0;
1095 blob->reserved2 = 0;
1096 blob->pointer = type->is_pointer;
1097 blob->reserved3 = 0;
1098 blob->tag = type->tag;
1100 else
1102 GString *str;
1103 gchar *s;
1104 gpointer value;
1106 str = g_string_new (0);
1107 serialize_type (module, modules, type, str);
1108 s = g_string_free (str, FALSE);
1110 types_count += 1;
1111 value = g_hash_table_lookup (types, s);
1112 if (value)
1114 blob->offset = GPOINTER_TO_INT (value);
1115 g_free (s);
1117 else
1119 unique_types_count += 1;
1120 g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
1122 blob->offset = *offset2;
1123 switch (type->tag)
1125 case TYPE_TAG_ARRAY:
1127 ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
1128 guint32 pos;
1130 array->pointer = 1;
1131 array->reserved = 0;
1132 array->tag = type->tag;
1133 array->zero_terminated = type->zero_terminated;
1134 array->has_length = type->has_length;
1135 array->reserved2 = 0;
1136 array->length = type->length;
1138 pos = *offset2 + 4;
1139 *offset2 += 8;
1141 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1142 module, modules, strings, types,
1143 data, &pos, offset2);
1145 break;
1147 case TYPE_TAG_INTERFACE:
1149 InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
1150 *offset2 += 4;
1152 iface->pointer = type->is_pointer;
1153 iface->reserved = 0;
1154 iface->tag = type->tag;
1155 iface->reserved2 = 0;
1156 iface->interface = find_entry (module, modules, type->interface);
1159 break;
1161 case TYPE_TAG_LIST:
1162 case TYPE_TAG_SLIST:
1164 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1165 guint32 pos;
1167 param->pointer = 1;
1168 param->reserved = 0;
1169 param->tag = type->tag;
1170 param->reserved2 = 0;
1171 param->n_types = 1;
1173 pos = *offset2 + 4;
1174 *offset2 += 8;
1176 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1177 module, modules, strings, types,
1178 data, &pos, offset2);
1180 break;
1182 case TYPE_TAG_HASH:
1184 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1185 guint32 pos;
1187 param->pointer = 1;
1188 param->reserved = 0;
1189 param->tag = type->tag;
1190 param->reserved2 = 0;
1191 param->n_types = 2;
1193 pos = *offset2 + 4;
1194 *offset2 += 12;
1196 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1197 module, modules, strings, types,
1198 data, &pos, offset2);
1199 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type2,
1200 module, modules, strings, types,
1201 data, &pos, offset2);
1203 break;
1205 case TYPE_TAG_ERROR:
1207 ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
1208 gint i;
1210 blob->pointer = 1;
1211 blob->reserved = 0;
1212 blob->tag = type->tag;
1213 blob->reserved2 = 0;
1214 if (type->errors)
1215 blob->n_domains = g_strv_length (type->errors);
1216 else
1217 blob->n_domains = 0;
1219 *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4);
1220 for (i = 0; i < blob->n_domains; i++)
1221 blob->domains[i] = find_entry (module, modules, type->errors[i]);
1223 break;
1225 default:
1226 g_error ("Unknown type tag %d\n", type->tag);
1227 break;
1232 break;
1234 case G_IDL_NODE_FIELD:
1236 GIdlNodeField *field = (GIdlNodeField *)node;
1237 FieldBlob *blob;
1239 blob = (FieldBlob *)&data[*offset];
1240 *offset += 8;
1242 blob->name = write_string (node->name, strings, data, offset2);
1243 blob->readable = field->readable;
1244 blob->writable = field->writable;
1245 blob->reserved = 0;
1246 blob->bits = 0;
1247 blob->struct_offset = field->offset;
1249 g_idl_node_build_metadata ((GIdlNode *)field->type,
1250 module, modules, strings, types,
1251 data, offset, offset2);
1253 break;
1255 case G_IDL_NODE_PROPERTY:
1257 GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
1258 PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1259 *offset += 8;
1261 blob->name = write_string (node->name, strings, data, offset2);
1262 blob->deprecated = prop->deprecated;
1263 blob->readable = prop->readable;
1264 blob->writable = prop->writable;
1265 blob->construct = prop->construct;
1266 blob->construct_only = prop->construct_only;
1267 blob->reserved = 0;
1269 g_idl_node_build_metadata ((GIdlNode *)prop->type,
1270 module, modules, strings, types,
1271 data, offset, offset2);
1273 break;
1275 case G_IDL_NODE_FUNCTION:
1277 FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1278 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1279 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1280 guint32 signature;
1281 gint n;
1283 signature = *offset2;
1284 n = g_list_length (function->parameters);
1286 *offset += 16;
1287 *offset2 += 8 + n * 12;
1289 blob->blob_type = BLOB_TYPE_FUNCTION;
1290 blob->deprecated = function->deprecated;
1291 blob->setter = function->is_setter;
1292 blob->getter = function->is_getter;
1293 blob->constructor = function->is_constructor;
1294 blob->wraps_vfunc = function->wraps_vfunc;
1295 blob->reserved = 0;
1296 blob->index = 0;
1297 blob->name = write_string (node->name, strings, data, offset2);
1298 blob->symbol = write_string (function->symbol, strings, data, offset2);
1299 blob->signature = signature;
1301 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1302 module, modules, strings, types,
1303 data, &signature, offset2);
1305 blob2->may_return_null = function->result->null_ok;
1306 blob2->caller_owns_return_value = function->result->transfer;
1307 blob2->caller_owns_return_container = function->result->shallow_transfer;
1308 blob2->reserved = 0;
1309 blob2->n_arguments = n;
1311 signature += 4;
1313 for (l = function->parameters; l; l = l->next)
1315 GIdlNode *param = (GIdlNode *)l->data;
1317 g_idl_node_build_metadata (param,
1318 module, modules, strings, types,
1319 data, &signature, offset2);
1322 break;
1324 case G_IDL_NODE_CALLBACK:
1326 CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1327 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1328 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1329 guint32 signature;
1330 gint n;
1332 signature = *offset2;
1333 n = g_list_length (function->parameters);
1335 *offset += 12;
1336 *offset2 += 8 + n * 12;
1338 blob->blob_type = BLOB_TYPE_CALLBACK;
1339 blob->deprecated = function->deprecated;
1340 blob->reserved = 0;
1341 blob->name = write_string (node->name, strings, data, offset2);
1342 blob->signature = signature;
1344 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1345 module, modules, strings, types,
1346 data, &signature, offset2);
1348 blob2->may_return_null = function->result->null_ok;
1349 blob2->caller_owns_return_value = function->result->transfer;
1350 blob2->caller_owns_return_container = function->result->shallow_transfer;
1351 blob2->reserved = 0;
1352 blob2->n_arguments = n;
1354 signature += 4;
1356 for (l = function->parameters; l; l = l->next)
1358 GIdlNode *param = (GIdlNode *)l->data;
1360 g_idl_node_build_metadata (param,
1361 module, modules, strings, types,
1362 data, &signature, offset2);
1365 break;
1367 case G_IDL_NODE_SIGNAL:
1369 SignalBlob *blob = (SignalBlob *)&data[*offset];
1370 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1371 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
1372 guint32 signature;
1373 gint n;
1375 signature = *offset2;
1376 n = g_list_length (signal->parameters);
1378 *offset += 12;
1379 *offset2 += 8 + n * 12;
1381 blob->deprecated = signal->deprecated;
1382 blob->run_first = signal->run_first;
1383 blob->run_last = signal->run_last;
1384 blob->run_cleanup = signal->run_cleanup;
1385 blob->no_recurse = signal->no_recurse;
1386 blob->detailed = signal->detailed;
1387 blob->action = signal->action;
1388 blob->no_hooks = signal->no_hooks;
1389 blob->has_class_closure = 0; /* FIXME */
1390 blob->true_stops_emit = 0; /* FIXME */
1391 blob->reserved = 0;
1392 blob->class_closure = 0; /* FIXME */
1393 blob->name = write_string (node->name, strings, data, offset2);
1394 blob->signature = signature;
1396 g_idl_node_build_metadata ((GIdlNode *)signal->result->type,
1397 module, modules, strings, types,
1398 data, &signature, offset2);
1400 blob2->may_return_null = signal->result->null_ok;
1401 blob2->caller_owns_return_value = signal->result->transfer;
1402 blob2->caller_owns_return_container = signal->result->shallow_transfer;
1403 blob2->reserved = 0;
1404 blob2->n_arguments = n;
1406 signature += 4;
1408 for (l = signal->parameters; l; l = l->next)
1410 GIdlNode *param = (GIdlNode *)l->data;
1412 g_idl_node_build_metadata (param, module, modules, strings, types,
1413 data, &signature, offset2);
1416 break;
1418 case G_IDL_NODE_VFUNC:
1420 VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1421 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1422 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
1423 guint32 signature;
1424 gint n;
1426 signature = *offset2;
1427 n = g_list_length (vfunc->parameters);
1429 *offset += 16;
1430 *offset2 += 8 + n * 12;
1432 blob->name = write_string (node->name, strings, data, offset2);
1433 blob->must_chain_up = 0; /* FIXME */
1434 blob->must_be_implemented = 0; /* FIXME */
1435 blob->must_not_be_implemented = 0; /* FIXME */
1436 blob->class_closure = 0; /* FIXME */
1437 blob->reserved = 0;
1439 blob->struct_offset = vfunc->offset;
1440 blob->reserved2 = 0;
1441 blob->signature = signature;
1443 g_idl_node_build_metadata ((GIdlNode *)vfunc->result->type,
1444 module, modules, strings, types,
1445 data, &signature, offset2);
1447 blob2->may_return_null = vfunc->result->null_ok;
1448 blob2->caller_owns_return_value = vfunc->result->transfer;
1449 blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1450 blob2->reserved = 0;
1451 blob2->n_arguments = n;
1453 signature += 4;
1455 for (l = vfunc->parameters; l; l = l->next)
1457 GIdlNode *param = (GIdlNode *)l->data;
1459 g_idl_node_build_metadata (param, module, modules, strings,
1460 types, data, &signature, offset2);
1463 break;
1465 case G_IDL_NODE_PARAM:
1467 ArgBlob *blob = (ArgBlob *)&data[*offset];
1468 GIdlNodeParam *param = (GIdlNodeParam *)node;
1470 *offset += 8;
1472 blob->name = write_string (node->name, strings, data, offset2);
1473 blob->in = param->in;
1474 blob->out = param->out;
1475 blob->dipper = param->dipper;
1476 blob->null_ok = param->null_ok;
1477 blob->optional = param->optional;
1478 blob->transfer_ownership = param->transfer;
1479 blob->transfer_container_ownership = param->shallow_transfer;
1480 blob->return_value = param->retval;
1481 blob->reserved = 0;
1483 g_idl_node_build_metadata ((GIdlNode *)param->type, module, modules,
1484 strings, types, data, offset, offset2);
1486 break;
1488 case G_IDL_NODE_STRUCT:
1490 StructBlob *blob = (StructBlob *)&data[*offset];
1491 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
1493 blob->blob_type = BLOB_TYPE_STRUCT;
1494 blob->deprecated = struct_->deprecated;
1495 blob->unregistered = TRUE;
1496 blob->reserved = 0;
1497 blob->name = write_string (node->name, strings, data, offset2);
1498 blob->gtype_name = 0;
1499 blob->gtype_init = 0;
1501 blob->n_fields = 0;
1502 blob->n_methods = 0;
1504 *offset += 20;
1505 for (l = struct_->members; l; l = l->next)
1507 GIdlNode *member = (GIdlNode *)l->data;
1509 if (member->type == G_IDL_NODE_FIELD)
1511 blob->n_fields++;
1512 g_idl_node_build_metadata (member, module, modules, strings,
1513 types, data, offset, offset2);
1517 for (l = struct_->members; l; l = l->next)
1519 GIdlNode *member = (GIdlNode *)l->data;
1521 if (member->type == G_IDL_NODE_FUNCTION)
1523 blob->n_methods++;
1524 g_idl_node_build_metadata (member, module, modules, strings,
1525 types, data, offset, offset2);
1529 break;
1531 case G_IDL_NODE_BOXED:
1533 StructBlob *blob = (StructBlob *)&data[*offset];
1534 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
1536 blob->blob_type = BLOB_TYPE_BOXED;
1537 blob->deprecated = boxed->deprecated;
1538 blob->unregistered = FALSE;
1539 blob->reserved = 0;
1540 blob->name = write_string (node->name, strings, data, offset2);
1541 blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
1542 blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
1544 blob->n_fields = 0;
1545 blob->n_methods = 0;
1547 *offset += 20;
1548 for (l = boxed->members; l; l = l->next)
1550 GIdlNode *member = (GIdlNode *)l->data;
1552 if (member->type == G_IDL_NODE_FIELD)
1554 blob->n_fields++;
1555 g_idl_node_build_metadata (member, module, modules, strings,
1556 types, data, offset, offset2);
1560 for (l = boxed->members; l; l = l->next)
1562 GIdlNode *member = (GIdlNode *)l->data;
1564 if (member->type == G_IDL_NODE_FUNCTION)
1566 blob->n_methods++;
1567 g_idl_node_build_metadata (member, module, modules, strings,
1568 types, data, offset, offset2);
1572 break;
1574 case G_IDL_NODE_UNION:
1576 UnionBlob *blob = (UnionBlob *)&data[*offset];
1577 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
1579 blob->blob_type = BLOB_TYPE_UNION;
1580 blob->deprecated = union_->deprecated;
1581 blob->reserved = 0;
1582 blob->name = write_string (node->name, strings, data, offset2);
1583 if (union_->gtype_name)
1585 blob->unregistered = FALSE;
1586 blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2);
1587 blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2);
1589 else
1591 blob->unregistered = TRUE;
1592 blob->gtype_name = 0;
1593 blob->gtype_init = 0;
1596 blob->n_fields = 0;
1597 blob->n_functions = 0;
1599 blob->discriminator_offset = union_->discriminator_offset;
1601 if (union_->discriminator_type)
1603 *offset += 24;
1604 blob->discriminated = TRUE;
1605 g_idl_node_build_metadata ((GIdlNode *)union_->discriminator_type,
1606 module, modules, strings, types,
1607 data, offset, offset2);
1609 else
1611 *offset += 28;
1612 blob->discriminated = FALSE;
1613 blob->discriminator_type.offset = 0;
1617 for (l = union_->members; l; l = l->next)
1619 GIdlNode *member = (GIdlNode *)l->data;
1621 if (member->type == G_IDL_NODE_FIELD)
1623 blob->n_fields++;
1624 g_idl_node_build_metadata (member, module, modules, strings,
1625 types, data, offset, offset2);
1629 for (l = union_->members; l; l = l->next)
1631 GIdlNode *member = (GIdlNode *)l->data;
1633 if (member->type == G_IDL_NODE_FUNCTION)
1635 blob->n_functions++;
1636 g_idl_node_build_metadata (member, module, modules, strings,
1637 types, data, offset, offset2);
1641 if (union_->discriminator_type)
1643 for (l = union_->discriminators; l; l = l->next)
1645 GIdlNode *member = (GIdlNode *)l->data;
1647 g_idl_node_build_metadata (member, module, modules, strings,
1648 types, data, offset, offset2);
1652 break;
1654 case G_IDL_NODE_ENUM:
1655 case G_IDL_NODE_FLAGS:
1657 EnumBlob *blob = (EnumBlob *)&data[*offset];
1658 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
1660 *offset += 20;
1662 if (node->type == G_IDL_NODE_ENUM)
1663 blob->blob_type = BLOB_TYPE_ENUM;
1664 else
1665 blob->blob_type = BLOB_TYPE_FLAGS;
1667 blob->deprecated = enum_->deprecated;
1668 blob->reserved = 0;
1669 blob->name = write_string (node->name, strings, data, offset2);
1670 if (enum_->gtype_name)
1672 blob->unregistered = FALSE;
1673 blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2);
1674 blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2);
1676 else
1678 blob->unregistered = TRUE;
1679 blob->gtype_name = 0;
1680 blob->gtype_init = 0;
1683 blob->n_values = 0;
1684 blob->reserved2 = 0;
1686 for (l = enum_->values; l; l = l->next)
1688 GIdlNode *value = (GIdlNode *)l->data;
1690 blob->n_values++;
1691 g_idl_node_build_metadata (value, module, modules, strings, types,
1692 data, offset, offset2);
1695 break;
1697 case G_IDL_NODE_OBJECT:
1699 ObjectBlob *blob = (ObjectBlob *)&data[*offset];
1700 GIdlNodeInterface *object = (GIdlNodeInterface *)node;
1702 blob->blob_type = BLOB_TYPE_OBJECT;
1703 blob->deprecated = object->deprecated;
1704 blob->reserved = 0;
1705 blob->name = write_string (node->name, strings, data, offset2);
1706 blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
1707 blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
1708 if (object->parent)
1709 blob->parent = find_entry (module, modules, object->parent);
1710 else
1711 blob->parent = 0;
1713 blob->n_interfaces = 0;
1714 blob->n_fields = 0;
1715 blob->n_properties = 0;
1716 blob->n_methods = 0;
1717 blob->n_signals = 0;
1718 blob->n_vfuncs = 0;
1719 blob->n_constants = 0;
1721 *offset += 32;
1722 for (l = object->interfaces; l; l = l->next)
1724 blob->n_interfaces++;
1725 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1726 *offset += 2;
1729 *offset = ALIGN_VALUE (*offset, 4);
1730 for (l = object->members; l; l = l->next)
1732 GIdlNode *member = (GIdlNode *)l->data;
1734 if (member->type == G_IDL_NODE_FIELD)
1736 blob->n_fields++;
1737 g_idl_node_build_metadata (member, module, modules, strings,
1738 types, data, offset, offset2);
1742 *offset = ALIGN_VALUE (*offset, 4);
1743 for (l = object->members; l; l = l->next)
1745 GIdlNode *member = (GIdlNode *)l->data;
1747 if (member->type == G_IDL_NODE_PROPERTY)
1749 blob->n_properties++;
1750 g_idl_node_build_metadata (member, module, modules, strings,
1751 types, data, offset, offset2);
1755 *offset = ALIGN_VALUE (*offset, 4);
1756 for (l = object->members; l; l = l->next)
1758 GIdlNode *member = (GIdlNode *)l->data;
1760 if (member->type == G_IDL_NODE_FUNCTION)
1762 blob->n_methods++;
1763 g_idl_node_build_metadata (member, module, modules, strings,
1764 types, data, offset, offset2);
1768 *offset = ALIGN_VALUE (*offset, 4);
1769 for (l = object->members; l; l = l->next)
1771 GIdlNode *member = (GIdlNode *)l->data;
1773 if (member->type == G_IDL_NODE_SIGNAL)
1775 blob->n_signals++;
1776 g_idl_node_build_metadata (member, module, modules, strings,
1777 types, data, offset, offset2);
1781 *offset = ALIGN_VALUE (*offset, 4);
1782 for (l = object->members; l; l = l->next)
1784 GIdlNode *member = (GIdlNode *)l->data;
1786 if (member->type == G_IDL_NODE_VFUNC)
1788 blob->n_vfuncs++;
1789 g_idl_node_build_metadata (member, module, modules, strings,
1790 types, data, offset, offset2);
1794 *offset = ALIGN_VALUE (*offset, 4);
1795 for (l = object->members; l; l = l->next)
1797 GIdlNode *member = (GIdlNode *)l->data;
1799 if (member->type == G_IDL_NODE_CONSTANT)
1801 blob->n_constants++;
1802 g_idl_node_build_metadata (member, module, modules, strings,
1803 types, data, offset, offset2);
1807 break;
1809 case G_IDL_NODE_INTERFACE:
1811 InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
1812 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
1814 blob->blob_type = BLOB_TYPE_INTERFACE;
1815 blob->deprecated = iface->deprecated;
1816 blob->reserved = 0;
1817 blob->name = write_string (node->name, strings, data, offset2);
1818 blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
1819 blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
1820 blob->n_prerequisites = 0;
1821 blob->n_properties = 0;
1822 blob->n_methods = 0;
1823 blob->n_signals = 0;
1824 blob->n_vfuncs = 0;
1825 blob->n_constants = 0;
1827 *offset += 28;
1828 for (l = iface->prerequisites; l; l = l->next)
1830 blob->n_prerequisites++;
1831 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1832 *offset += 2;
1835 *offset = ALIGN_VALUE (*offset, 4);
1836 for (l = iface->members; l; l = l->next)
1838 GIdlNode *member = (GIdlNode *)l->data;
1840 if (member->type == G_IDL_NODE_PROPERTY)
1842 blob->n_properties++;
1843 g_idl_node_build_metadata (member, module, modules, strings,
1844 types, data, offset, offset2);
1848 *offset = ALIGN_VALUE (*offset, 4);
1849 for (l = iface->members; l; l = l->next)
1851 GIdlNode *member = (GIdlNode *)l->data;
1853 if (member->type == G_IDL_NODE_FUNCTION)
1855 blob->n_methods++;
1856 g_idl_node_build_metadata (member, module, modules, strings,
1857 types, data, offset, offset2);
1861 *offset = ALIGN_VALUE (*offset, 4);
1862 for (l = iface->members; l; l = l->next)
1864 GIdlNode *member = (GIdlNode *)l->data;
1866 if (member->type == G_IDL_NODE_SIGNAL)
1868 blob->n_signals++;
1869 g_idl_node_build_metadata (member, module, modules, strings,
1870 types, data, offset, offset2);
1874 *offset = ALIGN_VALUE (*offset, 4);
1875 for (l = iface->members; l; l = l->next)
1877 GIdlNode *member = (GIdlNode *)l->data;
1879 if (member->type == G_IDL_NODE_VFUNC)
1881 blob->n_vfuncs++;
1882 g_idl_node_build_metadata (member, module, modules, strings,
1883 types, data, offset, offset2);
1887 *offset = ALIGN_VALUE (*offset, 4);
1888 for (l = iface->members; l; l = l->next)
1890 GIdlNode *member = (GIdlNode *)l->data;
1892 if (member->type == G_IDL_NODE_CONSTANT)
1894 blob->n_constants++;
1895 g_idl_node_build_metadata (member, module, modules, strings,
1896 types, data, offset, offset2);
1900 break;
1903 case G_IDL_NODE_VALUE:
1905 GIdlNodeValue *value = (GIdlNodeValue *)node;
1906 ValueBlob *blob = (ValueBlob *)&data[*offset];
1907 *offset += 12;
1909 blob->deprecated = value->deprecated;
1910 blob->reserved = 0;
1911 blob->name = write_string (node->name, strings, data, offset2);
1912 blob->value = value->value;
1914 break;
1916 case G_IDL_NODE_ERROR_DOMAIN:
1918 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
1919 ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
1920 *offset += 16;
1922 blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
1923 blob->deprecated = domain->deprecated;
1924 blob->reserved = 0;
1925 blob->name = write_string (node->name, strings, data, offset2);
1926 blob->get_quark = write_string (domain->getquark, strings, data, offset2);
1927 blob->error_codes = find_entry (module, modules, domain->codes);
1928 blob->reserved2 = 0;
1930 break;
1932 case G_IDL_NODE_CONSTANT:
1934 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
1935 ConstantBlob *blob = (ConstantBlob *)&data[*offset];
1936 guint32 pos;
1938 pos = *offset + 8;
1939 *offset += 20;
1941 blob->blob_type = BLOB_TYPE_CONSTANT;
1942 blob->deprecated = constant->deprecated;
1943 blob->reserved = 0;
1944 blob->name = write_string (node->name, strings, data, offset2);
1946 blob->offset = *offset2;
1947 switch (constant->type->tag)
1949 case TYPE_TAG_BOOLEAN:
1950 blob->size = 4;
1951 *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
1952 break;
1953 case TYPE_TAG_INT8:
1954 blob->size = 1;
1955 *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
1956 break;
1957 case TYPE_TAG_UINT8:
1958 blob->size = 1;
1959 *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
1960 break;
1961 case TYPE_TAG_INT16:
1962 blob->size = 2;
1963 *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
1964 break;
1965 case TYPE_TAG_UINT16:
1966 blob->size = 2;
1967 *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
1968 break;
1969 case TYPE_TAG_INT32:
1970 blob->size = 4;
1971 *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
1972 break;
1973 case TYPE_TAG_UINT32:
1974 blob->size = 4;
1975 *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
1976 break;
1977 case TYPE_TAG_INT64:
1978 blob->size = 8;
1979 *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
1980 break;
1981 case TYPE_TAG_UINT64:
1982 blob->size = 8;
1983 *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
1984 break;
1985 case TYPE_TAG_INT:
1986 blob->size = sizeof (gint);
1987 *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
1988 break;
1989 case TYPE_TAG_UINT:
1990 blob->size = sizeof (guint);
1991 *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
1992 break;
1993 case TYPE_TAG_SSIZE: /* FIXME */
1994 case TYPE_TAG_LONG:
1995 blob->size = sizeof (glong);
1996 *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
1997 break;
1998 case TYPE_TAG_SIZE: /* FIXME */
1999 case TYPE_TAG_ULONG:
2000 blob->size = sizeof (gulong);
2001 *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
2002 break;
2003 case TYPE_TAG_FLOAT:
2004 blob->size = sizeof (gfloat);
2005 *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
2006 break;
2007 case TYPE_TAG_DOUBLE:
2008 blob->size = sizeof (gdouble);
2009 *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
2010 break;
2011 case TYPE_TAG_UTF8:
2012 case TYPE_TAG_FILENAME:
2013 blob->size = strlen (constant->value) + 1;
2014 memcpy (&data[blob->offset], constant->value, blob->size);
2015 break;
2017 *offset2 += ALIGN_VALUE (blob->size, 4);
2019 g_idl_node_build_metadata ((GIdlNode *)constant->type, module, modules,
2020 strings, types, data, &pos, offset2);
2022 break;
2023 default:
2024 g_assert_not_reached ();
2027 g_debug ("node %p type %d, offset %d -> %d, offset2 %d -> %d",
2028 node, node->type, old_offset, *offset, old_offset2, *offset2);
2030 if (*offset2 - old_offset2 + *offset - old_offset > g_idl_node_get_full_size (node))
2031 g_error ("exceeding space reservation !!");
2034 /* if str is already in the pool, return previous location, otherwise write str
2035 * to the metadata at offset, put it in the pool and update offset. If the
2036 * metadata is not large enough to hold the string, reallocate it.
2038 guint32
2039 write_string (const gchar *str,
2040 GHashTable *strings,
2041 guchar *data,
2042 guint32 *offset)
2044 gpointer value;
2045 guint32 start;
2047 string_count += 1;
2048 string_size += strlen (str);
2050 value = g_hash_table_lookup (strings, str);
2052 if (value)
2053 return GPOINTER_TO_INT (value);
2055 unique_string_count += 1;
2056 unique_string_size += strlen (str);
2058 g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
2060 start = *offset;
2061 *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
2063 strcpy ((gchar*)&data[start], str);
2065 return start;