GHashTable *typelibs; /* (string) namespace -> GITypelib */
GHashTable *lazy_typelibs; /* (string) namespace-version -> GITypelib */
GHashTable *info_by_gtype; /* GType -> GIBaseInfo */
+ GHashTable *info_by_error_domain; /* GQuark -> GIBaseInfo */
};
G_DEFINE_TYPE (GIRepository, g_irepository, G_TYPE_OBJECT);
= g_hash_table_new_full (g_direct_hash, g_direct_equal,
(GDestroyNotify) NULL,
(GDestroyNotify) g_base_info_unref);
+ repository->priv->info_by_error_domain
+ = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ (GDestroyNotify) NULL,
+ (GDestroyNotify) g_base_info_unref);
}
static void
g_hash_table_destroy (repository->priv->typelibs);
g_hash_table_destroy (repository->priv->lazy_typelibs);
g_hash_table_destroy (repository->priv->info_by_gtype);
+ g_hash_table_destroy (repository->priv->info_by_error_domain);
(* G_OBJECT_CLASS (g_irepository_parent_class)->finalize) (G_OBJECT (repository));
}
NULL, typelib, entry->offset);
}
+typedef struct {
+ GIRepository *repository;
+ GQuark domain;
+
+ GITypelib *result_typelib;
+ DirEntry *result;
+} FindByErrorDomainData;
+
+static void
+find_by_error_domain_foreach (gpointer key,
+ gpointer value,
+ gpointer datap)
+{
+ GITypelib *typelib = (GITypelib*)value;
+ FindByErrorDomainData *data = datap;
+
+ if (data->result != NULL)
+ return;
+
+ data->result = g_typelib_get_dir_entry_by_error_domain (typelib, data->domain);
+ if (data->result)
+ data->result_typelib = typelib;
+}
+
+/**
+ * g_irepository_find_by_error_domain:
+ * @repository: (allow-none): A #GIRepository, may be %NULL for the default
+ * @domain: a #GError domain
+ *
+ * Searches for the enum type corresponding to the given #GError
+ * domain. Before calling this function for a particular namespace,
+ * you must call g_irepository_require() once to load the namespace, or
+ * otherwise ensure the namespace has already been loaded.
+ *
+ * Returns: (transfer full): #GIEnumInfo representing metadata about @domain's
+ * enum type, or %NULL
+ *
+ * Since: 1.29.17
+ */
+GIEnumInfo *
+g_irepository_find_by_error_domain (GIRepository *repository,
+ GQuark domain)
+{
+ FindByErrorDomainData data;
+ GIEnumInfo *cached;
+
+ repository = get_repository (repository);
+
+ cached = g_hash_table_lookup (repository->priv->info_by_error_domain,
+ GUINT_TO_POINTER (domain));
+
+ if (cached != NULL)
+ return g_base_info_ref ((GIBaseInfo *)cached);
+
+ data.repository = repository;
+ data.domain = domain;
+ data.result_typelib = NULL;
+ data.result = NULL;
+
+ g_hash_table_foreach (repository->priv->typelibs, find_by_error_domain_foreach, &data);
+ if (data.result == NULL)
+ g_hash_table_foreach (repository->priv->lazy_typelibs, find_by_error_domain_foreach, &data);
+
+ if (data.result != NULL)
+ {
+ cached = _g_info_new_full (data.result->blob_type,
+ repository,
+ NULL, data.result_typelib, data.result->offset);
+
+ g_hash_table_insert (repository->priv->info_by_error_domain,
+ GUINT_TO_POINTER (domain),
+ g_base_info_ref (cached));
+ return cached;
+ }
+ return NULL;
+}
+
static void
collect_namespaces (gpointer key,
gpointer value,
return NULL;
}
+DirEntry *
+g_typelib_get_dir_entry_by_error_domain (GITypelib *typelib,
+ GQuark error_domain)
+{
+ Header *header = (Header *)typelib->data;
+ guint n_entries = header->n_local_entries;
+ const char *domain_string = g_quark_to_string (error_domain);
+ DirEntry *entry;
+ guint i;
+
+ for (i = 1; i <= n_entries; i++)
+ {
+ EnumBlob *blob;
+ const char *enum_domain_string;
+
+ entry = g_typelib_get_dir_entry (typelib, i);
+ if (entry->blob_type != BLOB_TYPE_ENUM)
+ continue;
+
+ blob = (EnumBlob *)(&typelib->data[entry->offset]);
+ if (!blob->error_domain)
+ continue;
+
+ enum_domain_string = g_typelib_get_string (typelib, blob->error_domain);
+ if (strcmp (domain_string, enum_domain_string) == 0)
+ return entry;
+ }
+ return NULL;
+}
+
void
g_typelib_check_sanity (void)
{