remove obsolete ref modifier and callback keyword
[vala-lang.git] / gobject-introspection / gidlnode.c
blobbbde2a0058e05c74ad9d9f46b104eb85cb6c0ea6
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 <string.h>
24 #include "gidlmodule.h"
25 #include "gidlnode.h"
26 #include "gmetadata.h"
28 static gulong string_count = 0;
29 static gulong unique_string_count = 0;
30 static gulong string_size = 0;
31 static gulong unique_string_size = 0;
32 static gulong types_count = 0;
33 static gulong unique_types_count = 0;
35 void
36 init_stats (void)
38 string_count = 0;
39 unique_string_count = 0;
40 string_size = 0;
41 unique_string_size = 0;
42 types_count = 0;
43 unique_types_count = 0;
46 void
47 dump_stats (void)
49 g_message ("%d strings (%d before sharing), %d bytes (%d before sharing)",
50 unique_string_count, string_count, unique_string_size, string_size);
51 g_message ("%d types (%d before sharing)", unique_types_count, types_count);
54 #define ALIGN_VALUE(this, boundary) \
55 (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
58 GIdlNode *
59 g_idl_node_new (GIdlNodeTypeId type)
61 GIdlNode *node = NULL;
63 switch (type)
65 case G_IDL_NODE_FUNCTION:
66 node = g_malloc0 (sizeof (GIdlNodeFunction));
67 break;
69 case G_IDL_NODE_PARAM:
70 node = g_malloc0 (sizeof (GIdlNodeParam));
71 break;
73 case G_IDL_NODE_TYPE:
74 node = g_malloc0 (sizeof (GIdlNodeType));
75 break;
77 case G_IDL_NODE_OBJECT:
78 case G_IDL_NODE_INTERFACE:
79 node = g_malloc0 (sizeof (GIdlNodeInterface));
80 break;
82 case G_IDL_NODE_SIGNAL:
83 node = g_malloc0 (sizeof (GIdlNodeSignal));
84 break;
86 case G_IDL_NODE_PROPERTY:
87 node = g_malloc0 (sizeof (GIdlNodeProperty));
88 break;
90 case G_IDL_NODE_VFUNC:
91 node = g_malloc0 (sizeof (GIdlNodeFunction));
92 break;
94 case G_IDL_NODE_FIELD:
95 node = g_malloc0 (sizeof (GIdlNodeField));
96 break;
98 case G_IDL_NODE_ENUM:
99 case G_IDL_NODE_FLAGS:
100 node = g_malloc0 (sizeof (GIdlNodeEnum));
101 break;
103 case G_IDL_NODE_BOXED:
104 node = g_malloc0 (sizeof (GIdlNodeBoxed));
105 break;
107 case G_IDL_NODE_STRUCT:
108 node = g_malloc0 (sizeof (GIdlNodeStruct));
109 break;
111 case G_IDL_NODE_VALUE:
112 node = g_malloc0 (sizeof (GIdlNodeValue));
113 break;
115 case G_IDL_NODE_CONSTANT:
116 node = g_malloc0 (sizeof (GIdlNodeConstant));
117 break;
119 case G_IDL_NODE_ERROR_DOMAIN:
120 node = g_malloc0 (sizeof (GIdlNodeErrorDomain));
121 break;
123 case G_IDL_NODE_XREF:
124 node = g_malloc0 (sizeof (GIdlNodeXRef));
125 break;
127 case G_IDL_NODE_UNION:
128 node = g_malloc0 (sizeof (GIdlNodeUnion));
129 break;
131 default:
132 g_error ("Unhandled node type %d\n", type);
133 break;
136 node->type = type;
138 return node;
141 void
142 g_idl_node_free (GIdlNode *node)
144 GList *l;
146 if (node == NULL)
147 return;
149 switch (node->type)
151 case G_IDL_NODE_FUNCTION:
152 case G_IDL_NODE_CALLBACK:
154 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
156 g_free (node->name);
157 g_free (function->symbol);
158 g_idl_node_free ((GIdlNode *)function->result);
159 for (l = function->parameters; l; l = l->next)
160 g_idl_node_free ((GIdlNode *)l->data);
161 g_list_free (function->parameters);
163 break;
165 case G_IDL_NODE_TYPE:
167 GIdlNodeType *type = (GIdlNodeType *)node;
169 g_free (node->name);
170 g_idl_node_free ((GIdlNode *)type->parameter_type1);
171 g_idl_node_free ((GIdlNode *)type->parameter_type2);
173 g_free (type->interface);
174 g_strfreev (type->errors);
177 break;
179 case G_IDL_NODE_PARAM:
181 GIdlNodeParam *param = (GIdlNodeParam *)node;
183 g_free (node->name);
184 g_idl_node_free ((GIdlNode *)param->type);
186 break;
188 case G_IDL_NODE_PROPERTY:
190 GIdlNodeProperty *property = (GIdlNodeProperty *)node;
192 g_free (node->name);
193 g_idl_node_free ((GIdlNode *)property->type);
195 break;
197 case G_IDL_NODE_SIGNAL:
199 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
201 g_free (node->name);
202 for (l = signal->parameters; l; l = l->next)
203 g_idl_node_free ((GIdlNode *)l->data);
204 g_list_free (signal->parameters);
205 g_idl_node_free ((GIdlNode *)signal->result);
207 break;
209 case G_IDL_NODE_VFUNC:
211 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
213 g_free (node->name);
214 for (l = vfunc->parameters; l; l = l->next)
215 g_idl_node_free ((GIdlNode *)l->data);
216 g_list_free (vfunc->parameters);
217 g_idl_node_free ((GIdlNode *)vfunc->result);
219 break;
221 case G_IDL_NODE_FIELD:
223 GIdlNodeField *field = (GIdlNodeField *)node;
225 g_free (node->name);
226 g_idl_node_free ((GIdlNode *)field->type);
228 break;
230 case G_IDL_NODE_OBJECT:
231 case G_IDL_NODE_INTERFACE:
233 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
235 g_free (node->name);
236 g_free (iface->gtype_name);
237 g_free (iface->gtype_init);
239 g_free (iface->parent);
241 for (l = iface->interfaces; l; l = l->next)
242 g_free ((GIdlNode *)l->data);
243 g_list_free (iface->interfaces);
245 for (l = iface->members; l; l = l->next)
246 g_idl_node_free ((GIdlNode *)l->data);
247 g_list_free (iface->members);
250 break;
252 case G_IDL_NODE_VALUE:
254 GIdlNodeValue *value = (GIdlNodeValue *)node;
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 %d 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 GIdlNodeValue *value = (GIdlNodeValue *)node;
638 size = 12;
639 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
641 break;
643 case G_IDL_NODE_STRUCT:
645 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
647 size = 20;
648 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
649 for (l = struct_->members; l; l = l->next)
650 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
652 break;
654 case G_IDL_NODE_BOXED:
656 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
658 size = 20;
659 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
660 if (boxed->gtype_name)
662 size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
663 size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
665 for (l = boxed->members; l; l = l->next)
666 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
668 break;
670 case G_IDL_NODE_PROPERTY:
672 GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
674 size = 12;
675 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
676 size += g_idl_node_get_full_size ((GIdlNode *)prop->type);
678 break;
680 case G_IDL_NODE_SIGNAL:
682 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
684 size = 12;
685 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
686 for (l = signal->parameters; l; l = l->next)
687 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
688 size += g_idl_node_get_full_size ((GIdlNode *)signal->result);
690 break;
692 case G_IDL_NODE_VFUNC:
694 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
696 size = 16;
697 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
698 for (l = vfunc->parameters; l; l = l->next)
699 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
700 size += g_idl_node_get_full_size ((GIdlNode *)vfunc->result);
702 break;
704 case G_IDL_NODE_FIELD:
706 GIdlNodeField *field = (GIdlNodeField *)node;
708 size = 12;
709 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
710 size += g_idl_node_get_full_size ((GIdlNode *)field->type);
712 break;
714 case G_IDL_NODE_CONSTANT:
716 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
718 size = 20;
719 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
720 /* FIXME non-string values */
721 size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
722 size += g_idl_node_get_full_size ((GIdlNode *)constant->type);
724 break;
726 case G_IDL_NODE_ERROR_DOMAIN:
728 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
730 size = 16;
731 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
732 size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
734 break;
736 case G_IDL_NODE_XREF:
738 GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
740 size = 0;
741 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
742 size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
744 break;
746 case G_IDL_NODE_UNION:
748 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
750 size = 28;
751 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
752 for (l = union_->members; l; l = l->next)
753 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
754 for (l = union_->discriminators; l; l = l->next)
755 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
757 break;
759 default:
760 g_error ("Unknown type tag %d\n", node->type);
761 size = 0;
764 g_debug ("node %d type %d full size %d", node, node->type, size);
766 return size;
769 static gint64
770 parse_int_value (const gchar *str)
772 return strtoll (str, NULL, 0);
775 static guint64
776 parse_uint_value (const gchar *str)
778 return strtoull (str, NULL, 0);
781 static gdouble
782 parse_float_value (const gchar *str)
784 return strtod (str, NULL);
787 static gboolean
788 parse_boolean_value (const gchar *str)
790 if (strcmp (str, "TRUE") == 0)
791 return TRUE;
793 if (strcmp (str, "FALSE") == 0)
794 return FALSE;
796 return parse_int_value (str) ? TRUE : FALSE;
799 static GIdlNode *
800 find_entry_node (GIdlModule *module,
801 GList *modules,
802 const gchar *name,
803 guint16 *idx)
806 GList *l;
807 gint i;
808 gchar **names;
809 gint n_names;
810 GIdlNode *result = NULL;
812 names = g_strsplit (name, ".", 0);
813 n_names = g_strv_length (names);
814 if (n_names > 2)
815 g_error ("Too many name parts");
817 for (l = module->entries, i = 1; l; l = l->next, i++)
819 GIdlNode *node = (GIdlNode *)l->data;
821 if (n_names > 1)
823 if (node->type != G_IDL_NODE_XREF)
824 continue;
826 if (((GIdlNodeXRef *)node)->namespace == NULL ||
827 strcmp (((GIdlNodeXRef *)node)->namespace, names[0]) != 0)
828 continue;
831 if (strcmp (node->name, names[n_names - 1]) == 0)
833 if (idx)
834 *idx = i;
836 result = node;
837 goto out;
841 if (n_names > 1)
843 GIdlNode *node = g_idl_node_new (G_IDL_NODE_XREF);
845 ((GIdlNodeXRef *)node)->namespace = g_strdup (names[0]);
846 node->name = g_strdup (names[1]);
848 module->entries = g_list_append (module->entries, node);
850 if (idx)
851 *idx = g_list_length (module->entries);
853 result = node;
855 goto out;
858 g_warning ("Entry %s not found", name);
860 out:
862 g_strfreev (names);
864 return result;
867 static guint16
868 find_entry (GIdlModule *module,
869 GList *modules,
870 const gchar *name)
872 guint16 idx = 0;
874 find_entry_node (module, modules, name, &idx);
876 return idx;
879 static void
880 serialize_type (GIdlModule *module,
881 GList *modules,
882 GIdlNodeType *node,
883 GString *str)
885 gint i;
886 const gchar* basic[] = {
887 "void",
888 "gboolean",
889 "gint8",
890 "guint8",
891 "gint16",
892 "guint16",
893 "gint32",
894 "guint32",
895 "gint64",
896 "guint64",
897 "gint",
898 "guint",
899 "glong",
900 "gulong",
901 "gssize",
902 "gsize",
903 "gfloat",
904 "gdouble",
905 "utf8",
906 "filename"
909 if (node->tag < 20)
911 g_string_append_printf (str, "%s%s",
912 basic[node->tag], node->is_pointer ? "*" : "");
914 else if (node->tag == 20)
916 serialize_type (module, modules, node->parameter_type1, str);
917 g_string_append (str, "[");
919 if (node->has_length)
920 g_string_append_printf (str, "length=%d", node->length);
922 if (node->zero_terminated)
923 g_string_append_printf (str, "%szero-terminated=1",
924 node->has_length ? "," : "");
926 g_string_append (str, "]");
928 else if (node->tag == 21)
930 GIdlNode *iface;
931 gchar *name;
933 iface = find_entry_node (module, modules, node->interface, NULL);
934 if (iface)
935 name = iface->name;
936 else
938 g_warning ("Interface for type reference %s not found", node->interface);
939 name = node->interface;
942 g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : "");
944 else if (node->tag == 22)
946 g_string_append (str, "GList");
947 if (node->parameter_type1)
949 g_string_append (str, "<");
950 serialize_type (module, modules, node->parameter_type1, str);
951 g_string_append (str, ">");
954 else if (node->tag == 23)
956 g_string_append (str, "GSList");
957 if (node->parameter_type1)
959 g_string_append (str, "<");
960 serialize_type (module, modules, node->parameter_type1, str);
961 g_string_append (str, ">");
964 else if (node->tag == 24)
966 g_string_append (str, "GHashTable<");
967 if (node->parameter_type1)
969 g_string_append (str, "<");
970 serialize_type (module, modules, node->parameter_type1, str);
971 g_string_append (str, ",");
972 serialize_type (module, modules, node->parameter_type2, str);
973 g_string_append (str, ">");
976 else if (node->tag == 25)
978 g_string_append (str, "GError");
979 if (node->errors)
981 g_string_append (str, "<");
982 for (i = 0; node->errors[i]; i++)
984 if (i > 0)
985 g_string_append (str, ",");
986 g_string_append (str, node->errors[i]);
988 g_string_append (str, ">");
993 void
994 g_idl_node_build_metadata (GIdlNode *node,
995 GIdlModule *module,
996 GList *modules,
997 GHashTable *strings,
998 GHashTable *types,
999 guchar *data,
1000 guint32 *offset,
1001 guint32 *offset2)
1003 GList *l;
1004 guint32 old_offset = *offset;
1005 guint32 old_offset2 = *offset2;
1007 switch (node->type)
1009 case G_IDL_NODE_TYPE:
1011 GIdlNodeType *type = (GIdlNodeType *)node;
1012 SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
1014 *offset += 4;
1016 if (type->tag < TYPE_TAG_ARRAY)
1018 blob->reserved = 0;
1019 blob->reserved2 = 0;
1020 blob->pointer = type->is_pointer;
1021 blob->reserved3 = 0;
1022 blob->tag = type->tag;
1024 else
1026 GString *str;
1027 gchar *s;
1028 gpointer value;
1030 str = g_string_new (0);
1031 serialize_type (module, modules, type, str);
1032 s = g_string_free (str, FALSE);
1034 types_count += 1;
1035 value = g_hash_table_lookup (types, s);
1036 if (value)
1038 blob->offset = GPOINTER_TO_INT (value);
1039 g_free (s);
1041 else
1043 unique_types_count += 1;
1044 g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
1046 blob->offset = *offset2;
1047 switch (type->tag)
1049 case TYPE_TAG_ARRAY:
1051 ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
1052 guint32 pos;
1054 array->pointer = 1;
1055 array->reserved = 0;
1056 array->tag = type->tag;
1057 array->zero_terminated = type->zero_terminated;
1058 array->has_length = type->has_length;
1059 array->reserved2 = 0;
1060 array->length = type->length;
1062 pos = *offset2 + 4;
1063 *offset2 += 8;
1065 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1066 module, modules, strings, types,
1067 data, &pos, offset2);
1069 break;
1071 case TYPE_TAG_INTERFACE:
1073 InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
1074 *offset2 += 4;
1076 iface->pointer = type->is_pointer;
1077 iface->reserved = 0;
1078 iface->tag = type->tag;
1079 iface->reserved2 = 0;
1080 iface->interface = find_entry (module, modules, type->interface);
1083 break;
1085 case TYPE_TAG_LIST:
1086 case TYPE_TAG_SLIST:
1088 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1089 guint32 pos;
1091 param->pointer = 1;
1092 param->reserved = 0;
1093 param->tag = type->tag;
1094 param->reserved2 = 0;
1095 param->n_types = 1;
1097 pos = *offset2 + 4;
1098 *offset2 += 8;
1100 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1101 module, modules, strings, types,
1102 data, &pos, offset2);
1104 break;
1106 case TYPE_TAG_HASH:
1108 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1109 guint32 pos;
1111 param->pointer = 1;
1112 param->reserved = 0;
1113 param->tag = type->tag;
1114 param->reserved2 = 0;
1115 param->n_types = 2;
1117 pos = *offset2 + 4;
1118 *offset2 += 12;
1120 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1121 module, modules, strings, types,
1122 data, &pos, offset2);
1123 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type2,
1124 module, modules, strings, types,
1125 data, &pos, offset2);
1127 break;
1129 case TYPE_TAG_ERROR:
1131 ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
1132 gint i, domain;
1134 blob->pointer = 1;
1135 blob->reserved = 0;
1136 blob->tag = type->tag;
1137 blob->reserved2 = 0;
1138 if (type->errors)
1139 blob->n_domains = g_strv_length (type->errors);
1140 else
1141 blob->n_domains = 0;
1143 *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4);
1144 for (i = 0; i < blob->n_domains; i++)
1145 blob->domains[i] = find_entry (module, modules, type->errors[i]);
1147 break;
1149 default:
1150 g_error ("Unknown type tag %d\n", type->tag);
1151 break;
1156 break;
1158 case G_IDL_NODE_FIELD:
1160 GIdlNodeField *field = (GIdlNodeField *)node;
1161 FieldBlob *blob;
1163 blob = (FieldBlob *)&data[*offset];
1164 *offset += 8;
1166 blob->name = write_string (node->name, strings, data, offset2);
1167 blob->readable = field->readable;
1168 blob->writable = field->writable;
1169 blob->reserved = 0;
1170 blob->bits = 0;
1171 blob->struct_offset = field->offset;
1173 g_idl_node_build_metadata ((GIdlNode *)field->type,
1174 module, modules, strings, types,
1175 data, offset, offset2);
1177 break;
1179 case G_IDL_NODE_PROPERTY:
1181 GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
1182 PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1183 *offset += 8;
1185 blob->name = write_string (node->name, strings, data, offset2);
1186 blob->deprecated = prop->deprecated;
1187 blob->readable = prop->readable;
1188 blob->writable = prop->writable;
1189 blob->construct = prop->construct;
1190 blob->construct_only = prop->construct_only;
1191 blob->reserved = 0;
1193 g_idl_node_build_metadata ((GIdlNode *)prop->type,
1194 module, modules, strings, types,
1195 data, offset, offset2);
1197 break;
1199 case G_IDL_NODE_FUNCTION:
1201 FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1202 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1203 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1204 guint32 signature, res;
1205 gint n;
1207 signature = *offset2;
1208 n = g_list_length (function->parameters);
1210 *offset += 16;
1211 *offset2 += 8 + n * 12;
1213 blob->blob_type = BLOB_TYPE_FUNCTION;
1214 blob->deprecated = function->deprecated;
1215 blob->setter = function->is_setter;
1216 blob->getter = function->is_getter;
1217 blob->constructor = function->is_constructor;
1218 blob->wraps_vfunc = function->wraps_vfunc;
1219 blob->reserved = 0;
1220 blob->index = 0;
1221 blob->name = write_string (node->name, strings, data, offset2);
1222 blob->symbol = write_string (function->symbol, strings, data, offset2);
1223 blob->signature = signature;
1225 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1226 module, modules, strings, types,
1227 data, &signature, offset2);
1229 blob2->may_return_null = function->result->null_ok;
1230 blob2->caller_owns_return_value = function->result->transfer;
1231 blob2->caller_owns_return_container = function->result->shallow_transfer;
1232 blob2->reserved = 0;
1233 blob2->n_arguments = n;
1235 signature += 4;
1237 for (l = function->parameters; l; l = l->next)
1239 GIdlNode *param = (GIdlNode *)l->data;
1241 g_idl_node_build_metadata (param,
1242 module, modules, strings, types,
1243 data, &signature, offset2);
1246 break;
1248 case G_IDL_NODE_CALLBACK:
1250 CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1251 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1252 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1253 guint32 signature, res;
1254 gint n;
1256 signature = *offset2;
1257 n = g_list_length (function->parameters);
1259 *offset += 12;
1260 *offset2 += 8 + n * 12;
1262 blob->blob_type = BLOB_TYPE_CALLBACK;
1263 blob->deprecated = function->deprecated;
1264 blob->reserved = 0;
1265 blob->name = write_string (node->name, strings, data, offset2);
1266 blob->signature = signature;
1268 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1269 module, modules, strings, types,
1270 data, &signature, offset2);
1272 blob2->may_return_null = function->result->null_ok;
1273 blob2->caller_owns_return_value = function->result->transfer;
1274 blob2->caller_owns_return_container = function->result->shallow_transfer;
1275 blob2->reserved = 0;
1276 blob2->n_arguments = n;
1278 signature += 4;
1280 for (l = function->parameters; l; l = l->next)
1282 GIdlNode *param = (GIdlNode *)l->data;
1284 g_idl_node_build_metadata (param,
1285 module, modules, strings, types,
1286 data, &signature, offset2);
1289 break;
1291 case G_IDL_NODE_SIGNAL:
1293 SignalBlob *blob = (SignalBlob *)&data[*offset];
1294 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1295 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
1296 guint32 signature, res;
1297 gint n;
1299 signature = *offset2;
1300 n = g_list_length (signal->parameters);
1302 *offset += 12;
1303 *offset2 += 8 + n * 12;
1305 blob->deprecated = signal->deprecated;
1306 blob->run_first = signal->run_first;
1307 blob->run_last = signal->run_last;
1308 blob->run_cleanup = signal->run_cleanup;
1309 blob->no_recurse = signal->no_recurse;
1310 blob->detailed = signal->detailed;
1311 blob->action = signal->action;
1312 blob->no_hooks = signal->no_hooks;
1313 blob->has_class_closure = 0; /* FIXME */
1314 blob->true_stops_emit = 0; /* FIXME */
1315 blob->reserved = 0;
1316 blob->class_closure = 0; /* FIXME */
1317 blob->name = write_string (node->name, strings, data, offset2);
1318 blob->signature = signature;
1320 g_idl_node_build_metadata ((GIdlNode *)signal->result->type,
1321 module, modules, strings, types,
1322 data, &signature, offset2);
1324 blob2->may_return_null = signal->result->null_ok;
1325 blob2->caller_owns_return_value = signal->result->transfer;
1326 blob2->caller_owns_return_container = signal->result->shallow_transfer;
1327 blob2->reserved = 0;
1328 blob2->n_arguments = n;
1330 signature += 4;
1332 for (l = signal->parameters; l; l = l->next)
1334 GIdlNode *param = (GIdlNode *)l->data;
1336 g_idl_node_build_metadata (param, module, modules, strings, types,
1337 data, &signature, offset2);
1340 break;
1342 case G_IDL_NODE_VFUNC:
1344 VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1345 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1346 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
1347 guint32 signature, res;
1348 gint n;
1350 signature = *offset2;
1351 n = g_list_length (vfunc->parameters);
1353 *offset += 16;
1354 *offset2 += 8 + n * 12;
1356 blob->name = write_string (node->name, strings, data, offset2);
1357 blob->must_chain_up = 0; /* FIXME */
1358 blob->must_be_implemented = 0; /* FIXME */
1359 blob->must_not_be_implemented = 0; /* FIXME */
1360 blob->class_closure = 0; /* FIXME */
1361 blob->reserved = 0;
1363 blob->struct_offset = vfunc->offset;
1364 blob->reserved2 = 0;
1365 blob->signature = signature;
1367 g_idl_node_build_metadata ((GIdlNode *)vfunc->result->type,
1368 module, modules, strings, types,
1369 data, &signature, offset2);
1371 blob2->may_return_null = vfunc->result->null_ok;
1372 blob2->caller_owns_return_value = vfunc->result->transfer;
1373 blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1374 blob2->reserved = 0;
1375 blob2->n_arguments = n;
1377 signature += 4;
1379 for (l = vfunc->parameters; l; l = l->next)
1381 GIdlNode *param = (GIdlNode *)l->data;
1383 g_idl_node_build_metadata (param, module, modules, strings,
1384 types, data, &signature, offset2);
1387 break;
1389 case G_IDL_NODE_PARAM:
1391 ArgBlob *blob = (ArgBlob *)&data[*offset];
1392 GIdlNodeParam *param = (GIdlNodeParam *)node;
1393 guint32 res;
1395 *offset += 8;
1397 blob->name = write_string (node->name, strings, data, offset2);
1398 blob->in = param->in;
1399 blob->out = param->out;
1400 blob->dipper = param->dipper;
1401 blob->null_ok = param->null_ok;
1402 blob->optional = param->optional;
1403 blob->transfer_ownership = param->transfer;
1404 blob->transfer_container_ownership = param->shallow_transfer;
1405 blob->return_value = param->retval;
1406 blob->reserved = 0;
1408 g_idl_node_build_metadata ((GIdlNode *)param->type, module, modules,
1409 strings, types, data, offset, offset2);
1411 break;
1413 case G_IDL_NODE_STRUCT:
1415 StructBlob *blob = (StructBlob *)&data[*offset];
1416 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
1417 guint32 pos;
1419 blob->blob_type = BLOB_TYPE_STRUCT;
1420 blob->deprecated = struct_->deprecated;
1421 blob->unregistered = TRUE;
1422 blob->reserved = 0;
1423 blob->name = write_string (node->name, strings, data, offset2);
1424 blob->gtype_name = 0;
1425 blob->gtype_init = 0;
1427 blob->n_fields = 0;
1428 blob->n_methods = 0;
1430 *offset += 20;
1431 for (l = struct_->members; l; l = l->next)
1433 GIdlNode *member = (GIdlNode *)l->data;
1435 if (member->type == G_IDL_NODE_FIELD)
1437 blob->n_fields++;
1438 g_idl_node_build_metadata (member, module, modules, strings,
1439 types, data, offset, offset2);
1443 for (l = struct_->members; l; l = l->next)
1445 GIdlNode *member = (GIdlNode *)l->data;
1447 if (member->type == G_IDL_NODE_FUNCTION)
1449 blob->n_methods++;
1450 g_idl_node_build_metadata (member, module, modules, strings,
1451 types, data, offset, offset2);
1455 break;
1457 case G_IDL_NODE_BOXED:
1459 StructBlob *blob = (StructBlob *)&data[*offset];
1460 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
1462 blob->blob_type = BLOB_TYPE_BOXED;
1463 blob->deprecated = boxed->deprecated;
1464 blob->unregistered = FALSE;
1465 blob->reserved = 0;
1466 blob->name = write_string (node->name, strings, data, offset2);
1467 blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
1468 blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
1470 blob->n_fields = 0;
1471 blob->n_methods = 0;
1473 *offset += 20;
1474 for (l = boxed->members; l; l = l->next)
1476 GIdlNode *member = (GIdlNode *)l->data;
1478 if (member->type == G_IDL_NODE_FIELD)
1480 blob->n_fields++;
1481 g_idl_node_build_metadata (member, module, modules, strings,
1482 types, data, offset, offset2);
1486 for (l = boxed->members; l; l = l->next)
1488 GIdlNode *member = (GIdlNode *)l->data;
1490 if (member->type == G_IDL_NODE_FUNCTION)
1492 blob->n_methods++;
1493 g_idl_node_build_metadata (member, module, modules, strings,
1494 types, data, offset, offset2);
1498 break;
1500 case G_IDL_NODE_UNION:
1502 UnionBlob *blob = (UnionBlob *)&data[*offset];
1503 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
1505 blob->blob_type = BLOB_TYPE_UNION;
1506 blob->deprecated = union_->deprecated;
1507 blob->reserved = 0;
1508 blob->name = write_string (node->name, strings, data, offset2);
1509 if (union_->gtype_name)
1511 blob->unregistered = FALSE;
1512 blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2);
1513 blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2);
1515 else
1517 blob->unregistered = TRUE;
1518 blob->gtype_name = 0;
1519 blob->gtype_init = 0;
1522 blob->n_fields = 0;
1523 blob->n_functions = 0;
1525 blob->discriminator_offset = union_->discriminator_offset;
1527 if (union_->discriminator_type)
1529 *offset += 24;
1530 blob->discriminated = TRUE;
1531 g_idl_node_build_metadata ((GIdlNode *)union_->discriminator_type,
1532 module, modules, strings, types,
1533 data, offset, offset2);
1535 else
1537 *offset += 28;
1538 blob->discriminated = FALSE;
1539 blob->discriminator_type.offset = 0;
1543 for (l = union_->members; l; l = l->next)
1545 GIdlNode *member = (GIdlNode *)l->data;
1547 if (member->type == G_IDL_NODE_FIELD)
1549 blob->n_fields++;
1550 g_idl_node_build_metadata (member, module, modules, strings,
1551 types, data, offset, offset2);
1555 for (l = union_->members; l; l = l->next)
1557 GIdlNode *member = (GIdlNode *)l->data;
1559 if (member->type == G_IDL_NODE_FUNCTION)
1561 blob->n_functions++;
1562 g_idl_node_build_metadata (member, module, modules, strings,
1563 types, data, offset, offset2);
1567 if (union_->discriminator_type)
1569 for (l = union_->discriminators; l; l = l->next)
1571 GIdlNode *member = (GIdlNode *)l->data;
1573 g_idl_node_build_metadata (member, module, modules, strings,
1574 types, data, offset, offset2);
1578 break;
1580 case G_IDL_NODE_ENUM:
1581 case G_IDL_NODE_FLAGS:
1583 EnumBlob *blob = (EnumBlob *)&data[*offset];
1584 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
1586 *offset += 20;
1588 if (node->type == G_IDL_NODE_ENUM)
1589 blob->blob_type = BLOB_TYPE_ENUM;
1590 else
1591 blob->blob_type = BLOB_TYPE_FLAGS;
1593 blob->deprecated = enum_->deprecated;
1594 blob->reserved = 0;
1595 blob->name = write_string (node->name, strings, data, offset2);
1596 if (enum_->gtype_name)
1598 blob->unregistered = FALSE;
1599 blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2);
1600 blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2);
1602 else
1604 blob->unregistered = TRUE;
1605 blob->gtype_name = 0;
1606 blob->gtype_init = 0;
1609 blob->n_values = 0;
1610 blob->reserved2 = 0;
1612 for (l = enum_->values; l; l = l->next)
1614 GIdlNode *value = (GIdlNode *)l->data;
1616 blob->n_values++;
1617 g_idl_node_build_metadata (value, module, modules, strings, types,
1618 data, offset, offset2);
1621 break;
1623 case G_IDL_NODE_OBJECT:
1625 ObjectBlob *blob = (ObjectBlob *)&data[*offset];
1626 GIdlNodeInterface *object = (GIdlNodeInterface *)node;
1627 gint parent;
1629 blob->blob_type = BLOB_TYPE_OBJECT;
1630 blob->deprecated = object->deprecated;
1631 blob->reserved = 0;
1632 blob->name = write_string (node->name, strings, data, offset2);
1633 blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
1634 blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
1635 if (object->parent)
1636 blob->parent = find_entry (module, modules, object->parent);
1637 else
1638 blob->parent = 0;
1640 blob->n_interfaces = 0;
1641 blob->n_fields = 0;
1642 blob->n_properties = 0;
1643 blob->n_methods = 0;
1644 blob->n_signals = 0;
1645 blob->n_vfuncs = 0;
1646 blob->n_constants = 0;
1648 *offset += 32;
1649 for (l = object->interfaces; l; l = l->next)
1651 blob->n_interfaces++;
1652 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1653 *offset += 2;
1656 *offset = ALIGN_VALUE (*offset, 4);
1657 for (l = object->members; l; l = l->next)
1659 GIdlNode *member = (GIdlNode *)l->data;
1661 if (member->type == G_IDL_NODE_FIELD)
1663 blob->n_fields++;
1664 g_idl_node_build_metadata (member, module, modules, strings,
1665 types, data, offset, offset2);
1669 *offset = ALIGN_VALUE (*offset, 4);
1670 for (l = object->members; l; l = l->next)
1672 GIdlNode *member = (GIdlNode *)l->data;
1674 if (member->type == G_IDL_NODE_PROPERTY)
1676 blob->n_properties++;
1677 g_idl_node_build_metadata (member, module, modules, strings,
1678 types, data, offset, offset2);
1682 *offset = ALIGN_VALUE (*offset, 4);
1683 for (l = object->members; l; l = l->next)
1685 GIdlNode *member = (GIdlNode *)l->data;
1687 if (member->type == G_IDL_NODE_FUNCTION)
1689 blob->n_methods++;
1690 g_idl_node_build_metadata (member, module, modules, strings,
1691 types, data, offset, offset2);
1695 *offset = ALIGN_VALUE (*offset, 4);
1696 for (l = object->members; l; l = l->next)
1698 GIdlNode *member = (GIdlNode *)l->data;
1700 if (member->type == G_IDL_NODE_SIGNAL)
1702 blob->n_signals++;
1703 g_idl_node_build_metadata (member, module, modules, strings,
1704 types, data, offset, offset2);
1708 *offset = ALIGN_VALUE (*offset, 4);
1709 for (l = object->members; l; l = l->next)
1711 GIdlNode *member = (GIdlNode *)l->data;
1713 if (member->type == G_IDL_NODE_VFUNC)
1715 blob->n_vfuncs++;
1716 g_idl_node_build_metadata (member, module, modules, strings,
1717 types, data, offset, offset2);
1721 *offset = ALIGN_VALUE (*offset, 4);
1722 for (l = object->members; l; l = l->next)
1724 GIdlNode *member = (GIdlNode *)l->data;
1726 if (member->type == G_IDL_NODE_CONSTANT)
1728 blob->n_constants++;
1729 g_idl_node_build_metadata (member, module, modules, strings,
1730 types, data, offset, offset2);
1734 break;
1736 case G_IDL_NODE_INTERFACE:
1738 InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
1739 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
1741 blob->blob_type = BLOB_TYPE_INTERFACE;
1742 blob->deprecated = iface->deprecated;
1743 blob->reserved = 0;
1744 blob->name = write_string (node->name, strings, data, offset2);
1745 blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
1746 blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
1747 blob->n_prerequisites = 0;
1748 blob->n_properties = 0;
1749 blob->n_methods = 0;
1750 blob->n_signals = 0;
1751 blob->n_vfuncs = 0;
1752 blob->n_constants = 0;
1754 *offset += 28;
1755 for (l = iface->prerequisites; l; l = l->next)
1757 blob->n_prerequisites++;
1758 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1759 *offset += 2;
1762 *offset = ALIGN_VALUE (*offset, 4);
1763 for (l = iface->members; l; l = l->next)
1765 GIdlNode *member = (GIdlNode *)l->data;
1767 if (member->type == G_IDL_NODE_PROPERTY)
1769 blob->n_properties++;
1770 g_idl_node_build_metadata (member, module, modules, strings,
1771 types, data, offset, offset2);
1775 *offset = ALIGN_VALUE (*offset, 4);
1776 for (l = iface->members; l; l = l->next)
1778 GIdlNode *member = (GIdlNode *)l->data;
1780 if (member->type == G_IDL_NODE_FUNCTION)
1782 blob->n_methods++;
1783 g_idl_node_build_metadata (member, module, modules, strings,
1784 types, data, offset, offset2);
1788 *offset = ALIGN_VALUE (*offset, 4);
1789 for (l = iface->members; l; l = l->next)
1791 GIdlNode *member = (GIdlNode *)l->data;
1793 if (member->type == G_IDL_NODE_SIGNAL)
1795 blob->n_signals++;
1796 g_idl_node_build_metadata (member, module, modules, strings,
1797 types, data, offset, offset2);
1801 *offset = ALIGN_VALUE (*offset, 4);
1802 for (l = iface->members; l; l = l->next)
1804 GIdlNode *member = (GIdlNode *)l->data;
1806 if (member->type == G_IDL_NODE_VFUNC)
1808 blob->n_vfuncs++;
1809 g_idl_node_build_metadata (member, module, modules, strings,
1810 types, data, offset, offset2);
1814 *offset = ALIGN_VALUE (*offset, 4);
1815 for (l = iface->members; l; l = l->next)
1817 GIdlNode *member = (GIdlNode *)l->data;
1819 if (member->type == G_IDL_NODE_CONSTANT)
1821 blob->n_constants++;
1822 g_idl_node_build_metadata (member, module, modules, strings,
1823 types, data, offset, offset2);
1827 break;
1830 case G_IDL_NODE_VALUE:
1832 GIdlNodeValue *value = (GIdlNodeValue *)node;
1833 ValueBlob *blob = (ValueBlob *)&data[*offset];
1834 *offset += 12;
1836 blob->deprecated = value->deprecated;
1837 blob->reserved = 0;
1838 blob->name = write_string (node->name, strings, data, offset2);
1839 blob->value = value->value;
1841 break;
1843 case G_IDL_NODE_ERROR_DOMAIN:
1845 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
1846 ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
1847 *offset += 16;
1849 blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
1850 blob->deprecated = domain->deprecated;
1851 blob->reserved = 0;
1852 blob->name = write_string (node->name, strings, data, offset2);
1853 blob->get_quark = write_string (domain->getquark, strings, data, offset2);
1854 blob->error_codes = find_entry (module, modules, domain->codes);
1855 blob->reserved2 = 0;
1857 break;
1859 case G_IDL_NODE_CONSTANT:
1861 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
1862 ConstantBlob *blob = (ConstantBlob *)&data[*offset];
1863 guint32 pos;
1865 pos = *offset + 8;
1866 *offset += 20;
1868 blob->blob_type = BLOB_TYPE_CONSTANT;
1869 blob->deprecated = constant->deprecated;
1870 blob->reserved = 0;
1871 blob->name = write_string (node->name, strings, data, offset2);
1873 blob->offset = *offset2;
1874 switch (constant->type->tag)
1876 case TYPE_TAG_BOOLEAN:
1877 blob->size = 4;
1878 *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
1879 break;
1880 case TYPE_TAG_INT8:
1881 blob->size = 1;
1882 *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
1883 break;
1884 case TYPE_TAG_UINT8:
1885 blob->size = 1;
1886 *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
1887 break;
1888 case TYPE_TAG_INT16:
1889 blob->size = 2;
1890 *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
1891 break;
1892 case TYPE_TAG_UINT16:
1893 blob->size = 2;
1894 *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
1895 break;
1896 case TYPE_TAG_INT32:
1897 blob->size = 4;
1898 *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
1899 break;
1900 case TYPE_TAG_UINT32:
1901 blob->size = 4;
1902 *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
1903 break;
1904 case TYPE_TAG_INT64:
1905 blob->size = 8;
1906 *(gint64*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
1907 break;
1908 case TYPE_TAG_UINT64:
1909 blob->size = 8;
1910 *(guint64*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
1911 break;
1912 case TYPE_TAG_INT:
1913 blob->size = sizeof (gint);
1914 *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
1915 break;
1916 case TYPE_TAG_UINT:
1917 blob->size = sizeof (guint);
1918 *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
1919 break;
1920 case TYPE_TAG_SSIZE: /* FIXME */
1921 case TYPE_TAG_LONG:
1922 blob->size = sizeof (glong);
1923 *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
1924 break;
1925 case TYPE_TAG_SIZE: /* FIXME */
1926 case TYPE_TAG_ULONG:
1927 blob->size = sizeof (gulong);
1928 *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
1929 break;
1930 case TYPE_TAG_FLOAT:
1931 blob->size = sizeof (gfloat);
1932 *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
1933 break;
1934 case TYPE_TAG_DOUBLE:
1935 blob->size = sizeof (gdouble);
1936 *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
1937 break;
1938 case TYPE_TAG_UTF8:
1939 case TYPE_TAG_FILENAME:
1940 blob->size = strlen (constant->value) + 1;
1941 memcpy (&data[blob->offset], constant->value, blob->size);
1942 break;
1944 *offset2 += ALIGN_VALUE (blob->size, 4);
1946 g_idl_node_build_metadata ((GIdlNode *)constant->type, module, modules,
1947 strings, types, data, &pos, offset2);
1949 break;
1952 g_debug ("node %p type %d, offset %d -> %d, offset2 %d -> %d",
1953 node, node->type, old_offset, *offset, old_offset2, *offset2);
1955 if (*offset2 - old_offset2 + *offset - old_offset > g_idl_node_get_full_size (node))
1956 g_error ("exceeding space reservation !!");
1959 /* if str is already in the pool, return previous location, otherwise write str
1960 * to the metadata at offset, put it in the pool and update offset. If the
1961 * metadata is not large enough to hold the string, reallocate it.
1963 guint32
1964 write_string (const gchar *str,
1965 GHashTable *strings,
1966 guchar *data,
1967 guint32 *offset)
1969 gpointer value;
1970 guint32 start;
1972 string_count += 1;
1973 string_size += strlen (str);
1975 value = g_hash_table_lookup (strings, str);
1977 if (value)
1978 return GPOINTER_TO_INT (value);
1980 unique_string_count += 1;
1981 unique_string_size += strlen (str);
1983 g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
1985 start = *offset;
1986 *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
1988 strcpy ((gchar*)&data[start], str);
1990 return start;