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"
27 #define ALIGN_VALUE(this, boundary) \
28 (( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
32 g_idl_module_new (const gchar
*name
, const gchar
*shared_library
)
36 module
= g_new (GIdlModule
, 1);
38 module
->name
= g_strdup (name
);
40 module
->shared_library
= g_strdup (shared_library
);
42 module
->shared_library
= NULL
;
43 module
->entries
= NULL
;
49 g_idl_module_free (GIdlModule
*module
)
53 g_free (module
->name
);
55 for (e
= module
->entries
; e
; e
= e
->next
)
56 g_idl_node_free ((GIdlNode
*)e
->data
);
58 g_list_free (module
->entries
);
64 g_idl_module_build_metadata (GIdlModule
*module
,
76 guint32 n_local_entries
;
77 guint32 size
, offset
, offset2
, old_offset
;
82 header_size
= ALIGN_VALUE (sizeof (Header
), 4);
83 n_local_entries
= g_list_length (module
->entries
);
87 strings
= g_hash_table_new (g_str_hash
, g_str_equal
);
88 types
= g_hash_table_new (g_str_hash
, g_str_equal
);
89 n_entries
= g_list_length (module
->entries
);
91 g_message ("%d entries (%d local)\n", n_entries
, n_local_entries
);
93 dir_size
= n_entries
* 12;
94 size
= header_size
+ dir_size
;
96 size
+= ALIGN_VALUE (strlen (module
->name
) + 1, 4);
98 for (e
= module
->entries
; e
; e
= e
->next
)
100 GIdlNode
*node
= e
->data
;
102 size
+= g_idl_node_get_full_size (node
);
105 g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n",
106 size
, header_size
, dir_size
, size
- header_size
- dir_size
);
108 data
= g_malloc0 (size
);
111 header
= (Header
*)data
;
112 memcpy (header
, G_IDL_MAGIC
, 16);
113 header
->major_version
= 1;
114 header
->minor_version
= 0;
115 header
->reserved
= 0;
116 header
->n_entries
= n_entries
;
117 header
->n_local_entries
= n_local_entries
;
118 header
->n_annotations
= 0;
119 header
->annotations
= 0; /* filled in later */
120 header
->size
= 0; /* filled in later */
121 header
->namespace = write_string (module
->name
, strings
, data
, &header_size
);
122 header
->shared_library
= (module
->shared_library
?
123 write_string (module
->shared_library
, strings
, data
, &header_size
)
125 header
->directory
= ALIGN_VALUE (header_size
, 4);
126 header
->entry_blob_size
= 12;
127 header
->function_blob_size
= 16;
128 header
->callback_blob_size
= 12;
129 header
->signal_blob_size
= 12;
130 header
->vfunc_blob_size
= 16;
131 header
->arg_blob_size
= 12;
132 header
->property_blob_size
= 12;
133 header
->field_blob_size
= 12;
134 header
->value_blob_size
= 12;
135 header
->constant_blob_size
= 20;
136 header
->error_domain_blob_size
= 16;
137 header
->annotation_blob_size
= 12;
138 header
->signature_blob_size
= 8;
139 header
->enum_blob_size
= 20;
140 header
->struct_blob_size
= 20;
141 header
->object_blob_size
= 32;
142 header
->interface_blob_size
= 28;
143 header
->union_blob_size
= 28;
145 /* fill in directory and content */
146 entry
= (DirEntry
*)&data
[header
->directory
];
148 offset2
= header
->directory
+ dir_size
;
150 for (e
= module
->entries
, i
= 0; e
; e
= e
->next
, i
++)
152 GIdlNode
*node
= e
->data
;
154 if (strchr (node
->name
, '.'))
156 g_error ("Names may not contain '.'");
159 /* we picked up implicit xref nodes, start over */
162 g_message ("Found implicit cross references, starting over");
164 g_hash_table_destroy (strings
);
165 g_hash_table_destroy (types
);
176 if (node
->type
== G_IDL_NODE_XREF
)
178 entry
->blob_type
= 0;
179 entry
->local
= FALSE
;
180 entry
->offset
= write_string (((GIdlNodeXRef
*)node
)->namespace, strings
, data
, &offset2
);
181 entry
->name
= write_string (node
->name
, strings
, data
, &offset2
);
186 offset2
= offset
+ g_idl_node_get_size (node
);
188 entry
->blob_type
= node
->type
;
190 entry
->offset
= offset
;
191 entry
->name
= write_string (node
->name
, strings
, data
, &offset2
);
193 g_idl_node_build_metadata (node
, module
, modules
,
194 strings
, types
, data
, &offset
, &offset2
);
196 if (offset2
> old_offset
+ g_idl_node_get_full_size (node
))
197 g_error ("left a hole of %d bytes\n", offset2
- old_offset
- g_idl_node_get_full_size (node
));
204 g_hash_table_destroy (strings
);
205 g_hash_table_destroy (types
);
207 header
->annotations
= offset2
;
209 g_message ("reallocating to %d bytes", offset2
);
211 metadata
= g_realloc (data
, offset2
);
212 length
= header
->size
= offset2
;
213 return g_metadata_new_from_memory (metadata
, length
);