diff --git a/girmodule.c b/girmodule.c index b380912b5..ae40d5f5b 100644 --- a/girmodule.c +++ b/girmodule.c @@ -192,6 +192,16 @@ write_attributes (GIrModule *module, return wdata.count; } +static gint +node_cmp_offset_func (gconstpointer a, + gconstpointer b) +{ + const GIrNode *na = a; + const GIrNode *nb = b; + return na->offset - nb->offset; +} + + GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules) @@ -209,7 +219,7 @@ g_ir_module_build_typelib (GIrModule *module, guint32 size, offset, offset2, old_offset; GHashTable *strings; GHashTable *types; - GList *offset_ordered_nodes; + GList *nodes_with_attributes; char *dependencies; guchar *data; @@ -242,7 +252,7 @@ g_ir_module_build_typelib (GIrModule *module, _g_irnode_init_stats (); strings = g_hash_table_new (g_str_hash, g_str_equal); types = g_hash_table_new (g_str_hash, g_str_equal); - offset_ordered_nodes = NULL; + nodes_with_attributes = NULL; n_entries = g_list_length (module->entries); g_message ("%d entries (%d local), %d dependencies\n", n_entries, n_local_entries, @@ -258,7 +268,6 @@ g_ir_module_build_typelib (GIrModule *module, GIrNode *node = e->data; size += g_ir_node_get_full_size (node); - size += g_ir_node_get_attribute_size (node); /* Also reset the offset here */ node->offset = 0; @@ -350,10 +359,10 @@ g_ir_module_build_typelib (GIrModule *module, g_hash_table_destroy (types); /* Reset the cached offsets */ - for (link = offset_ordered_nodes; link; link = link->next) + for (link = nodes_with_attributes; link; link = link->next) ((GIrNode *) link->data)->offset = 0; - g_list_free (offset_ordered_nodes); + g_list_free (nodes_with_attributes); strings = NULL; g_free (data); @@ -387,12 +396,12 @@ g_ir_module_build_typelib (GIrModule *module, build.modules = modules; build.strings = strings; build.types = types; - build.offset_ordered_nodes = offset_ordered_nodes; + build.nodes_with_attributes = nodes_with_attributes; build.n_attributes = header->n_attributes; build.data = data; g_ir_node_build_typelib (node, NULL, &build, &offset, &offset2); - offset_ordered_nodes = build.offset_ordered_nodes; + nodes_with_attributes = build.nodes_with_attributes; header->n_attributes = build.n_attributes; if (offset2 > old_offset + g_ir_node_get_full_size (node)) @@ -402,7 +411,8 @@ g_ir_module_build_typelib (GIrModule *module, entry++; } - offset_ordered_nodes = g_list_reverse (offset_ordered_nodes); + /* GIBaseInfo expects the AttributeBlob array to be sorted on the field (offset) */ + nodes_with_attributes = g_list_sort (nodes_with_attributes, node_cmp_offset_func); g_message ("header: %d entries, %d attributes", header->n_entries, header->n_attributes); @@ -413,10 +423,9 @@ g_ir_module_build_typelib (GIrModule *module, header->attributes = offset; offset2 = offset + header->n_attributes * header->attribute_blob_size; - for (e = offset_ordered_nodes; e; e = e->next) + for (e = nodes_with_attributes; e; e = e->next) { GIrNode *node = e->data; - write_attributes (module, node, strings, data, &offset, &offset2); } @@ -429,7 +438,7 @@ g_ir_module_build_typelib (GIrModule *module, g_hash_table_destroy (strings); g_hash_table_destroy (types); - g_list_free (offset_ordered_nodes); + g_list_free (nodes_with_attributes); return typelib; } diff --git a/girnode.c b/girnode.c index 0f5223fa0..fbdcdf965 100644 --- a/girnode.c +++ b/girnode.c @@ -573,7 +573,7 @@ add_attribute_size (gpointer key, gpointer value, gpointer data) *size_p += ALIGN_VALUE (strlen (value_str) + 1, 4); } -/* returns the full size of the blob including variable-size parts */ +/* returns the full size of the blob including variable-size parts (including attributes) */ static guint32 g_ir_node_get_full_size_internal (GIrNode *parent, GIrNode *node) @@ -878,6 +878,8 @@ g_ir_node_get_full_size_internal (GIrNode *parent, node->name ? "' " : "", node, g_ir_node_type_to_string (node->type), size); + g_hash_table_foreach (node->attributes, add_attribute_size, &size); + return size; } @@ -887,14 +889,6 @@ g_ir_node_get_full_size (GIrNode *node) return g_ir_node_get_full_size_internal (NULL, node); } -guint32 -g_ir_node_get_attribute_size (GIrNode *node) -{ - guint32 size = 0; - g_hash_table_foreach (node->attributes, add_attribute_size, &size); - return size; -} - int g_ir_node_cmp (GIrNode *node, GIrNode *other) @@ -1438,7 +1432,7 @@ g_ir_node_build_typelib (GIrNode *node, */ g_assert (node->offset == 0); node->offset = *offset; - build->offset_ordered_nodes = g_list_prepend (build->offset_ordered_nodes, node); + build->nodes_with_attributes = g_list_prepend (build->nodes_with_attributes, node); build->n_attributes += g_hash_table_size (node->attributes); diff --git a/girnode.h b/girnode.h index 038a53d78..bd9acd068 100644 --- a/girnode.h +++ b/girnode.h @@ -51,7 +51,7 @@ struct _GIrTypelibBuild { GList *modules; GHashTable *strings; GHashTable *types; - GList *offset_ordered_nodes; + GList *nodes_with_attributes; guint32 n_attributes; guchar *data; }; @@ -362,7 +362,6 @@ GIrNode * g_ir_node_new (GIrNodeTypeId type); void g_ir_node_free (GIrNode *node); guint32 g_ir_node_get_size (GIrNode *node); guint32 g_ir_node_get_full_size (GIrNode *node); -guint32 g_ir_node_get_attribute_size (GIrNode *node); void g_ir_node_build_typelib (GIrNode *node, GIrNode *parent, GIrTypelibBuild *build,