diff options
author | Colin Walters <walters@verbum.org> | 2009-02-19 21:48:51 -0500 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2009-03-03 17:26:37 -0500 |
commit | d5215b23315e7c9c22c6a32218bb6f8027a9dd4c (patch) | |
tree | e8d9e360099c756677ad23a1039f4d05533008b9 /girepository/girmodule.c | |
parent | 2bdd2bf9303ae0e718c00ec84078336e722138f1 (diff) | |
download | gobject-introspection-d5215b23315e7c9c22c6a32218bb6f8027a9dd4c.tar.gz |
Bug 571548 - Generic attributes
We now support an extensible mechanism where arbitrary key-value
pairs may be associated with almost all items, including objects,
methods, and properties.
These attributes appear in both the .gir and the .typelib.
Diffstat (limited to 'girepository/girmodule.c')
-rw-r--r-- | girepository/girmodule.c | 88 |
1 files changed, 84 insertions, 4 deletions
diff --git a/girepository/girmodule.c b/girepository/girmodule.c index 5abd31f8..96ee9ce9 100644 --- a/girepository/girmodule.c +++ b/girepository/girmodule.c @@ -109,6 +109,53 @@ g_ir_module_add_include_module (GIrModule *module, module); } +struct AttributeWriteData +{ + guint count; + guchar *databuf; + GIrNode *node; + GHashTable *strings; + guint32 *offset; + guint32 *offset2; +}; + +static void +write_attribute (gpointer key, gpointer value, gpointer datap) +{ + struct AttributeWriteData *data = datap; + guint32 old_offset = *(data->offset); + AttributeBlob *blob = (AttributeBlob*)&(data->databuf[old_offset]); + + *(data->offset) += sizeof (AttributeBlob); + + blob->offset = data->node->offset; + blob->name = write_string ((const char*) key, data->strings, data->databuf, data->offset2); + blob->value = write_string ((const char*) value, data->strings, data->databuf, data->offset2); + + data->count++; +} + +static guint +write_attributes (GIrModule *module, + GIrNode *node, + GHashTable *strings, + guchar *data, + guint32 *offset, + guint32 *offset2) +{ + struct AttributeWriteData wdata; + wdata.count = 0; + wdata.databuf = data; + wdata.node = node; + wdata.offset = offset; + wdata.offset2 = offset2; + wdata.strings = strings; + + g_hash_table_foreach (node->attributes, write_attribute, &wdata); + + return wdata.count; +} + GTypelib * g_ir_module_build_typelib (GIrModule *module, GList *modules) @@ -126,6 +173,7 @@ g_ir_module_build_typelib (GIrModule *module, guint32 size, offset, offset2, old_offset; GHashTable *strings; GHashTable *types; + GList *offset_ordered_nodes; char *dependencies; guchar *data; @@ -158,6 +206,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; n_entries = g_list_length (module->entries); g_message ("%d entries (%d local), %d dependencies\n", n_entries, n_local_entries, @@ -173,6 +222,10 @@ 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; } /* Adjust size for strings allocated in header below specially */ @@ -195,8 +248,8 @@ g_ir_module_build_typelib (GIrModule *module, header->reserved = 0; header->n_entries = n_entries; header->n_local_entries = n_local_entries; - header->n_annotations = 0; - header->annotations = 0; /* filled in later */ + header->n_attributes = 0; + header->attributes = 0; /* filled in later */ if (dependencies != NULL) header->dependencies = write_string (dependencies, strings, data, &header_size); else @@ -219,7 +272,7 @@ g_ir_module_build_typelib (GIrModule *module, header->value_blob_size = sizeof (ValueBlob); header->constant_blob_size = sizeof (ConstantBlob); header->error_domain_blob_size = sizeof (ErrorDomainBlob); - header->annotation_blob_size = sizeof (AnnotationBlob); + header->attribute_blob_size = sizeof (AttributeBlob); header->signature_blob_size = sizeof (SignatureBlob); header->enum_blob_size = sizeof (EnumBlob); header->struct_blob_size = sizeof (StructBlob); @@ -245,10 +298,17 @@ g_ir_module_build_typelib (GIrModule *module, /* we picked up implicit xref nodes, start over */ if (i == n_entries) { + GList *link; g_message ("Found implicit cross references, starting over"); g_hash_table_destroy (strings); g_hash_table_destroy (types); + + /* Reset the cached offsets */ + for (link = offset_ordered_nodes; link; link = link->next) + ((GIrNode *) link->data)->offset = 0; + + g_list_free (offset_ordered_nodes); strings = NULL; g_free (data); @@ -282,9 +342,14 @@ g_ir_module_build_typelib (GIrModule *module, build.modules = modules; build.strings = strings; build.types = types; + build.offset_ordered_nodes = offset_ordered_nodes; + 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; + header->n_attributes = build.n_attributes; + if (offset2 > old_offset + g_ir_node_get_full_size (node)) g_error ("left a hole of %d bytes\n", offset2 - old_offset - g_ir_node_get_full_size (node)); } @@ -292,9 +357,23 @@ g_ir_module_build_typelib (GIrModule *module, entry++; } + offset_ordered_nodes = g_list_reverse (offset_ordered_nodes); + + g_message ("header: %d entries, %d attributes", header->n_entries, header->n_attributes); + _g_irnode_dump_stats (); - header->annotations = offset2; + /* Write attributes after the blobs */ + offset = offset2; + header->attributes = offset; + offset2 = offset + header->n_attributes * header->attribute_blob_size; + + for (e = offset_ordered_nodes; e; e = e->next) + { + GIrNode *node = e->data; + + write_attributes (module, node, strings, data, &offset, &offset2); + } g_message ("reallocating to %d bytes", offset2); @@ -305,6 +384,7 @@ g_ir_module_build_typelib (GIrModule *module, g_hash_table_destroy (strings); g_hash_table_destroy (types); + g_list_free (offset_ordered_nodes); return typelib; } |