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.
24 #include "gidlmodule.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;
39 unique_string_count = 0;
41 unique_string_size = 0;
43 unique_types_count = 0;
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);
55 #define ALIGN_VALUE(this, boundary) \
56 (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
60 g_idl_node_new (GIdlNodeTypeId type)
62 GIdlNode *node = NULL;
66 case G_IDL_NODE_FUNCTION:
67 node = g_malloc0 (sizeof (GIdlNodeFunction));
70 case G_IDL_NODE_PARAM:
71 node = g_malloc0 (sizeof (GIdlNodeParam));
75 node = g_malloc0 (sizeof (GIdlNodeType));
78 case G_IDL_NODE_OBJECT:
79 case G_IDL_NODE_INTERFACE:
80 node = g_malloc0 (sizeof (GIdlNodeInterface));
83 case G_IDL_NODE_SIGNAL:
84 node = g_malloc0 (sizeof (GIdlNodeSignal));
87 case G_IDL_NODE_PROPERTY:
88 node = g_malloc0 (sizeof (GIdlNodeProperty));
91 case G_IDL_NODE_VFUNC:
92 node = g_malloc0 (sizeof (GIdlNodeFunction));
95 case G_IDL_NODE_FIELD:
96 node = g_malloc0 (sizeof (GIdlNodeField));
100 case G_IDL_NODE_FLAGS:
101 node = g_malloc0 (sizeof (GIdlNodeEnum));
104 case G_IDL_NODE_BOXED:
105 node = g_malloc0 (sizeof (GIdlNodeBoxed));
108 case G_IDL_NODE_STRUCT:
109 node = g_malloc0 (sizeof (GIdlNodeStruct));
112 case G_IDL_NODE_VALUE:
113 node = g_malloc0 (sizeof (GIdlNodeValue));
116 case G_IDL_NODE_CONSTANT:
117 node = g_malloc0 (sizeof (GIdlNodeConstant));
120 case G_IDL_NODE_ERROR_DOMAIN:
121 node = g_malloc0 (sizeof (GIdlNodeErrorDomain));
124 case G_IDL_NODE_XREF:
125 node = g_malloc0 (sizeof (GIdlNodeXRef));
128 case G_IDL_NODE_UNION:
129 node = g_malloc0 (sizeof (GIdlNodeUnion));
133 g_error ("Unhandled node type %d\n", type);
143 g_idl_node_free (GIdlNode *node)
152 case G_IDL_NODE_FUNCTION:
153 case G_IDL_NODE_CALLBACK:
155 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
158 g_free (function->symbol);
159 g_idl_node_free ((GIdlNode *)function->result);
160 for (l = function->parameters; l; l = l->next)
161 g_idl_node_free ((GIdlNode *)l->data);
162 g_list_free (function->parameters);
166 case G_IDL_NODE_TYPE:
168 GIdlNodeType *type = (GIdlNodeType *)node;
171 g_idl_node_free ((GIdlNode *)type->parameter_type1);
172 g_idl_node_free ((GIdlNode *)type->parameter_type2);
174 g_free (type->interface);
175 g_strfreev (type->errors);
180 case G_IDL_NODE_PARAM:
182 GIdlNodeParam *param = (GIdlNodeParam *)node;
185 g_idl_node_free ((GIdlNode *)param->type);
189 case G_IDL_NODE_PROPERTY:
191 GIdlNodeProperty *property = (GIdlNodeProperty *)node;
194 g_idl_node_free ((GIdlNode *)property->type);
198 case G_IDL_NODE_SIGNAL:
200 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
203 for (l = signal->parameters; l; l = l->next)
204 g_idl_node_free ((GIdlNode *)l->data);
205 g_list_free (signal->parameters);
206 g_idl_node_free ((GIdlNode *)signal->result);
210 case G_IDL_NODE_VFUNC:
212 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
215 for (l = vfunc->parameters; l; l = l->next)
216 g_idl_node_free ((GIdlNode *)l->data);
217 g_list_free (vfunc->parameters);
218 g_idl_node_free ((GIdlNode *)vfunc->result);
222 case G_IDL_NODE_FIELD:
224 GIdlNodeField *field = (GIdlNodeField *)node;
227 g_idl_node_free ((GIdlNode *)field->type);
231 case G_IDL_NODE_OBJECT:
232 case G_IDL_NODE_INTERFACE:
234 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
237 g_free (iface->gtype_name);
238 g_free (iface->gtype_init);
240 g_free (iface->parent);
242 for (l = iface->interfaces; l; l = l->next)
243 g_free ((GIdlNode *)l->data);
244 g_list_free (iface->interfaces);
246 for (l = iface->members; l; l = l->next)
247 g_idl_node_free ((GIdlNode *)l->data);
248 g_list_free (iface->members);
253 case G_IDL_NODE_VALUE:
255 GIdlNodeValue *value = (GIdlNodeValue *)node;
261 case G_IDL_NODE_ENUM:
262 case G_IDL_NODE_FLAGS:
264 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
267 g_free (enum_->gtype_name);
268 g_free (enum_->gtype_init);
270 for (l = enum_->values; l; l = l->next)
271 g_idl_node_free ((GIdlNode *)l->data);
272 g_list_free (enum_->values);
276 case G_IDL_NODE_BOXED:
278 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
281 g_free (boxed->gtype_name);
282 g_free (boxed->gtype_init);
284 for (l = boxed->members; l; l = l->next)
285 g_idl_node_free ((GIdlNode *)l->data);
286 g_list_free (boxed->members);
290 case G_IDL_NODE_STRUCT:
292 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
295 for (l = struct_->members; l; l = l->next)
296 g_idl_node_free ((GIdlNode *)l->data);
297 g_list_free (struct_->members);
301 case G_IDL_NODE_CONSTANT:
303 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
306 g_free (constant->value);
307 g_idl_node_free ((GIdlNode *)constant->type);
311 case G_IDL_NODE_ERROR_DOMAIN:
313 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
316 g_free (domain->getquark);
317 g_free (domain->codes);
321 case G_IDL_NODE_XREF:
323 GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
326 g_free (xref->namespace);
330 case G_IDL_NODE_UNION:
332 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
335 g_free (union_->gtype_name);
336 g_free (union_->gtype_init);
338 g_idl_node_free ((GIdlNode *)union_->discriminator_type);
339 for (l = union_->members; l; l = l->next)
340 g_idl_node_free ((GIdlNode *)l->data);
341 for (l = union_->discriminators; l; l = l->next)
342 g_idl_node_free ((GIdlNode *)l->data);
347 g_error ("Unhandled node type %d\n", node->type);
354 /* returns the fixed size of the blob */
356 g_idl_node_get_size (GIdlNode *node)
363 case G_IDL_NODE_CALLBACK:
367 case G_IDL_NODE_FUNCTION:
371 case G_IDL_NODE_PARAM:
375 case G_IDL_NODE_TYPE:
379 case G_IDL_NODE_OBJECT:
381 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
383 n = g_list_length (iface->interfaces);
384 size = 32 + 2 * (n + (n % 2));
386 for (l = iface->members; l; l = l->next)
387 size += g_idl_node_get_size ((GIdlNode *)l->data);
391 case G_IDL_NODE_INTERFACE:
393 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
395 n = g_list_length (iface->prerequisites);
396 size = 28 + 2 * (n + (n % 2));
398 for (l = iface->members; l; l = l->next)
399 size += g_idl_node_get_size ((GIdlNode *)l->data);
403 case G_IDL_NODE_ENUM:
404 case G_IDL_NODE_FLAGS:
406 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
408 n = g_list_length (enum_->values);
413 case G_IDL_NODE_VALUE:
417 case G_IDL_NODE_STRUCT:
419 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
422 for (l = struct_->members; l; l = l->next)
423 size += g_idl_node_get_size ((GIdlNode *)l->data);
427 case G_IDL_NODE_BOXED:
429 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
432 for (l = boxed->members; l; l = l->next)
433 size += g_idl_node_get_size ((GIdlNode *)l->data);
437 case G_IDL_NODE_PROPERTY:
441 case G_IDL_NODE_SIGNAL:
445 case G_IDL_NODE_VFUNC:
449 case G_IDL_NODE_FIELD:
453 case G_IDL_NODE_CONSTANT:
457 case G_IDL_NODE_ERROR_DOMAIN:
461 case G_IDL_NODE_XREF:
465 case G_IDL_NODE_UNION:
467 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
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);
478 g_error ("Unhandled node type %d\n", node->type);
482 g_debug ("node %d type %d size %d", node, node->type, size);
487 /* returns the full size of the blob including variable-size parts */
489 g_idl_node_get_full_size (GIdlNode *node)
494 g_assert (node != NULL);
498 case G_IDL_NODE_CALLBACK:
500 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
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);
509 case G_IDL_NODE_FUNCTION:
511 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
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);
521 case G_IDL_NODE_PARAM:
523 GIdlNodeParam *param = (GIdlNodeParam *)node;
527 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
528 size += g_idl_node_get_full_size ((GIdlNode *)param->type);
532 case G_IDL_NODE_TYPE:
534 GIdlNodeType *type = (GIdlNodeType *)node;
542 size = 4 + 4 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
549 size = 4 + 4 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
553 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1)
554 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type2);
558 gint n = g_strv_length (type->errors);
559 size = 4 + 4 + 2 * (n + n % 2);
563 g_error ("Unknown type tag %d\n", type->tag);
570 case G_IDL_NODE_OBJECT:
572 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
574 n = g_list_length (iface->interfaces);
577 size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
578 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
579 size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
580 size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
581 size += 2 * (n + (n % 2));
583 for (l = iface->members; l; l = l->next)
584 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
588 case G_IDL_NODE_INTERFACE:
590 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
592 n = g_list_length (iface->prerequisites);
594 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
595 size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
596 size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
597 size += 2 * (n + (n % 2));
599 for (l = iface->members; l; l = l->next)
600 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
604 case G_IDL_NODE_ENUM:
605 case G_IDL_NODE_FLAGS:
607 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
610 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
611 if (enum_->gtype_name)
613 size += ALIGN_VALUE (strlen (enum_->gtype_name) + 1, 4);
614 size += ALIGN_VALUE (strlen (enum_->gtype_init) + 1, 4);
617 for (l = enum_->values; l; l = l->next)
618 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
622 case G_IDL_NODE_VALUE:
624 GIdlNodeValue *value = (GIdlNodeValue *)node;
627 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
631 case G_IDL_NODE_STRUCT:
633 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
636 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
637 for (l = struct_->members; l; l = l->next)
638 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
642 case G_IDL_NODE_BOXED:
644 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
647 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
648 if (boxed->gtype_name)
650 size += ALIGN_VALUE (strlen (boxed->gtype_name) + 1, 4);
651 size += ALIGN_VALUE (strlen (boxed->gtype_init) + 1, 4);
653 for (l = boxed->members; l; l = l->next)
654 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
658 case G_IDL_NODE_PROPERTY:
660 GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
663 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
664 size += g_idl_node_get_full_size ((GIdlNode *)prop->type);
668 case G_IDL_NODE_SIGNAL:
670 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
673 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
674 for (l = signal->parameters; l; l = l->next)
675 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
676 size += g_idl_node_get_full_size ((GIdlNode *)signal->result);
680 case G_IDL_NODE_VFUNC:
682 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
685 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
686 for (l = vfunc->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 *)vfunc->result);
692 case G_IDL_NODE_FIELD:
694 GIdlNodeField *field = (GIdlNodeField *)node;
697 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
698 size += g_idl_node_get_full_size ((GIdlNode *)field->type);
702 case G_IDL_NODE_CONSTANT:
704 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
707 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
708 /* FIXME non-string values */
709 size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
710 size += g_idl_node_get_full_size ((GIdlNode *)constant->type);
714 case G_IDL_NODE_ERROR_DOMAIN:
716 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
719 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
720 size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
724 case G_IDL_NODE_XREF:
726 GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
729 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
730 size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
734 case G_IDL_NODE_UNION:
736 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
739 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
740 for (l = union_->members; l; l = l->next)
741 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
742 for (l = union_->discriminators; l; l = l->next)
743 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
748 g_error ("Unknown type tag %d\n", node->type);
752 g_debug ("node %d type %d full size %d", node, node->type, size);
758 parse_int_value (const gchar *str)
760 return strtoll (str, NULL, 0);
764 parse_uint_value (const gchar *str)
766 return strtoull (str, NULL, 0);
770 parse_float_value (const gchar *str)
772 return strtod (str, NULL);
776 parse_boolean_value (const gchar *str)
778 if (strcmp (str, "TRUE") == 0)
781 if (strcmp (str, "FALSE") == 0)
784 return parse_int_value (str) ? TRUE : FALSE;
788 find_entry_node (GIdlModule *module,
798 GIdlNode *result = NULL;
800 names = g_strsplit (name, ".", 0);
801 n_names = g_strv_length (names);
803 g_error ("Too many name parts");
805 for (l = module->entries, i = 0; l; l = l->next, i++)
807 GIdlNode *node = (GIdlNode *)l->data;
811 if (node->type != G_IDL_NODE_XREF)
814 if (((GIdlNodeXRef *)node)->namespace == NULL ||
815 strcmp (((GIdlNodeXRef *)node)->namespace, names[0]) != 0)
819 if (strcmp (node->name, names[n_names - 1]) == 0)
831 GIdlNode *node = g_idl_node_new (G_IDL_NODE_XREF);
833 ((GIdlNodeXRef *)node)->namespace = g_strdup (names[0]);
834 node->name = g_strdup (names[1]);
836 module->entries = g_list_append (module->entries, node);
839 *idx = g_list_length (module->entries) - 1;
846 g_warning ("Entry %s not found", name);
856 find_entry (GIdlModule *module,
862 find_entry_node (module, modules, name, &idx);
868 serialize_type (GIdlModule *module,
875 const gchar* basic[] = {
898 g_string_append_printf (str, "%s%s",
899 basic[node->tag], node->is_pointer ? "*" : "");
901 else if (node->tag == 20)
903 serialize_type (module, modules, node->parameter_type1, str);
904 g_string_append (str, "[");
906 if (node->has_length)
907 g_string_append_printf (str, "length=%d", node->length);
909 if (node->zero_terminated)
910 g_string_append_printf (str, "%szero-terminated=1",
911 node->has_length ? "," : "");
913 g_string_append (str, "]");
915 else if (node->tag == 21)
920 iface = find_entry_node (module, modules, node->interface, NULL);
925 g_warning ("Interface for type reference %s not found", node->interface);
926 name = node->interface;
929 g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : "");
931 else if (node->tag == 22)
933 g_string_append (str, "GList<");
934 serialize_type (module, modules, node->parameter_type1, str);
935 g_string_append (str, ">");
937 else if (node->tag == 23)
939 g_string_append (str, "GSList<");
940 serialize_type (module, modules, node->parameter_type1, str);
941 g_string_append (str, ">");
943 else if (node->tag == 24)
945 g_string_append (str, "GHashTable<");
946 serialize_type (module, modules, node->parameter_type1, str);
947 g_string_append (str, ",");
948 serialize_type (module, modules, node->parameter_type2, str);
949 g_string_append (str, ">");
951 else if (node->tag == 25)
953 g_string_append (str, "GError<");
954 for (i = 0; node->errors[i]; i++)
957 g_string_append (str, ",");
958 g_string_append (str, node->errors[i]);
960 g_string_append (str, ">");
965 g_idl_node_build_metadata (GIdlNode *node,
975 guint32 old_offset = *offset;
976 guint32 old_offset2 = *offset2;
980 case G_IDL_NODE_TYPE:
982 GIdlNodeType *type = (GIdlNodeType *)node;
983 SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
991 blob->pointer = type->is_pointer;
993 blob->tag = type->tag;
1001 str = g_string_new (0);
1002 serialize_type (module, modules, type, str);
1003 s = g_string_free (str, FALSE);
1006 value = g_hash_table_lookup (types, s);
1009 blob->offset = GPOINTER_TO_INT (value);
1014 unique_types_count += 1;
1015 g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
1017 blob->offset = *offset2;
1022 ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
1026 array->reserved = 0;
1027 array->tag = type->tag;
1028 array->zero_terminated = type->zero_terminated;
1029 array->has_length = type->has_length;
1030 array->reserved2 = 0;
1031 array->length = type->length;
1036 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1037 module, modules, strings, types,
1038 data, &pos, offset2);
1044 InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
1048 iface->reserved = 0;
1049 iface->tag = type->tag;
1050 iface->reserved2 = 0;
1051 iface->interface = find_entry (module, modules, type->interface);
1058 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1062 param->reserved = 0;
1063 param->tag = type->tag;
1064 param->reserved2 = 0;
1070 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1071 module, modules, strings, types,
1072 data, &pos, offset2);
1078 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
1082 param->reserved = 0;
1083 param->tag = type->tag;
1084 param->reserved2 = 0;
1090 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
1091 module, modules, strings, types,
1092 data, &pos, offset2);
1093 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type2,
1094 module, modules, strings, types,
1095 data, &pos, offset2);
1101 ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
1106 blob->tag = type->tag;
1107 blob->reserved2 = 0;
1108 blob->n_domains = g_strv_length (type->errors);
1110 *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4);
1111 for (i = 0; type->errors[i]; i++)
1112 blob->domains[i] = find_entry (module, modules, type->errors[i]);
1117 g_error ("Unknown type tag %d\n", type->tag);
1125 case G_IDL_NODE_FIELD:
1127 GIdlNodeField *field = (GIdlNodeField *)node;
1130 blob = (FieldBlob *)&data[*offset];
1133 blob->name = write_string (node->name, strings, data, offset2);
1134 blob->readable = field->readable;
1135 blob->writable = field->writable;
1138 blob->struct_offset = 0;
1140 g_idl_node_build_metadata ((GIdlNode *)field->type,
1141 module, modules, strings, types,
1142 data, offset, offset2);
1146 case G_IDL_NODE_PROPERTY:
1148 GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
1149 PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1152 blob->name = write_string (node->name, strings, data, offset2);
1153 blob->deprecated = prop->deprecated;
1154 blob->readable = prop->readable;
1155 blob->writable = prop->writable;
1156 blob->construct = prop->construct;
1157 blob->construct_only = prop->construct_only;
1160 g_idl_node_build_metadata ((GIdlNode *)prop->type,
1161 module, modules, strings, types,
1162 data, offset, offset2);
1166 case G_IDL_NODE_FUNCTION:
1168 FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1169 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1170 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1171 guint32 signature, res;
1174 signature = *offset2;
1175 n = g_list_length (function->parameters);
1178 *offset2 += 8 + n * 12;
1180 blob->blob_type = BLOB_TYPE_FUNCTION;
1181 blob->deprecated = function->deprecated;
1182 blob->setter = function->is_setter;
1183 blob->getter = function->is_getter;
1184 blob->constructor = function->is_constructor;
1185 blob->wraps_vfunc = function->wraps_vfunc;
1188 blob->name = write_string (node->name, strings, data, offset2);
1189 blob->symbol = write_string (function->symbol, strings, data, offset2);
1190 blob->signature = signature;
1192 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1193 module, modules, strings, types,
1194 data, &signature, offset2);
1196 blob2->may_return_null = function->result->null_ok;
1197 blob2->caller_owns_return_value = function->result->transfer;
1198 blob2->caller_owns_return_container = function->result->shallow_transfer;
1199 blob2->reserved = 0;
1200 blob2->n_arguments = n;
1204 for (l = function->parameters; l; l = l->next)
1206 GIdlNode *param = (GIdlNode *)l->data;
1208 g_idl_node_build_metadata (param,
1209 module, modules, strings, types,
1210 data, &signature, offset2);
1215 case G_IDL_NODE_CALLBACK:
1217 CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1218 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1219 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1220 guint32 signature, res;
1223 signature = *offset2;
1224 n = g_list_length (function->parameters);
1227 *offset2 += 8 + n * 12;
1229 blob->blob_type = BLOB_TYPE_CALLBACK;
1230 blob->deprecated = function->deprecated;
1232 blob->name = write_string (node->name, strings, data, offset2);
1233 blob->signature = signature;
1235 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1236 module, modules, strings, types,
1237 data, &signature, offset2);
1239 blob2->may_return_null = function->result->null_ok;
1240 blob2->caller_owns_return_value = function->result->transfer;
1241 blob2->caller_owns_return_container = function->result->shallow_transfer;
1242 blob2->reserved = 0;
1243 blob2->n_arguments = n;
1247 for (l = function->parameters; l; l = l->next)
1249 GIdlNode *param = (GIdlNode *)l->data;
1251 g_idl_node_build_metadata (param,
1252 module, modules, strings, types,
1253 data, &signature, offset2);
1258 case G_IDL_NODE_SIGNAL:
1260 SignalBlob *blob = (SignalBlob *)&data[*offset];
1261 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1262 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
1263 guint32 signature, res;
1266 signature = *offset2;
1267 n = g_list_length (signal->parameters);
1270 *offset2 += 8 + n * 12;
1272 blob->deprecated = signal->deprecated;
1273 blob->run_first = signal->run_first;
1274 blob->run_last = signal->run_last;
1275 blob->run_cleanup = signal->run_cleanup;
1276 blob->no_recurse = signal->no_recurse;
1277 blob->detailed = signal->detailed;
1278 blob->action = signal->action;
1279 blob->no_hooks = signal->no_hooks;
1280 blob->has_class_closure = 0; /* FIXME */
1281 blob->true_stops_emit = 0; /* FIXME */
1283 blob->class_closure = 0; /* FIXME */
1284 blob->name = write_string (node->name, strings, data, offset2);
1285 blob->signature = signature;
1287 g_idl_node_build_metadata ((GIdlNode *)signal->result->type,
1288 module, modules, strings, types,
1289 data, &signature, offset2);
1291 blob2->may_return_null = signal->result->null_ok;
1292 blob2->caller_owns_return_value = signal->result->transfer;
1293 blob2->caller_owns_return_container = signal->result->shallow_transfer;
1294 blob2->reserved = 0;
1295 blob2->n_arguments = n;
1299 for (l = signal->parameters; l; l = l->next)
1301 GIdlNode *param = (GIdlNode *)l->data;
1303 g_idl_node_build_metadata (param, module, modules, strings, types,
1304 data, &signature, offset2);
1309 case G_IDL_NODE_VFUNC:
1311 VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1312 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1313 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
1314 guint32 signature, res;
1317 signature = *offset2;
1318 n = g_list_length (vfunc->parameters);
1321 *offset2 += 8 + n * 12;
1323 blob->name = write_string (node->name, strings, data, offset2);
1324 blob->must_chain_up = 0; /* FIXME */
1325 blob->must_be_implemented = 0; /* FIXME */
1326 blob->must_not_be_implemented = 0; /* FIXME */
1327 blob->class_closure = 0; /* FIXME */
1330 blob->struct_offset = 0; /* FIXME */
1331 blob->reserved2 = 0;
1332 blob->signature = signature;
1334 g_idl_node_build_metadata ((GIdlNode *)vfunc->result->type,
1335 module, modules, strings, types,
1336 data, &signature, offset2);
1338 blob2->may_return_null = vfunc->result->null_ok;
1339 blob2->caller_owns_return_value = vfunc->result->transfer;
1340 blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1341 blob2->reserved = 0;
1342 blob2->n_arguments = n;
1346 for (l = vfunc->parameters; l; l = l->next)
1348 GIdlNode *param = (GIdlNode *)l->data;
1350 g_idl_node_build_metadata (param, module, modules, strings,
1351 types, data, &signature, offset2);
1356 case G_IDL_NODE_PARAM:
1358 ArgBlob *blob = (ArgBlob *)&data[*offset];
1359 GIdlNodeParam *param = (GIdlNodeParam *)node;
1364 blob->name = write_string (node->name, strings, data, offset2);
1365 blob->in = param->in;
1366 blob->out = param->out;
1367 blob->dipper = param->dipper;
1368 blob->null_ok = param->null_ok;
1369 blob->optional = param->optional;
1370 blob->transfer_ownership = param->transfer;
1371 blob->transfer_container_ownership = param->shallow_transfer;
1372 blob->return_value = param->retval;
1375 g_idl_node_build_metadata ((GIdlNode *)param->type, module, modules,
1376 strings, types, data, offset, offset2);
1380 case G_IDL_NODE_STRUCT:
1382 StructBlob *blob = (StructBlob *)&data[*offset];
1383 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
1386 blob->blob_type = BLOB_TYPE_STRUCT;
1387 blob->deprecated = struct_->deprecated;
1388 blob->unregistered = TRUE;
1390 blob->name = write_string (node->name, strings, data, offset2);
1391 blob->gtype_name = 0;
1392 blob->gtype_init = 0;
1395 blob->n_methods = 0;
1398 for (l = struct_->members; l; l = l->next)
1400 GIdlNode *member = (GIdlNode *)l->data;
1402 if (member->type == G_IDL_NODE_FIELD)
1405 g_idl_node_build_metadata (member, module, modules, strings,
1406 types, data, offset, offset2);
1410 for (l = struct_->members; l; l = l->next)
1412 GIdlNode *member = (GIdlNode *)l->data;
1414 if (member->type == G_IDL_NODE_FUNCTION)
1417 g_idl_node_build_metadata (member, module, modules, strings,
1418 types, data, offset, offset2);
1424 case G_IDL_NODE_BOXED:
1426 StructBlob *blob = (StructBlob *)&data[*offset];
1427 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
1429 blob->blob_type = BLOB_TYPE_BOXED;
1430 blob->deprecated = boxed->deprecated;
1431 blob->unregistered = FALSE;
1433 blob->name = write_string (node->name, strings, data, offset2);
1434 blob->gtype_name = write_string (boxed->gtype_name, strings, data, offset2);
1435 blob->gtype_init = write_string (boxed->gtype_init, strings, data, offset2);
1438 blob->n_methods = 0;
1441 for (l = boxed->members; l; l = l->next)
1443 GIdlNode *member = (GIdlNode *)l->data;
1445 if (member->type == G_IDL_NODE_FIELD)
1448 g_idl_node_build_metadata (member, module, modules, strings,
1449 types, data, offset, offset2);
1453 for (l = boxed->members; l; l = l->next)
1455 GIdlNode *member = (GIdlNode *)l->data;
1457 if (member->type == G_IDL_NODE_FUNCTION)
1460 g_idl_node_build_metadata (member, module, modules, strings,
1461 types, data, offset, offset2);
1467 case G_IDL_NODE_UNION:
1469 UnionBlob *blob = (UnionBlob *)&data[*offset];
1470 GIdlNodeUnion *union_ = (GIdlNodeUnion *)node;
1472 blob->blob_type = BLOB_TYPE_UNION;
1473 blob->deprecated = union_->deprecated;
1475 blob->name = write_string (node->name, strings, data, offset2);
1476 if (union_->gtype_name)
1478 blob->unregistered = FALSE;
1479 blob->gtype_name = write_string (union_->gtype_name, strings, data, offset2);
1480 blob->gtype_init = write_string (union_->gtype_init, strings, data, offset2);
1484 blob->unregistered = TRUE;
1485 blob->gtype_name = 0;
1486 blob->gtype_init = 0;
1490 blob->n_functions = 0;
1492 blob->discriminator_offset = union_->discriminator_offset;
1494 if (union_->discriminator_type)
1497 blob->discriminated = TRUE;
1498 g_idl_node_build_metadata ((GIdlNode *)union_->discriminator_type,
1499 module, modules, strings, types,
1500 data, offset, offset2);
1505 blob->discriminated = FALSE;
1506 blob->discriminator_type.offset = 0;
1510 for (l = union_->members; l; l = l->next)
1512 GIdlNode *member = (GIdlNode *)l->data;
1514 if (member->type == G_IDL_NODE_FIELD)
1517 g_idl_node_build_metadata (member, module, modules, strings,
1518 types, data, offset, offset2);
1522 for (l = union_->members; l; l = l->next)
1524 GIdlNode *member = (GIdlNode *)l->data;
1526 if (member->type == G_IDL_NODE_FUNCTION)
1528 blob->n_functions++;
1529 g_idl_node_build_metadata (member, module, modules, strings,
1530 types, data, offset, offset2);
1534 if (union_->discriminator_type)
1536 for (l = union_->discriminators; l; l = l->next)
1538 GIdlNode *member = (GIdlNode *)l->data;
1540 g_idl_node_build_metadata (member, module, modules, strings,
1541 types, data, offset, offset2);
1547 case G_IDL_NODE_ENUM:
1548 case G_IDL_NODE_FLAGS:
1550 EnumBlob *blob = (EnumBlob *)&data[*offset];
1551 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
1555 if (node->type == G_IDL_NODE_ENUM)
1556 blob->blob_type = BLOB_TYPE_ENUM;
1558 blob->blob_type = BLOB_TYPE_FLAGS;
1560 blob->deprecated = enum_->deprecated;
1562 blob->name = write_string (node->name, strings, data, offset2);
1563 if (enum_->gtype_name)
1565 blob->unregistered = FALSE;
1566 blob->gtype_name = write_string (enum_->gtype_name, strings, data, offset2);
1567 blob->gtype_init = write_string (enum_->gtype_init, strings, data, offset2);
1571 blob->unregistered = TRUE;
1572 blob->gtype_name = 0;
1573 blob->gtype_init = 0;
1577 blob->reserved2 = 0;
1579 for (l = enum_->values; l; l = l->next)
1581 GIdlNode *value = (GIdlNode *)l->data;
1584 g_idl_node_build_metadata (value, module, modules, strings, types,
1585 data, offset, offset2);
1590 case G_IDL_NODE_OBJECT:
1592 ObjectBlob *blob = (ObjectBlob *)&data[*offset];
1593 GIdlNodeInterface *object = (GIdlNodeInterface *)node;
1596 blob->blob_type = BLOB_TYPE_OBJECT;
1597 blob->deprecated = object->deprecated;
1599 blob->name = write_string (node->name, strings, data, offset2);
1600 blob->gtype_name = write_string (object->gtype_name, strings, data, offset2);
1601 blob->gtype_init = write_string (object->gtype_init, strings, data, offset2);
1603 blob->parent = find_entry (module, modules, object->parent);
1607 blob->n_interfaces = 0;
1609 blob->n_properties = 0;
1610 blob->n_methods = 0;
1611 blob->n_signals = 0;
1613 blob->n_constants = 0;
1616 for (l = object->interfaces; l; l = l->next)
1618 blob->n_interfaces++;
1619 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1623 *offset = ALIGN_VALUE (*offset, 4);
1624 for (l = object->members; l; l = l->next)
1626 GIdlNode *member = (GIdlNode *)l->data;
1628 if (member->type == G_IDL_NODE_FIELD)
1631 g_idl_node_build_metadata (member, module, modules, strings,
1632 types, data, offset, offset2);
1636 *offset = ALIGN_VALUE (*offset, 4);
1637 for (l = object->members; l; l = l->next)
1639 GIdlNode *member = (GIdlNode *)l->data;
1641 if (member->type == G_IDL_NODE_PROPERTY)
1643 blob->n_properties++;
1644 g_idl_node_build_metadata (member, module, modules, strings,
1645 types, data, offset, offset2);
1649 *offset = ALIGN_VALUE (*offset, 4);
1650 for (l = object->members; l; l = l->next)
1652 GIdlNode *member = (GIdlNode *)l->data;
1654 if (member->type == G_IDL_NODE_FUNCTION)
1657 g_idl_node_build_metadata (member, module, modules, strings,
1658 types, data, offset, offset2);
1662 *offset = ALIGN_VALUE (*offset, 4);
1663 for (l = object->members; l; l = l->next)
1665 GIdlNode *member = (GIdlNode *)l->data;
1667 if (member->type == G_IDL_NODE_SIGNAL)
1670 g_idl_node_build_metadata (member, module, modules, strings,
1671 types, data, offset, offset2);
1675 *offset = ALIGN_VALUE (*offset, 4);
1676 for (l = object->members; l; l = l->next)
1678 GIdlNode *member = (GIdlNode *)l->data;
1680 if (member->type == G_IDL_NODE_VFUNC)
1683 g_idl_node_build_metadata (member, module, modules, strings,
1684 types, data, offset, offset2);
1688 *offset = ALIGN_VALUE (*offset, 4);
1689 for (l = object->members; l; l = l->next)
1691 GIdlNode *member = (GIdlNode *)l->data;
1693 if (member->type == G_IDL_NODE_CONSTANT)
1695 blob->n_constants++;
1696 g_idl_node_build_metadata (member, module, modules, strings,
1697 types, data, offset, offset2);
1703 case G_IDL_NODE_INTERFACE:
1705 InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
1706 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
1708 blob->blob_type = BLOB_TYPE_INTERFACE;
1709 blob->deprecated = iface->deprecated;
1711 blob->name = write_string (node->name, strings, data, offset2);
1712 blob->gtype_name = write_string (iface->gtype_name, strings, data, offset2);
1713 blob->gtype_init = write_string (iface->gtype_init, strings, data, offset2);
1714 blob->n_prerequisites = 0;
1715 blob->n_properties = 0;
1716 blob->n_methods = 0;
1717 blob->n_signals = 0;
1719 blob->n_constants = 0;
1722 for (l = iface->prerequisites; l; l = l->next)
1724 blob->n_prerequisites++;
1725 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1729 *offset = ALIGN_VALUE (*offset, 4);
1730 for (l = iface->members; l; l = l->next)
1732 GIdlNode *member = (GIdlNode *)l->data;
1734 if (member->type == G_IDL_NODE_PROPERTY)
1736 blob->n_properties++;
1737 g_idl_node_build_metadata (member, module, modules, strings,
1738 types, data, offset, offset2);
1742 *offset = ALIGN_VALUE (*offset, 4);
1743 for (l = iface->members; l; l = l->next)
1745 GIdlNode *member = (GIdlNode *)l->data;
1747 if (member->type == G_IDL_NODE_FUNCTION)
1750 g_idl_node_build_metadata (member, module, modules, strings,
1751 types, data, offset, offset2);
1755 *offset = ALIGN_VALUE (*offset, 4);
1756 for (l = iface->members; l; l = l->next)
1758 GIdlNode *member = (GIdlNode *)l->data;
1760 if (member->type == G_IDL_NODE_SIGNAL)
1763 g_idl_node_build_metadata (member, module, modules, strings,
1764 types, data, offset, offset2);
1768 *offset = ALIGN_VALUE (*offset, 4);
1769 for (l = iface->members; l; l = l->next)
1771 GIdlNode *member = (GIdlNode *)l->data;
1773 if (member->type == G_IDL_NODE_VFUNC)
1776 g_idl_node_build_metadata (member, module, modules, strings,
1777 types, data, offset, offset2);
1781 *offset = ALIGN_VALUE (*offset, 4);
1782 for (l = iface->members; l; l = l->next)
1784 GIdlNode *member = (GIdlNode *)l->data;
1786 if (member->type == G_IDL_NODE_CONSTANT)
1788 blob->n_constants++;
1789 g_idl_node_build_metadata (member, module, modules, strings,
1790 types, data, offset, offset2);
1797 case G_IDL_NODE_VALUE:
1799 GIdlNodeValue *value = (GIdlNodeValue *)node;
1800 ValueBlob *blob = (ValueBlob *)&data[*offset];
1803 blob->deprecated = value->deprecated;
1805 blob->name = write_string (node->name, strings, data, offset2);
1806 blob->value = value->value;
1810 case G_IDL_NODE_ERROR_DOMAIN:
1812 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
1813 ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
1816 blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
1817 blob->deprecated = domain->deprecated;
1819 blob->name = write_string (node->name, strings, data, offset2);
1820 blob->get_quark = write_string (domain->getquark, strings, data, offset2);
1821 blob->error_codes = find_entry (module, modules, domain->codes);
1822 blob->reserved2 = 0;
1826 case G_IDL_NODE_CONSTANT:
1828 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
1829 ConstantBlob *blob = (ConstantBlob *)&data[*offset];
1835 blob->blob_type = BLOB_TYPE_CONSTANT;
1836 blob->deprecated = constant->deprecated;
1838 blob->name = write_string (node->name, strings, data, offset2);
1840 blob->offset = *offset2;
1841 switch (constant->type->tag)
1845 *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
1849 *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
1853 *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
1857 *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
1861 *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
1865 *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
1869 *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
1873 *(gint32*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
1877 *(guint32*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
1880 blob->size = sizeof (gfloat);
1881 *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
1884 blob->size = sizeof (gdouble);
1885 *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
1888 blob->size = strlen (constant->value) + 1;
1889 memcpy (&data[blob->offset], constant->value, blob->size);
1892 blob->size = sizeof (gint);
1893 *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
1896 blob->size = sizeof (guint);
1897 *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
1900 blob->size = sizeof (glong);
1901 *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
1904 blob->size = sizeof (gulong);
1905 *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
1908 *offset2 += ALIGN_VALUE (blob->size, 4);
1910 g_idl_node_build_metadata ((GIdlNode *)constant->type, module, modules,
1911 strings, types, data, &pos, offset2);
1916 g_debug ("node %p type %d, offset %d -> %d, offset2 %d -> %d",
1917 node, node->type, old_offset, *offset, old_offset2, *offset2);
1919 if (*offset2 - old_offset2 + *offset - old_offset > g_idl_node_get_full_size (node))
1920 g_error ("exceeding space reservation !!");
1923 /* if str is already in the pool, return previous location, otherwise write str
1924 * to the metadata at offset, put it in the pool and update offset. If the
1925 * metadata is not large enough to hold the string, reallocate it.
1928 write_string (const gchar *str,
1929 GHashTable *strings,
1937 string_size += strlen (str);
1939 value = g_hash_table_lookup (strings, str);
1942 return GPOINTER_TO_INT (value);
1944 unique_string_count += 1;
1945 unique_string_size += strlen (str);
1947 g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
1950 *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
1952 strcpy ((gchar*)&data[start], str);