summaryrefslogtreecommitdiff
path: root/girepository/gitypelib.c
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2010-10-18 12:04:08 -0400
committerColin Walters <walters@verbum.org>2010-10-18 12:04:08 -0400
commitf97cc8687469f25752f7927545ad4daecef8ab44 (patch)
treec1c792e80f9c24ad5990e2dd7fd7acc4a2d31dcb /girepository/gitypelib.c
parent80a42c6eb38b4b8fd68b5d4e8780a834ad8bdda5 (diff)
downloadgobject-introspection-f97cc8687469f25752f7927545ad4daecef8ab44.tar.gz
girepository: Refactor lookup code
This is a cleanup patch in preparation for future indexing patches. The lookup code was a mess trying to mash in the 3 different cases of name, GType, and index into one mega-function. Split it up properly, and move the core typelib internal-scanning bits into gitypelib.c where it belongs.
Diffstat (limited to 'girepository/gitypelib.c')
-rw-r--r--girepository/gitypelib.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/girepository/gitypelib.c b/girepository/gitypelib.c
index cab697a2..4f851702 100644
--- a/girepository/gitypelib.c
+++ b/girepository/gitypelib.c
@@ -139,6 +139,80 @@ g_typelib_get_dir_entry (GITypelib *typelib,
return (DirEntry *)&typelib->data[header->directory + (index - 1) * header->entry_blob_size];
}
+DirEntry *
+g_typelib_get_dir_entry_by_name (GITypelib *typelib,
+ const char *name)
+{
+ Header *header = (Header *)typelib->data;
+ guint n_entries = header->n_local_entries;
+ DirEntry *entry;
+ guint i;
+
+ for (i = 1; i <= n_entries; i++)
+ {
+ const char *entry_name;
+
+ 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;
+}
+
+DirEntry *
+g_typelib_get_dir_entry_by_gtype (GITypelib *typelib,
+ gboolean fastpass,
+ GType gtype)
+{
+ Header *header = (Header *)typelib->data;
+ guint n_entries = header->n_local_entries;
+ const char *gtype_name = g_type_name (gtype);
+ DirEntry *entry;
+ guint i;
+ const char *c_prefix;
+
+ /* Inside each typelib, we include the "C prefix" which acts as
+ * a namespace mechanism. For GtkTreeView, the C prefix is Gtk.
+ * Given the assumption that GTypes for a library also use the
+ * C prefix, we know we can skip examining a typelib if our
+ * target type does not have this typelib's C prefix.
+ *
+ * However, not every class library necessarily conforms to this,
+ * e.g. Clutter has Cogl inside it. So, we split this into two
+ * passes. First we try a lookup, skipping things which don't
+ * have the prefix. If that fails then we try a global lookup,
+ * ignoring the prefix.
+ *
+ * See http://bugzilla.gnome.org/show_bug.cgi?id=564016
+ */
+ c_prefix = g_typelib_get_string (typelib, header->c_prefix);
+ if (fastpass && c_prefix != NULL)
+ {
+ if (g_ascii_strncasecmp (c_prefix, gtype_name, strlen (c_prefix)) != 0)
+ return NULL;
+ }
+
+ for (i = 1; i <= n_entries; i++)
+ {
+ RegisteredTypeBlob *blob;
+ const char *type;
+
+ entry = g_typelib_get_dir_entry (typelib, i);
+ if (!BLOB_IS_REGISTERED_TYPE (entry))
+ continue;
+
+ blob = (RegisteredTypeBlob *)(&typelib->data[entry->offset]);
+ if (!blob->gtype_name)
+ continue;
+
+ type = g_typelib_get_string (typelib, blob->gtype_name);
+ if (strcmp (type, gtype_name) == 0)
+ return entry;
+ }
+ return NULL;
+}
+
void
g_typelib_check_sanity (void)
{