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.
23 #include "gidlmodule.h"
25 #include "gmetadata.h"
27 #define ALIGN_VALUE(this, boundary) \
28 (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
32 g_idl_node_new (GIdlNodeTypeId type)
34 GIdlNode *node = NULL;
38 case G_IDL_NODE_FUNCTION:
39 node = g_malloc0 (sizeof (GIdlNodeFunction));
42 case G_IDL_NODE_PARAM:
43 node = g_malloc0 (sizeof (GIdlNodeParam));
47 node = g_malloc0 (sizeof (GIdlNodeType));
50 case G_IDL_NODE_OBJECT:
51 case G_IDL_NODE_INTERFACE:
52 node = g_malloc0 (sizeof (GIdlNodeInterface));
55 case G_IDL_NODE_SIGNAL:
56 node = g_malloc0 (sizeof (GIdlNodeSignal));
59 case G_IDL_NODE_PROPERTY:
60 node = g_malloc0 (sizeof (GIdlNodeProperty));
63 case G_IDL_NODE_VFUNC:
64 node = g_malloc0 (sizeof (GIdlNodeFunction));
67 case G_IDL_NODE_FIELD:
68 node = g_malloc0 (sizeof (GIdlNodeField));
72 case G_IDL_NODE_FLAGS:
73 node = g_malloc0 (sizeof (GIdlNodeEnum));
76 case G_IDL_NODE_BOXED:
77 node = g_malloc0 (sizeof (GIdlNodeBoxed));
80 case G_IDL_NODE_STRUCT:
81 node = g_malloc0 (sizeof (GIdlNodeStruct));
84 case G_IDL_NODE_VALUE:
85 node = g_malloc0 (sizeof (GIdlNodeValue));
88 case G_IDL_NODE_CONSTANT:
89 node = g_malloc0 (sizeof (GIdlNodeConstant));
92 case G_IDL_NODE_ERROR_DOMAIN:
93 node = g_malloc0 (sizeof (GIdlNodeErrorDomain));
97 node = g_malloc0 (sizeof (GIdlNodeXRef));
101 g_error ("Unhandled node type %d\n", type);
111 g_idl_node_free (GIdlNode *node)
117 case G_IDL_NODE_FUNCTION:
119 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
122 g_free (function->c_name);
123 g_idl_node_free ((GIdlNode *)function->result);
124 for (l = function->parameters; l; l = l->next)
125 g_idl_node_free ((GIdlNode *)l->data);
126 g_list_free (function->parameters);
130 case G_IDL_NODE_TYPE:
132 GIdlNodeType *type = (GIdlNodeType *)node;
135 if (type->parameter_type1)
136 g_idl_node_free ((GIdlNode *)type->parameter_type1);
137 if (type->parameter_type2)
138 g_idl_node_free ((GIdlNode *)type->parameter_type2);
140 g_free (type->interface);
141 g_strfreev (type->errors);
146 case G_IDL_NODE_PARAM:
148 GIdlNodeParam *param = (GIdlNodeParam *)node;
151 g_idl_node_free ((GIdlNode *)param->type);
155 case G_IDL_NODE_PROPERTY:
157 GIdlNodeProperty *property = (GIdlNodeProperty *)node;
160 g_idl_node_free ((GIdlNode *)property->type);
164 case G_IDL_NODE_SIGNAL:
166 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
169 for (l = signal->parameters; l; l = l->next)
170 g_idl_node_free ((GIdlNode *)l->data);
171 g_list_free (signal->parameters);
172 g_idl_node_free ((GIdlNode *)signal->result);
176 case G_IDL_NODE_VFUNC:
178 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
181 for (l = vfunc->parameters; l; l = l->next)
182 g_idl_node_free ((GIdlNode *)l->data);
183 g_list_free (vfunc->parameters);
184 g_idl_node_free ((GIdlNode *)vfunc->result);
188 case G_IDL_NODE_FIELD:
190 GIdlNodeField *field = (GIdlNodeField *)node;
193 g_free (field->c_name);
194 g_idl_node_free ((GIdlNode *)field->type);
198 case G_IDL_NODE_OBJECT:
199 case G_IDL_NODE_INTERFACE:
201 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
204 g_free (iface->c_name);
205 g_free (iface->init_func);
207 g_free (iface->parent);
209 for (l = iface->interfaces; l; l = l->next)
210 g_free ((GIdlNode *)l->data);
211 g_list_free (iface->interfaces);
213 for (l = iface->members; l; l = l->next)
214 g_idl_node_free ((GIdlNode *)l->data);
215 g_list_free (iface->members);
220 case G_IDL_NODE_VALUE:
222 GIdlNodeValue *value = (GIdlNodeValue *)node;
225 g_free (value->c_name);
229 case G_IDL_NODE_ENUM:
230 case G_IDL_NODE_FLAGS:
232 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
235 for (l = enum_->values; l; l = l->next)
236 g_idl_node_free ((GIdlNode *)l->data);
237 g_list_free (enum_->values);
241 case G_IDL_NODE_BOXED:
243 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
246 g_free (boxed->c_name);
247 g_free (boxed->init_func);
249 for (l = boxed->members; l; l = l->next)
250 g_idl_node_free ((GIdlNode *)l->data);
251 g_list_free (boxed->members);
255 case G_IDL_NODE_STRUCT:
257 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
260 for (l = struct_->members; l; l = l->next)
261 g_idl_node_free ((GIdlNode *)l->data);
262 g_list_free (struct_->members);
266 case G_IDL_NODE_CONSTANT:
268 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
271 g_free (constant->value);
272 g_idl_node_free ((GIdlNode *)constant->type);
276 case G_IDL_NODE_ERROR_DOMAIN:
278 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
281 g_free (domain->getquark);
282 g_free (domain->codes);
286 case G_IDL_NODE_XREF:
288 GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
291 g_free (xref->namespace);
296 g_error ("Unhandled node type %d\n", node->type);
303 /* returns the fixed size of the blob */
305 g_idl_node_get_size (GIdlNode *node)
312 case G_IDL_NODE_CALLBACK:
316 case G_IDL_NODE_FUNCTION:
320 case G_IDL_NODE_PARAM:
324 case G_IDL_NODE_TYPE:
328 case G_IDL_NODE_OBJECT:
330 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
332 n = g_list_length (iface->interfaces);
333 size = 32 + 2 * (n + (n % 2));
335 for (l = iface->members; l; l = l->next)
336 size += g_idl_node_get_size ((GIdlNode *)l->data);
340 case G_IDL_NODE_INTERFACE:
342 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
344 n = g_list_length (iface->prerequisites);
345 size = 28 + 2 * (n + (n % 2));
347 for (l = iface->members; l; l = l->next)
348 size += g_idl_node_get_size ((GIdlNode *)l->data);
352 case G_IDL_NODE_ENUM:
353 case G_IDL_NODE_FLAGS:
355 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
357 n = g_list_length (enum_->values);
362 case G_IDL_NODE_VALUE:
366 case G_IDL_NODE_STRUCT:
367 case G_IDL_NODE_BOXED:
369 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
372 for (l = boxed->members; l; l = l->next)
373 size += g_idl_node_get_size ((GIdlNode *)l->data);
377 case G_IDL_NODE_PROPERTY:
381 case G_IDL_NODE_SIGNAL:
385 case G_IDL_NODE_VFUNC:
389 case G_IDL_NODE_FIELD:
393 case G_IDL_NODE_CONSTANT:
397 case G_IDL_NODE_ERROR_DOMAIN:
401 case G_IDL_NODE_XREF:
406 g_error ("Unhandled node type %d\n", node->type);
413 /* returns the full size of the blob including variable-size parts */
415 g_idl_node_get_full_size (GIdlNode *node)
422 case G_IDL_NODE_CALLBACK:
424 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
426 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
427 for (l = function->parameters; l; l = l->next)
428 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
429 size += g_idl_node_get_full_size ((GIdlNode *)function->result);
433 case G_IDL_NODE_FUNCTION:
435 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
437 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
438 size += ALIGN_VALUE (strlen (function->c_name) + 1, 4);
439 for (l = function->parameters; l; l = l->next)
440 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
441 size += g_idl_node_get_full_size ((GIdlNode *)function->result);
445 case G_IDL_NODE_PARAM:
447 GIdlNodeParam *param = (GIdlNodeParam *)node;
451 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
452 size += g_idl_node_get_full_size ((GIdlNode *)param->type);
456 case G_IDL_NODE_TYPE:
458 GIdlNodeType *type = (GIdlNodeType *)node;
466 size = 4 + 4 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
473 size = 4 + 4 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1);
477 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type1)
478 + g_idl_node_get_full_size ((GIdlNode *)type->parameter_type2);
482 gint n = g_strv_length (type->errors);
483 size = 4 + 4 + 2 * (n + n % 2);
487 g_error ("Unknown type tag %d\n", type->tag);
494 case G_IDL_NODE_OBJECT:
496 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
498 n = g_list_length (iface->interfaces);
500 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
501 size += ALIGN_VALUE (strlen (iface->c_name) + 1, 4);
502 size += ALIGN_VALUE (strlen (iface->init_func) + 1, 4);
503 size += 2 * (n + (n % 2));
505 for (l = iface->members; l; l = l->next)
506 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
510 case G_IDL_NODE_INTERFACE:
512 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
514 n = g_list_length (iface->prerequisites);
516 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
517 size += ALIGN_VALUE (strlen (iface->c_name) + 1, 4);
518 size += ALIGN_VALUE (strlen (iface->init_func) + 1, 4);
519 size += 2 * (n + (n % 2));
521 for (l = iface->members; l; l = l->next)
522 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
526 case G_IDL_NODE_ENUM:
527 case G_IDL_NODE_FLAGS:
529 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
532 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
533 size += ALIGN_VALUE (strlen (enum_->c_name) + 1, 4);
534 if (enum_->init_func)
535 size += ALIGN_VALUE (strlen (enum_->init_func) + 1, 4);
537 for (l = enum_->values; l; l = l->next)
538 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
542 case G_IDL_NODE_VALUE:
544 GIdlNodeValue *value = (GIdlNodeValue *)node;
547 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
548 size += ALIGN_VALUE (strlen (value->c_name) + 1, 4);
552 case G_IDL_NODE_STRUCT:
554 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
557 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
558 for (l = struct_->members; l; l = l->next)
559 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
563 case G_IDL_NODE_BOXED:
565 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
568 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
570 size += ALIGN_VALUE (strlen (boxed->c_name) + 1, 4);
571 if (boxed->init_func)
572 size += ALIGN_VALUE (strlen (boxed->init_func) + 1, 4);
573 for (l = boxed->members; l; l = l->next)
574 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
578 case G_IDL_NODE_PROPERTY:
580 GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
583 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
584 size += g_idl_node_get_full_size ((GIdlNode *)prop->type);
588 case G_IDL_NODE_SIGNAL:
590 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
593 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
594 for (l = signal->parameters; l; l = l->next)
595 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
596 size += g_idl_node_get_full_size ((GIdlNode *)signal->result);
600 case G_IDL_NODE_VFUNC:
602 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
605 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
606 for (l = vfunc->parameters; l; l = l->next)
607 size += g_idl_node_get_full_size ((GIdlNode *)l->data);
608 size += g_idl_node_get_full_size ((GIdlNode *)vfunc->result);
612 case G_IDL_NODE_FIELD:
614 GIdlNodeField *field = (GIdlNodeField *)node;
617 size += ALIGN_VALUE (strlen (field->c_name) + 1, 4);
618 size += g_idl_node_get_full_size ((GIdlNode *)field->type);
622 case G_IDL_NODE_CONSTANT:
624 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
627 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
628 /* FIXME non-string values */
629 size += ALIGN_VALUE (strlen (constant->value) + 1, 4);
630 size += g_idl_node_get_full_size ((GIdlNode *)constant->type);
634 case G_IDL_NODE_ERROR_DOMAIN:
636 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
639 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
640 size += ALIGN_VALUE (strlen (domain->getquark) + 1, 4);
644 case G_IDL_NODE_XREF:
646 GIdlNodeXRef *xref = (GIdlNodeXRef *)node;
649 size += ALIGN_VALUE (strlen (node->name) + 1, 4);
650 size += ALIGN_VALUE (strlen (xref->namespace) + 1, 4);
655 g_error ("Unknown type tag %d\n", node->type);
663 parse_int_value (const gchar *str)
665 return strtoll (str, NULL, 0);
669 parse_uint_value (const gchar *str)
671 return strtoull (str, NULL, 0);
675 parse_float_value (const gchar *str)
677 return strtod (str, NULL);
681 parse_boolean_value (const gchar *str)
683 if (strcmp (str, "TRUE") == 0)
686 if (strcmp (str, "FALSE") == 0)
689 return parse_int_value (str) ? TRUE : FALSE;
693 find_entry_node (GIdlModule *module,
701 for (l = module->entries, i = 0; l; l = l->next, i++)
703 GIdlNode *node = (GIdlNode *)l->data;
705 if (strcmp (node->name, name) == 0)
713 for (m = modules; m; m = m->next)
715 GIdlModule *foreign = (GIdlModule *)m->data;
717 if (foreign == module)
720 for (l = foreign->entries; l; l = l->next)
722 GIdlNode *node = (GIdlNode *)l->data;
724 if (node->type == G_IDL_NODE_XREF)
727 if (strcmp (node->name, name) == 0)
729 GIdlNode *xref = g_idl_node_new (G_IDL_NODE_XREF);
730 xref->name = g_strdup (name);
731 ((GIdlNodeXRef *)xref)->namespace = g_strdup (foreign->name);
733 module->entries = g_list_append (module->entries, xref);
736 *idx = g_list_length (module->entries) - 1;
743 g_warning ("No such entry: '%s'\n", name);
749 find_entry (GIdlModule *module,
755 find_entry_node (module, modules, name, &idx);
761 serialize_type (GIdlModule *module,
768 const gchar* basic[] = {
791 g_string_append_printf (str, "%s%s",
792 basic[node->tag], node->is_pointer ? "*" : "");
794 else if (node->tag == 20)
796 serialize_type (module, modules, node->parameter_type1, str);
797 g_string_append (str, "[");
799 if (node->has_length)
800 g_string_append_printf (str, "length=%d", node->length);
802 if (node->zero_terminated)
803 g_string_append_printf (str, "%szero-terminated=1",
804 node->has_length ? "," : "");
806 g_string_append (str, "]");
808 else if (node->tag == 21)
812 iface = find_entry_node (module, modules, node->interface, NULL);
813 g_string_append_printf (str, "%s%s",
814 iface->name, node->is_pointer ? "*" : "");
816 else if (node->tag == 22)
818 g_string_append (str, "GList<");
819 serialize_type (module, modules, node->parameter_type1, str);
820 g_string_append (str, ">");
822 else if (node->tag == 23)
824 g_string_append (str, "GSList<");
825 serialize_type (module, modules, node->parameter_type1, str);
826 g_string_append (str, ">");
828 else if (node->tag == 24)
830 g_string_append (str, "GHashTable<");
831 serialize_type (module, modules, node->parameter_type1, str);
832 g_string_append (str, ",");
833 serialize_type (module, modules, node->parameter_type2, str);
834 g_string_append (str, ">");
836 else if (node->tag == 25)
838 g_string_append (str, "GError<");
839 for (i = 0; node->errors[i]; i++)
842 g_string_append (str, ",");
843 g_string_append (str, node->errors[i]);
845 g_string_append (str, ">");
850 g_idl_node_build_metadata (GIdlNode *node,
863 case G_IDL_NODE_TYPE:
865 GIdlNodeType *type = (GIdlNodeType *)node;
866 SimpleTypeBlob *blob = (SimpleTypeBlob *)&data[*offset];
874 blob->pointer = type->is_pointer;
876 blob->tag = type->tag;
884 str = g_string_new (0);
885 serialize_type (module, modules, type, str);
886 s = g_string_free (str, FALSE);
888 value = g_hash_table_lookup (types, s);
891 blob->offset = GPOINTER_TO_INT (value);
896 g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
898 blob->offset = *offset2;
903 ArrayTypeBlob *array = (ArrayTypeBlob *)&data[*offset2];
908 array->tag = type->tag;
909 array->zero_terminated = type->zero_terminated;
910 array->has_length = type->has_length;
911 array->reserved2 = 0;
912 array->length = type->length;
917 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
918 module, modules, strings, types,
919 data, &pos, offset2);
925 InterfaceTypeBlob *iface = (InterfaceTypeBlob *)&data[*offset2];
932 iface->tag = type->tag;
933 iface->reserved2 = 0;
934 iface->interface = 0;
935 iface->interface = find_entry (module, modules, type->interface);
942 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
947 param->tag = type->tag;
948 param->reserved2 = 0;
954 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
955 module, modules, strings, types,
956 data, &pos, offset2);
962 ParamTypeBlob *param = (ParamTypeBlob *)&data[*offset2];
967 param->tag = type->tag;
968 param->reserved2 = 0;
974 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type1,
975 module, modules, strings, types,
976 data, &pos, offset2);
977 g_idl_node_build_metadata ((GIdlNode *)type->parameter_type2,
978 module, modules, strings, types,
979 data, &pos, offset2);
985 ErrorTypeBlob *blob = (ErrorTypeBlob *)&data[*offset2];
990 blob->tag = type->tag;
992 blob->n_domains = g_strv_length (type->errors);
994 *offset2 = ALIGN_VALUE (*offset2 + 4 + 2 * blob->n_domains, 4);
995 for (i = 0; type->errors[i]; i++)
996 blob->domains[i] = find_entry (module, modules, type->errors[i]);
1001 g_error ("Unknown type tag %d\n", type->tag);
1009 case G_IDL_NODE_FIELD:
1011 GIdlNodeField *field = (GIdlNodeField *)node;
1014 blob = (FieldBlob *)&data[*offset];
1017 blob->name = write_string (field->c_name, strings, data, offset2);
1018 blob->readable = field->readable;
1019 blob->writable = field->writable;
1022 blob->struct_offset = 0;
1024 g_idl_node_build_metadata ((GIdlNode *)field->type,
1025 module, modules, strings, types,
1026 data, offset, offset2);
1030 case G_IDL_NODE_PROPERTY:
1032 GIdlNodeProperty *prop = (GIdlNodeProperty *)node;
1033 PropertyBlob *blob = (PropertyBlob *)&data[*offset];
1036 blob->name = write_string (node->name, strings, data, offset2);
1037 blob->deprecated = prop->deprecated;
1038 blob->readable = prop->readable;
1039 blob->writable = prop->writable;
1040 blob->construct = prop->construct;
1041 blob->construct_only = prop->construct_only;
1044 g_idl_node_build_metadata ((GIdlNode *)prop->type,
1045 module, modules, strings, types,
1046 data, offset, offset2);
1050 case G_IDL_NODE_FUNCTION:
1052 FunctionBlob *blob = (FunctionBlob *)&data[*offset];
1053 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1054 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1055 guint32 signature, res;
1058 signature = *offset2;
1059 n = g_list_length (function->parameters);
1062 *offset2 += 8 + n * 12;
1064 blob->blob_type = BLOB_TYPE_FUNCTION;
1065 blob->deprecated = function->deprecated;
1066 blob->setter = function->is_setter;
1067 blob->getter = function->is_getter;
1068 blob->constructor = function->is_constructor;
1069 blob->wraps_vfunc = function->wraps_vfunc;
1072 blob->name = write_string (node->name, strings, data, offset2);
1073 blob->c_name = write_string (function->c_name, strings, data, offset2);
1074 blob->signature = signature;
1076 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1077 module, modules, strings, types,
1078 data, &signature, offset2);
1080 blob2->may_return_null = function->result->null_ok;
1081 blob2->caller_owns_return_value = function->result->transfer;
1082 blob2->caller_owns_return_container = function->result->shallow_transfer;
1083 blob2->reserved = 0;
1084 blob2->n_arguments = n;
1088 for (l = function->parameters; l; l = l->next)
1090 GIdlNode *param = (GIdlNode *)l->data;
1092 g_idl_node_build_metadata (param,
1093 module, modules, strings, types,
1094 data, &signature, offset2);
1099 case G_IDL_NODE_CALLBACK:
1101 CallbackBlob *blob = (CallbackBlob *)&data[*offset];
1102 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1103 GIdlNodeFunction *function = (GIdlNodeFunction *)node;
1104 guint32 signature, res;
1107 signature = *offset2;
1108 n = g_list_length (function->parameters);
1111 *offset2 += 8 + n * 12;
1113 blob->blob_type = BLOB_TYPE_CALLBACK;
1114 blob->deprecated = function->deprecated;
1116 blob->name = write_string (node->name, strings, data, offset2);
1117 blob->signature = signature;
1119 g_idl_node_build_metadata ((GIdlNode *)function->result->type,
1120 module, modules, strings, types,
1121 data, &signature, offset2);
1123 blob2->may_return_null = function->result->null_ok;
1124 blob2->caller_owns_return_value = function->result->transfer;
1125 blob2->caller_owns_return_container = function->result->shallow_transfer;
1126 blob2->reserved = 0;
1127 blob2->n_arguments = n;
1131 for (l = function->parameters; l; l = l->next)
1133 GIdlNode *param = (GIdlNode *)l->data;
1135 g_idl_node_build_metadata (param,
1136 module, modules, strings, types,
1137 data, &signature, offset2);
1142 case G_IDL_NODE_SIGNAL:
1144 SignalBlob *blob = (SignalBlob *)&data[*offset];
1145 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1146 GIdlNodeSignal *signal = (GIdlNodeSignal *)node;
1147 guint32 signature, res;
1150 signature = *offset2;
1151 n = g_list_length (signal->parameters);
1154 *offset2 += 8 + n * 12;
1156 blob->deprecated = signal->deprecated;
1157 blob->run_first = signal->run_first;
1158 blob->run_last = signal->run_last;
1159 blob->run_cleanup = signal->run_cleanup;
1160 blob->no_recurse = signal->no_recurse;
1161 blob->detailed = signal->detailed;
1162 blob->action = signal->action;
1163 blob->no_hooks = signal->no_hooks;
1164 blob->has_class_closure = 0; /* FIXME */
1165 blob->true_stops_emit = 0; /* FIXME */
1167 blob->class_closure = 0; /* FIXME */
1168 blob->name = write_string (node->name, strings, data, offset2);
1169 blob->signature = signature;
1171 g_idl_node_build_metadata ((GIdlNode *)signal->result->type,
1172 module, modules, strings, types,
1173 data, &signature, offset2);
1175 blob2->may_return_null = signal->result->null_ok;
1176 blob2->caller_owns_return_value = signal->result->transfer;
1177 blob2->caller_owns_return_container = signal->result->shallow_transfer;
1178 blob2->reserved = 0;
1179 blob2->n_arguments = n;
1183 for (l = signal->parameters; l; l = l->next)
1185 GIdlNode *param = (GIdlNode *)l->data;
1187 g_idl_node_build_metadata (param, module, modules, strings, types,
1188 data, &signature, offset2);
1193 case G_IDL_NODE_VFUNC:
1195 VFuncBlob *blob = (VFuncBlob *)&data[*offset];
1196 SignatureBlob *blob2 = (SignatureBlob *)&data[*offset2];
1197 GIdlNodeVFunc *vfunc = (GIdlNodeVFunc *)node;
1198 guint32 signature, res;
1201 signature = *offset2;
1202 n = g_list_length (vfunc->parameters);
1205 *offset2 += 8 + n * 12;
1207 blob->name = write_string (node->name, strings, data, offset2);
1208 blob->must_chain_up = 0; /* FIXME */
1209 blob->must_be_implemented = 0; /* FIXME */
1210 blob->must_not_be_implemented = 0; /* FIXME */
1211 blob->class_closure = 0; /* FIXME */
1214 blob->struct_offset = 0; /* FIXME */
1215 blob->reserved2 = 0;
1216 blob->signature = signature;
1218 g_idl_node_build_metadata ((GIdlNode *)vfunc->result->type,
1219 module, modules, strings, types,
1220 data, &signature, offset2);
1222 blob2->may_return_null = vfunc->result->null_ok;
1223 blob2->caller_owns_return_value = vfunc->result->transfer;
1224 blob2->caller_owns_return_container = vfunc->result->shallow_transfer;
1225 blob2->reserved = 0;
1226 blob2->n_arguments = n;
1230 for (l = vfunc->parameters; l; l = l->next)
1232 GIdlNode *param = (GIdlNode *)l->data;
1234 g_idl_node_build_metadata (param, module, modules, strings,
1235 types, data, &signature, offset2);
1240 case G_IDL_NODE_PARAM:
1242 ArgBlob *blob = (ArgBlob *)&data[*offset];
1243 GIdlNodeParam *param = (GIdlNodeParam *)node;
1248 blob->name = write_string (node->name, strings, data, offset2);
1249 blob->in = param->in;
1250 blob->out = param->out;
1251 blob->dipper = param->dipper;
1252 blob->null_ok = param->null_ok;
1253 blob->optional = param->optional;
1254 blob->transfer_ownership = param->transfer;
1255 blob->transfer_container_ownership = param->shallow_transfer;
1256 blob->return_value = param->retval;
1259 g_idl_node_build_metadata ((GIdlNode *)param->type, module, modules,
1260 types, strings, data, offset, offset2);
1264 case G_IDL_NODE_STRUCT:
1266 StructBlob *blob = (StructBlob *)&data[*offset];
1267 GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
1270 blob->blob_type = BLOB_TYPE_STRUCT;
1271 blob->deprecated = struct_->deprecated;
1272 blob->unregistered = TRUE;
1274 blob->name = write_string (node->name, strings, data, offset2);
1275 blob->gtype_name = 0;
1276 blob->gtype_init = 0;
1279 blob->n_methods = 0;
1282 for (l = struct_->members; l; l = l->next)
1284 GIdlNode *member = (GIdlNode *)l->data;
1286 if (member->type == G_IDL_NODE_FIELD)
1289 g_idl_node_build_metadata (member, module, modules, strings,
1290 types, data, offset, offset2);
1294 for (l = struct_->members; l; l = l->next)
1296 GIdlNode *member = (GIdlNode *)l->data;
1298 if (member->type == G_IDL_NODE_FUNCTION)
1301 g_idl_node_build_metadata (member, module, modules, strings,
1302 types, data, offset, offset2);
1308 case G_IDL_NODE_BOXED:
1310 StructBlob *blob = (StructBlob *)&data[*offset];
1311 GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
1313 blob->blob_type = BLOB_TYPE_BOXED;
1314 blob->deprecated = boxed->deprecated;
1315 blob->unregistered = FALSE;
1317 blob->name = write_string (node->name, strings, data, offset2);
1318 blob->gtype_name = write_string (boxed->c_name, strings, data, offset2);
1319 blob->gtype_init = write_string (boxed->init_func, strings, data, offset2);
1322 blob->n_methods = 0;
1325 for (l = boxed->members; l; l = l->next)
1327 GIdlNode *member = (GIdlNode *)l->data;
1329 if (member->type == G_IDL_NODE_FIELD)
1332 g_idl_node_build_metadata (member, module, modules, strings,
1333 types, data, offset, offset2);
1337 for (l = boxed->members; l; l = l->next)
1339 GIdlNode *member = (GIdlNode *)l->data;
1341 if (member->type == G_IDL_NODE_FUNCTION)
1344 g_idl_node_build_metadata (member, module, modules, strings,
1345 types, data, offset, offset2);
1351 case G_IDL_NODE_ENUM:
1352 case G_IDL_NODE_FLAGS:
1354 EnumBlob *blob = (EnumBlob *)&data[*offset];
1355 GIdlNodeEnum *enum_ = (GIdlNodeEnum *)node;
1359 if (node->type == G_IDL_NODE_ENUM)
1360 blob->blob_type = BLOB_TYPE_ENUM;
1362 blob->blob_type = BLOB_TYPE_FLAGS;
1364 blob->deprecated = enum_->deprecated;
1366 blob->name = write_string (node->name, strings, data, offset2);
1367 blob->gtype_name = write_string (enum_->c_name, strings, data, offset2);
1368 if (enum_->init_func)
1370 blob->unregistered = FALSE;
1371 blob->gtype_init = write_string (enum_->init_func, strings, data, offset2);
1375 blob->unregistered = TRUE;
1376 blob->gtype_init = 0;
1380 blob->reserved2 = 0;
1382 for (l = enum_->values; l; l = l->next)
1384 GIdlNode *value = (GIdlNode *)l->data;
1387 g_idl_node_build_metadata (value, module, modules, strings, types,
1388 data, offset, offset2);
1393 case G_IDL_NODE_OBJECT:
1395 ObjectBlob *blob = (ObjectBlob *)&data[*offset];
1396 GIdlNodeInterface *object = (GIdlNodeInterface *)node;
1399 blob->blob_type = BLOB_TYPE_OBJECT;
1400 blob->deprecated = object->deprecated;
1402 blob->name = write_string (node->name, strings, data, offset2);
1403 blob->gtype_name = write_string (object->c_name, strings, data, offset2);
1404 blob->gtype_init = write_string (object->init_func, strings, data, offset2);
1406 blob->parent = find_entry (module, modules, object->parent);
1410 blob->n_interfaces = 0;
1412 blob->n_properties = 0;
1413 blob->n_methods = 0;
1414 blob->n_signals = 0;
1416 blob->n_constants = 0;
1419 for (l = object->interfaces; l; l = l->next)
1421 blob->n_interfaces++;
1422 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1426 *offset = ALIGN_VALUE (*offset, 4);
1427 for (l = object->members; l; l = l->next)
1429 GIdlNode *member = (GIdlNode *)l->data;
1431 if (member->type == G_IDL_NODE_FIELD)
1434 g_idl_node_build_metadata (member, module, modules, strings,
1435 types, data, offset, offset2);
1439 *offset = ALIGN_VALUE (*offset, 4);
1440 for (l = object->members; l; l = l->next)
1442 GIdlNode *member = (GIdlNode *)l->data;
1444 if (member->type == G_IDL_NODE_PROPERTY)
1446 blob->n_properties++;
1447 g_idl_node_build_metadata (member, module, modules, strings,
1448 types, data, offset, offset2);
1452 *offset = ALIGN_VALUE (*offset, 4);
1453 for (l = object->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);
1465 *offset = ALIGN_VALUE (*offset, 4);
1466 for (l = object->members; l; l = l->next)
1468 GIdlNode *member = (GIdlNode *)l->data;
1470 if (member->type == G_IDL_NODE_SIGNAL)
1473 g_idl_node_build_metadata (member, module, modules, strings,
1474 types, data, offset, offset2);
1478 *offset = ALIGN_VALUE (*offset, 4);
1479 for (l = object->members; l; l = l->next)
1481 GIdlNode *member = (GIdlNode *)l->data;
1483 if (member->type == G_IDL_NODE_VFUNC)
1486 g_idl_node_build_metadata (member, module, modules, strings,
1487 types, data, offset, offset2);
1491 *offset = ALIGN_VALUE (*offset, 4);
1492 for (l = object->members; l; l = l->next)
1494 GIdlNode *member = (GIdlNode *)l->data;
1496 if (member->type == G_IDL_NODE_CONSTANT)
1498 blob->n_constants++;
1499 g_idl_node_build_metadata (member, module, modules, strings,
1500 types, data, offset, offset2);
1506 case G_IDL_NODE_INTERFACE:
1508 InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
1509 GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
1512 blob->blob_type = BLOB_TYPE_INTERFACE;
1513 blob->deprecated = iface->deprecated;
1515 blob->name = write_string (node->name, strings, data, offset2);
1516 blob->gtype_name = write_string (iface->c_name, strings, data, offset2);
1517 blob->gtype_init = write_string (iface->init_func, strings, data, offset2);
1518 blob->n_prerequisites = 0;
1519 blob->n_properties = 0;
1520 blob->n_methods = 0;
1521 blob->n_signals = 0;
1523 blob->n_constants = 0;
1526 for (l = iface->prerequisites; l; l = l->next)
1528 blob->n_prerequisites++;
1529 *(guint16*)&data[*offset] = find_entry (module, modules, (gchar *)l->data);
1533 *offset = ALIGN_VALUE (*offset, 4);
1534 for (l = iface->members; l; l = l->next)
1536 GIdlNode *member = (GIdlNode *)l->data;
1538 if (member->type == G_IDL_NODE_PROPERTY)
1540 blob->n_properties++;
1541 g_idl_node_build_metadata (member, module, modules, strings,
1542 types, data, offset, offset2);
1546 *offset = ALIGN_VALUE (*offset, 4);
1547 for (l = iface->members; l; l = l->next)
1549 GIdlNode *member = (GIdlNode *)l->data;
1551 if (member->type == G_IDL_NODE_FUNCTION)
1554 g_idl_node_build_metadata (member, module, modules, strings,
1555 types, data, offset, offset2);
1559 *offset = ALIGN_VALUE (*offset, 4);
1560 for (l = iface->members; l; l = l->next)
1562 GIdlNode *member = (GIdlNode *)l->data;
1564 if (member->type == G_IDL_NODE_SIGNAL)
1567 g_idl_node_build_metadata (member, module, modules, strings,
1568 types, data, offset, offset2);
1572 *offset = ALIGN_VALUE (*offset, 4);
1573 for (l = iface->members; l; l = l->next)
1575 GIdlNode *member = (GIdlNode *)l->data;
1577 if (member->type == G_IDL_NODE_VFUNC)
1580 g_idl_node_build_metadata (member, module, modules, strings,
1581 types, data, offset, offset2);
1585 *offset = ALIGN_VALUE (*offset, 4);
1586 for (l = iface->members; l; l = l->next)
1588 GIdlNode *member = (GIdlNode *)l->data;
1590 if (member->type == G_IDL_NODE_CONSTANT)
1592 blob->n_constants++;
1593 g_idl_node_build_metadata (member, module, modules, strings,
1594 types, data, offset, offset2);
1601 case G_IDL_NODE_VALUE:
1603 GIdlNodeValue *value = (GIdlNodeValue *)node;
1604 ValueBlob *blob = (ValueBlob *)&data[*offset];
1607 blob->deprecated = value->deprecated;
1609 blob->name = write_string (node->name, strings, data, offset2);
1610 blob->short_name = write_string (value->c_name, strings, data, offset2);
1611 blob->value = value->value;
1615 case G_IDL_NODE_ERROR_DOMAIN:
1617 GIdlNodeErrorDomain *domain = (GIdlNodeErrorDomain *)node;
1618 ErrorDomainBlob *blob = (ErrorDomainBlob *)&data[*offset];
1621 blob->blob_type = BLOB_TYPE_ERROR_DOMAIN;
1622 blob->deprecated = domain->deprecated;
1624 blob->name = write_string (node->name, strings, data, offset2);
1625 blob->get_quark = write_string (domain->getquark, strings, data, offset2);
1626 blob->error_codes = find_entry (module, modules, domain->codes);
1627 blob->reserved2 = 0;
1631 case G_IDL_NODE_CONSTANT:
1633 GIdlNodeConstant *constant = (GIdlNodeConstant *)node;
1634 ConstantBlob *blob = (ConstantBlob *)&data[*offset];
1640 blob->blob_type = BLOB_TYPE_CONSTANT;
1641 blob->deprecated = constant->deprecated;
1643 blob->name = write_string (node->name, strings, data, offset2);
1645 blob->offset = *offset2;
1646 switch (constant->type->tag)
1650 *(gboolean*)&data[blob->offset] = parse_boolean_value (constant->value);
1654 *(gint8*)&data[blob->offset] = (gint8) parse_int_value (constant->value);
1658 *(guint8*)&data[blob->offset] = (guint8) parse_uint_value (constant->value);
1662 *(gint16*)&data[blob->offset] = (gint16) parse_int_value (constant->value);
1666 *(guint16*)&data[blob->offset] = (guint16) parse_uint_value (constant->value);
1670 *(gint32*)&data[blob->offset] = (gint32) parse_int_value (constant->value);
1674 *(guint32*)&data[blob->offset] = (guint32) parse_uint_value (constant->value);
1678 *(gint32*)&data[blob->offset] = (gint64) parse_int_value (constant->value);
1682 *(guint32*)&data[blob->offset] = (guint64) parse_uint_value (constant->value);
1685 blob->size = sizeof (gfloat);
1686 *(gfloat*)&data[blob->offset] = (gfloat) parse_float_value (constant->value);
1689 blob->size = sizeof (gdouble);
1690 *(gdouble*)&data[blob->offset] = (gdouble) parse_float_value (constant->value);
1693 blob->size = strlen (constant->value) + 1;
1694 memcpy (&data[blob->offset], constant->value, blob->size);
1697 blob->size = sizeof (gint);
1698 *(gint*)&data[blob->offset] = (gint) parse_int_value (constant->value);
1701 blob->size = sizeof (guint);
1702 *(gint*)&data[blob->offset] = (guint) parse_uint_value (constant->value);
1705 blob->size = sizeof (glong);
1706 *(glong*)&data[blob->offset] = (glong) parse_int_value (constant->value);
1709 blob->size = sizeof (gulong);
1710 *(gulong*)&data[blob->offset] = (gulong) parse_uint_value (constant->value);
1713 *offset2 += ALIGN_VALUE (blob->size, 4);
1715 g_idl_node_build_metadata ((GIdlNode *)constant->type, module, modules,
1716 strings, types, data, &pos, offset2);
1723 /* if str is already in the pool, return previous location, otherwise write str
1724 * to the metadata at offset, put it in the pool and update offset. If the
1725 * metadata is not large enough to hold the string, reallocate it.
1728 write_string (const gchar *str,
1729 GHashTable *strings,
1736 value = g_hash_table_lookup (strings, str);
1739 return GPOINTER_TO_INT (value);
1741 g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
1744 *offset = ALIGN_VALUE (start + strlen (str) + 1, 4);
1746 strcpy (&data[start], str);