Remove g_irepository_unregister, add GIRepositoryLoadFlags

svn path=/trunk/; revision=543
This commit is contained in:
Colin Walters 2008-08-30 20:31:12 +00:00
parent e6a68106a2
commit 74651b01bd
2 changed files with 139 additions and 65 deletions

View File

@ -35,6 +35,7 @@ static GSList *search_path = NULL;
struct _GIRepositoryPrivate
{
GHashTable *typelibs; /* (string) namespace -> GTypelib */
GHashTable *lazy_typelibs; /* (string) namespace -> GTypelib */
};
G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
@ -44,6 +45,12 @@ g_irepository_init (GIRepository *repository)
{
repository->priv = G_TYPE_INSTANCE_GET_PRIVATE (repository, G_TYPE_IREPOSITORY,
GIRepositoryPrivate);
repository->priv->typelibs
= g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) NULL,
(GDestroyNotify) g_typelib_free);
repository->priv->lazy_typelibs
= g_hash_table_new (g_str_hash, g_str_equal);
}
static void
@ -76,10 +83,6 @@ init_globals ()
if (default_repository == NULL)
{
default_repository = g_object_new (G_TYPE_IREPOSITORY, NULL);
default_repository->priv->typelibs
= g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) NULL,
(GDestroyNotify) g_typelib_free);
}
if (search_path == NULL)
@ -135,13 +138,7 @@ static GIRepository *
get_repository (GIRepository *repository)
{
if (repository != NULL)
{
if (repository->priv->typelibs == NULL)
repository->priv->typelibs = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) NULL,
(GDestroyNotify) g_typelib_free);
return repository;
}
else
{
init_globals ();
@ -149,26 +146,45 @@ get_repository (GIRepository *repository)
}
}
static const char *
register_internal (GIRepository *repository,
const char *source,
static GTypelib *
get_registered_status (GIRepository *repository,
const char *namespace,
gboolean allow_lazy,
gboolean *lazy_status)
{
GTypelib *typelib;
repository = get_repository (repository);
if (lazy_status)
*lazy_status = FALSE;
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
if (typelib)
return typelib;
typelib = g_hash_table_lookup (repository->priv->lazy_typelibs, namespace);
if (!typelib)
return NULL;
if (lazy_status)
*lazy_status = TRUE;
if (!allow_lazy)
return NULL;
return typelib;
}
static GTypelib *
get_registered (GIRepository *repository,
const char *namespace)
{
return get_registered_status (repository, namespace, TRUE, NULL);
}
static gboolean
load_dependencies_recurse (GIRepository *repository,
GTypelib *typelib,
GError **error)
{
Header *header;
const gchar *name;
const char *dependencies_glob;
char **dependencies;
g_return_val_if_fail (typelib != NULL, FALSE);
header = (Header *)typelib->data;
g_return_val_if_fail (header != NULL, FALSE);
name = g_typelib_get_string (typelib, header->namespace);
dependencies = get_typelib_dependencies (typelib);
if (dependencies != NULL)
{
int i;
@ -177,23 +193,69 @@ register_internal (GIRepository *repository,
{
char *dependency = dependencies[i];
if (!g_irepository_require (repository, dependency, error))
if (!g_irepository_require (repository, dependency,
0, error))
{
g_strfreev (dependencies);
return NULL;
return FALSE;
}
}
g_strfreev (dependencies);
}
return TRUE;
}
g_assert (g_hash_table_lookup (repository->priv->typelibs, name) == NULL);
g_hash_table_insert (repository->priv->typelibs,
build_typelib_key (name, source), (void *)typelib);
static const char *
register_internal (GIRepository *repository,
const char *source,
gboolean lazy,
GTypelib *typelib,
GError **error)
{
Header *header;
const gchar *namespace;
gboolean was_loaded;
gboolean currently_lazy;
g_return_val_if_fail (typelib != NULL, FALSE);
header = (Header *)typelib->data;
g_return_val_if_fail (header != NULL, FALSE);
namespace = g_typelib_get_string (typelib, header->namespace);
if (lazy)
{
g_assert (!g_hash_table_lookup (repository->priv->lazy_typelibs,
namespace));
g_hash_table_insert (repository->priv->lazy_typelibs,
build_typelib_key (namespace, source), (void *)typelib);
}
else
{
gpointer value;
char *key;
/* First, try loading all the dependencies */
if (!load_dependencies_recurse (repository, typelib, error))
return NULL;
/* Check if we are transitioning from lazily loaded state */
if (g_hash_table_lookup_extended (repository->priv->lazy_typelibs,
namespace,
(gpointer)&key, &value))
g_hash_table_remove (repository->priv->lazy_typelibs, key);
else
key = build_typelib_key (namespace, source);
g_hash_table_insert (repository->priv->typelibs, key, (void *)typelib);
}
if (typelib->module == NULL)
typelib->module = g_module_open (NULL, 0);
return name;
return namespace;
}
char **
@ -206,7 +268,7 @@ g_irepository_get_dependencies (GIRepository *repository,
repository = get_repository (repository);
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
typelib = get_registered (repository, namespace);
g_return_val_if_fail (typelib != NULL, NULL);
return get_typelib_dependencies (typelib);
@ -215,31 +277,23 @@ g_irepository_get_dependencies (GIRepository *repository,
const char *
g_irepository_load_typelib (GIRepository *repository,
GTypelib *typelib,
GIRepositoryLoadFlags flags,
GError **error)
{
Header *header;
const char *namespace;
gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY;
gboolean is_lazy;
repository = get_repository (repository);
header = (Header *) typelib->data;
namespace = g_typelib_get_string (typelib, header->namespace);
if (g_hash_table_lookup (repository->priv->typelibs, namespace))
if (get_registered_status (repository, namespace, allow_lazy, &is_lazy))
return namespace;
return register_internal (repository, "<builtin>", typelib, error);
}
void
g_irepository_unregister (GIRepository *repository,
const gchar *namespace)
{
repository = get_repository (repository);
if (!g_hash_table_remove (repository->priv->typelibs, namespace))
{
g_printerr ("namespace '%s' not registered\n", namespace);
}
return register_internal (repository, "<builtin>",
allow_lazy, typelib, error);
}
gboolean
@ -247,8 +301,7 @@ g_irepository_is_registered (GIRepository *repository,
const gchar *namespace)
{
repository = get_repository (repository);
return g_hash_table_lookup (repository->priv->typelibs, namespace) != NULL;
return get_registered (repository, namespace) != NULL;
}
GIRepository *
@ -280,7 +333,7 @@ g_irepository_get_n_infos (GIRepository *repository,
{
GTypelib *typelib;
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
typelib = get_registered (repository, namespace);
if (typelib)
n_interfaces = ((Header *)typelib->data)->n_local_entries;
@ -289,6 +342,8 @@ g_irepository_get_n_infos (GIRepository *repository,
{
g_hash_table_foreach (repository->priv->typelibs,
count_interfaces, &n_interfaces);
g_hash_table_foreach (repository->priv->lazy_typelibs,
count_interfaces, &n_interfaces);
}
return n_interfaces;
@ -384,13 +439,16 @@ g_irepository_get_info (GIRepository *repository,
{
GTypelib *typelib;
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
typelib = get_registered (repository, namespace);
if (typelib)
find_interface ((void *)namespace, typelib, &data);
}
else
{
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
}
return data.iface;
}
@ -409,6 +467,7 @@ g_irepository_find_by_gtype (GIRepository *repository,
data.iface = NULL;
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
return data.iface;
}
@ -442,13 +501,16 @@ g_irepository_find_by_name (GIRepository *repository,
{
GTypelib *typelib;
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
typelib = get_registered (repository, namespace);
if (typelib)
find_interface ((void *)namespace, typelib, &data);
}
else
{
g_hash_table_foreach (repository->priv->typelibs, find_interface, &data);
g_hash_table_foreach (repository->priv->lazy_typelibs, find_interface, &data);
}
return data.iface;
}
@ -483,6 +545,7 @@ g_irepository_get_namespaces (GIRepository *repository)
repository = get_repository (repository);
g_hash_table_foreach (repository->priv->typelibs, collect_namespaces, &list);
g_hash_table_foreach (repository->priv->lazy_typelibs, collect_namespaces, &list);
names = g_malloc0 (sizeof (gchar *) * (g_list_length (list) + 1));
i = 0;
@ -502,7 +565,7 @@ g_irepository_get_shared_library (GIRepository *repository,
repository = get_repository (repository);
typelib = g_hash_table_lookup (repository->priv->typelibs, namespace);
typelib = get_registered (repository, namespace);
if (!typelib)
return NULL;
header = (Header *) typelib->data;
@ -535,7 +598,12 @@ g_irepository_get_typelib_path (GIRepository *repository,
if (!g_hash_table_lookup_extended (repository->priv->typelibs, namespace,
&orig_key, &value))
{
if (!g_hash_table_lookup_extended (repository->priv->lazy_typelibs, namespace,
&orig_key, &value))
return NULL;
}
return ((char*)orig_key) + strlen ((char *) orig_key) + 1;
}
@ -543,6 +611,7 @@ g_irepository_get_typelib_path (GIRepository *repository,
* g_irepository_require
* @repository: Repository, may be %NULL for the default
* @namespace: GI namespace to use, e.g. "Gtk"
* @flags: Set of %GIRepositoryLoadFlags, may be %0
* @error: a #GError.
*
* Force the namespace @namespace to be loaded if it isn't
@ -555,6 +624,7 @@ g_irepository_get_typelib_path (GIRepository *repository,
gboolean
g_irepository_require (GIRepository *repository,
const gchar *namespace,
GIRepositoryLoadFlags flags,
GError **error)
{
GSList *ldir;
@ -566,13 +636,12 @@ g_irepository_require (GIRepository *repository,
const gchar *typelib_namespace, *shlib_fname;
GModule *module;
guint32 shlib;
GHashTable *table;
gboolean allow_lazy = flags & G_IREPOSITORY_LOAD_FLAG_LAZY;
gboolean is_lazy;
repository = get_repository (repository);
table = repository->priv->typelibs;
/* don't bother loading a namespace if already registered */
if (g_hash_table_lookup (table, namespace))
if (get_registered_status (repository, namespace, allow_lazy, &is_lazy))
return TRUE;
fname = g_strconcat (namespace, ".typelib", NULL);
@ -617,7 +686,8 @@ g_irepository_require (GIRepository *repository,
}
g_free (fname);
if (!register_internal (repository, full_path, typelib, error))
if (!register_internal (repository, full_path, allow_lazy,
typelib, error))
{
g_typelib_free (typelib);
g_free (full_path);

View File

@ -67,6 +67,10 @@ struct _GIRepositoryClass
GObjectClass parent;
};
typedef enum
{
G_IREPOSITORY_LOAD_FLAG_LAZY = 1 << 0
} GIRepositoryLoadFlags;
/* Repository */
@ -75,9 +79,8 @@ GIRepository *g_irepository_get_default (void);
void g_irepository_prepend_search_path (const char *directory);
const char * g_irepository_load_typelib (GIRepository *repository,
GTypelib *typelib,
GIRepositoryLoadFlags flags,
GError **error);
void g_irepository_unregister (GIRepository *repository,
const gchar *namespace);
gboolean g_irepository_is_registered (GIRepository *repository,
const gchar *namespace);
GIBaseInfo * g_irepository_find_by_name (GIRepository *repository,
@ -85,6 +88,7 @@ GIBaseInfo * g_irepository_find_by_name (GIRepository *repository,
const gchar *name);
gboolean g_irepository_require (GIRepository *repository,
const char *namespace,
GIRepositoryLoadFlags flags,
GError **error);
gchar ** g_irepository_get_dependencies (GIRepository *repository,
const char *namespace);