diff options
author | Colin Walters <walters@verbum.org> | 2010-10-25 13:33:01 -0400 |
---|---|---|
committer | Colin Walters <walters@verbum.org> | 2010-12-02 12:49:47 -0500 |
commit | 9821bdbbd304612ddcf9164cd7b655341701874f (patch) | |
tree | 3838abbc20c481c8ef57a6b76bf42b8dfa08609c /girepository/gitypelib.c | |
parent | fa383ec4fe3724193b1f551e3915e9620d6b4f20 (diff) | |
download | gobject-introspection-wip/cmph-rebase3.tar.gz |
Add directory index sectionwip/cmph-rebase3
Use the internal perfect hashing API to add an index to the directory.
To support this, add the notion of additional "sections" to the
typelib. A section index is inserted between the header and the
directory.
https://bugzilla.gnome.org/show_bug.cgi?id=554943
Diffstat (limited to 'girepository/gitypelib.c')
-rw-r--r-- | girepository/gitypelib.c | 52 |
1 files changed, 44 insertions, 8 deletions
diff --git a/girepository/gitypelib.c b/girepository/gitypelib.c index a0b74d3d..90f2c1bb 100644 --- a/girepository/gitypelib.c +++ b/girepository/gitypelib.c @@ -139,25 +139,61 @@ g_typelib_get_dir_entry (GITypelib *typelib, return (DirEntry *)&typelib->data[header->directory + (index - 1) * header->entry_blob_size]; } +static Section * +get_section_by_id (GITypelib *typelib, + SectionType section_type) +{ + Header *header = (Header *)typelib->data; + Section *section; + + if (header->sections == 0) + return NULL; + + for (section = (Section*)&typelib->data[header->sections]; + section->id != GI_SECTION_END; + section++) + { + if (section->id == section_type) + return section; + } + return NULL; +} + DirEntry * -g_typelib_get_dir_entry_by_name (GITypelib *typelib, +g_typelib_get_dir_entry_by_name (GITypelib *typelib, const char *name) { - Header *header = (Header *)typelib->data; - guint n_entries = header->n_local_entries; + Section *dirindex; + gint i; + const char *entry_name; DirEntry *entry; - guint i; - for (i = 1; i <= n_entries; i++) + dirindex = get_section_by_id (typelib, GI_SECTION_DIRECTORY_INDEX); + + if (dirindex == NULL) + { + gint n_entries = ((Header *)typelib->data)->n_local_entries; + for (i = 1; i <= n_entries; i++) + { + entry = g_typelib_get_dir_entry (typelib, i); + entry_name = g_typelib_get_string (typelib, entry->name); + if (strcmp (name, entry_name) == 0) + return entry; + } + return NULL; + } + else { - const char *entry_name; + guint8 *hash = (guint8*) &typelib->data[dirindex->offset]; + guint16 index; - entry = g_typelib_get_dir_entry (typelib, i); + index = _gi_typelib_hash_search (hash, name); + entry = g_typelib_get_dir_entry (typelib, index + 1); entry_name = g_typelib_get_string (typelib, entry->name); if (strcmp (name, entry_name) == 0) return entry; + return NULL; } - return NULL; } DirEntry * |