[tracker/threaded-extractor: 13/15] libtracker-extract: Add API to iterate through the modules handling a mimetype
- From: Martyn James Russell <mr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/threaded-extractor: 13/15] libtracker-extract: Add API to iterate through the modules handling a mimetype
- Date: Thu, 7 Jul 2011 10:57:43 +0000 (UTC)
commit f5584097cec5d73ef4bfbb9f7de9e9f5b6e5bebf
Author: Carlos Garnacho <carlos lanedo com>
Date: Fri Jun 24 15:06:32 2011 +0200
libtracker-extract: Add API to iterate through the modules handling a mimetype
There are situations where the most specific miner could just not know
enough about the file, this API allows falling back to less specific
modules.
src/libtracker-extract/tracker-module-manager.c | 262 +++++++++++++++++++----
src/libtracker-extract/tracker-module-manager.h | 12 +
2 files changed, 232 insertions(+), 42 deletions(-)
---
diff --git a/src/libtracker-extract/tracker-module-manager.c b/src/libtracker-extract/tracker-module-manager.c
index b6027e6..910bca3 100644
--- a/src/libtracker-extract/tracker-module-manager.c
+++ b/src/libtracker-extract/tracker-module-manager.c
@@ -38,6 +38,7 @@ typedef struct {
TrackerExtractMetadataFunc extract_func;
TrackerExtractInitFunc init_func;
TrackerExtractShutdownFunc shutdown_func;
+ guint initialized : 1;
} ModuleInfo;
static GHashTable *modules = NULL;
@@ -45,6 +46,13 @@ static GHashTable *mimetype_map = NULL;
static gboolean initialized = FALSE;
static GArray *rules = NULL;
+struct _TrackerMimetypeInfo {
+ const GList *rules;
+ const GList *cur;
+
+ ModuleInfo *cur_module_info;
+};
+
static gboolean
load_extractor_rule (GKeyFile *key_file,
GError **error)
@@ -165,9 +173,10 @@ tracker_extract_module_manager_init (void)
return TRUE;
}
-static RuleInfo *
-lookup_rule (const gchar *mimetype)
+static GList *
+lookup_rules (const gchar *mimetype)
{
+ GList *mimetype_rules = NULL;
RuleInfo *info;
gchar *reversed;
gint len, i;
@@ -176,11 +185,11 @@ lookup_rule (const gchar *mimetype)
return NULL;
}
- if (!mimetype_map) {
- info = g_hash_table_lookup (mimetype_map, mimetype);
+ if (mimetype_map) {
+ mimetype_rules = g_hash_table_lookup (mimetype_map, mimetype);
- if (info) {
- return info;
+ if (mimetype_rules) {
+ return mimetype_rules;
}
}
@@ -197,49 +206,26 @@ lookup_rule (const gchar *mimetype)
for (l = info->patterns; l; l = l->next) {
if (g_pattern_match (l->data, len, mimetype, reversed)) {
/* Match, store for future queries and return */
- g_hash_table_insert (mimetype_map, g_strdup (mimetype), info);
- g_free (reversed);
- return info;
+ mimetype_rules = g_list_prepend (mimetype_rules, info);
}
}
}
+ if (mimetype_rules) {
+ mimetype_rules = g_list_reverse (mimetype_rules);
+ g_hash_table_insert (mimetype_map, g_strdup (mimetype), mimetype_rules);
+ }
+
g_free (reversed);
- return NULL;
+ return mimetype_rules;
}
-GModule *
-tracker_extract_module_manager_get_for_mimetype (const gchar *mimetype,
- TrackerExtractInitFunc *init_func,
- TrackerExtractShutdownFunc *shutdown_func,
- TrackerExtractMetadataFunc *extract_func)
+static ModuleInfo *
+load_module (RuleInfo *info,
+ gboolean initialize)
{
ModuleInfo *module_info = NULL;
- RuleInfo *info;
-
- if (init_func) {
- *init_func = NULL;
- }
-
- if (shutdown_func) {
- *shutdown_func = NULL;
- }
-
- if (extract_func) {
- *extract_func = NULL;
- }
-
- if (!initialized &&
- !tracker_extract_module_manager_init ()) {
- return NULL;
- }
-
- info = lookup_rule (mimetype);
-
- if (!info) {
- return NULL;
- }
if (modules) {
module_info = g_hash_table_lookup (modules, info->module_path);
@@ -284,6 +270,70 @@ tracker_extract_module_manager_get_for_mimetype (const gchar *m
g_hash_table_insert (modules, (gpointer) info->module_path, module_info);
}
+ if (module_info && initialize &&
+ !module_info->initialized) {
+ if (module_info->init_func) {
+ GError *error = NULL;
+
+ if (!(module_info->init_func) (&module_info->thread_awareness, &error)) {
+ g_critical ("Could not initialize module %s: %s",
+ g_module_name (module_info->module),
+ (error) ? error->message : "No error given");
+
+ if (error) {
+ g_error_free (error);
+ }
+
+ return NULL;
+ }
+ } else {
+ module_info->thread_awareness = TRACKER_MODULE_MAIN_THREAD;
+ }
+
+ module_info->initialized = TRUE;
+ }
+
+ return module_info;
+}
+
+GModule *
+tracker_extract_module_manager_get_for_mimetype (const gchar *mimetype,
+ TrackerExtractInitFunc *init_func,
+ TrackerExtractShutdownFunc *shutdown_func,
+ TrackerExtractMetadataFunc *extract_func)
+{
+ ModuleInfo *module_info = NULL;
+ GList *mimetype_rules;
+
+ if (init_func) {
+ *init_func = NULL;
+ }
+
+ if (shutdown_func) {
+ *shutdown_func = NULL;
+ }
+
+ if (extract_func) {
+ *extract_func = NULL;
+ }
+
+ if (!initialized &&
+ !tracker_extract_module_manager_init ()) {
+ return NULL;
+ }
+
+ mimetype_rules = lookup_rules (mimetype);
+
+ if (!mimetype_rules) {
+ return NULL;
+ }
+
+ module_info = load_module (mimetype_rules->data, FALSE);
+
+ if (!module_info) {
+ return NULL;
+ }
+
if (extract_func) {
*extract_func = module_info->extract_func;
}
@@ -302,14 +352,142 @@ tracker_extract_module_manager_get_for_mimetype (const gchar *m
gboolean
tracker_extract_module_manager_mimetype_is_handled (const gchar *mimetype)
{
- RuleInfo *info;
+ GList *mimetype_rules;
if (!initialized &&
!tracker_extract_module_manager_init ()) {
return FALSE;
}
- info = lookup_rule (mimetype);
+ mimetype_rules = lookup_rules (mimetype);
+
+ return mimetype_rules != NULL;
+}
+
+static gboolean
+initialize_first_module (TrackerMimetypeInfo *info)
+{
+ ModuleInfo *module_info = NULL;
+
+ /* Actually iterates through the list loaded + initialized module */
+ while (info->cur && !module_info) {
+ module_info = load_module (info->cur->data, TRUE);
+
+ if (!module_info) {
+ info->cur = info->cur->next;
+ }
+ }
+
+ info->cur_module_info = module_info;
+ return (info->cur_module_info != NULL);
+}
+
+/**
+ * tracker_extract_module_manager_get_mimetype_handlers:
+ * @mimetype: a mimetype string
+ *
+ * Returns a #TrackerMimetypeInfo struct containing information about
+ * the modules that handle @mimetype, or %NULL if no modules handle
+ * @mimetype.
+ *
+ * The modules are ordered from most to least specific, and the
+ * returned #TrackerMimetypeInfo already points to the first
+ * module.
+ *
+ * Returns: (transfer full): (free-function: tracker_mimetype_info_free):
+ * (allow-none): A #TrackerMimetypeInfo holding the information
+ * about the different modules handling @mimetype, or %NULL if
+ * no modules handle @mimetype.
+ **/
+TrackerMimetypeInfo *
+tracker_extract_module_manager_get_mimetype_handlers (const gchar *mimetype)
+{
+ TrackerMimetypeInfo *info;
+ GList *mimetype_rules;
+
+ g_return_val_if_fail (mimetype != NULL, NULL);
+
+ mimetype_rules = lookup_rules (mimetype);
+
+ g_print ("EING: %p\n", mimetype_rules);
+
+ if (!mimetype_rules) {
+ return NULL;
+ }
+
+ info = g_slice_new0 (TrackerMimetypeInfo);
+ info->rules = mimetype_rules;
+ info->cur = info->rules;
+
+ if (!initialize_first_module (info)) {
+ g_print ("NOOOO\n");
+ tracker_mimetype_info_free (info);
+ info = NULL;
+ }
+
+ return info;
+}
+
+/**
+ * tracker_mimetype_info_get_module:
+ * @info: a #TrackerMimetypeInfo
+ * @extract_func: (out): (allow-none): return value for the extraction function
+ * @thread_awareness: (out): (allow-none): thread awareness of the extractor module
+ *
+ * Returns the #GModule that @info is currently pointing to, if @extract_func is
+ * not %NULL, it will be filled in with the pointer to the metadata extraction
+ * function. If @thread_awareness is not %NULL, it will be filled in with the
+ * module thread awareness description.
+ *
+ * Returns: The %GModule currently pointed to by @info.
+ **/
+GModule *
+tracker_mimetype_info_get_module (TrackerMimetypeInfo *info,
+ TrackerExtractMetadataFunc *extract_func,
+ TrackerModuleThreadAwareness *thread_awareness)
+{
+ g_return_val_if_fail (info != NULL, NULL);
+
+ if (!info->cur_module_info) {
+ return NULL;
+ }
+
+ if (extract_func) {
+ *extract_func = info->cur_module_info->extract_func;
+ }
+
+ if (thread_awareness) {
+ *thread_awareness = info->cur_module_info->thread_awareness;
+ }
+
+ return info->cur_module_info->module;
+}
+
+/**
+ * tracker_mimetype_info_iter_next:
+ * @info: a #TrackerMimetypeInfo
+ *
+ * Iterates to the next module handling the mimetype.
+ *
+ * Returns: %TRUE if there is a next module.
+ **/
+gboolean
+tracker_mimetype_info_iter_next (TrackerMimetypeInfo *info)
+{
+ g_return_val_if_fail (info != NULL, FALSE);
+
+ if (info->cur->next) {
+ info->cur = info->cur->next;
+ return initialize_first_module (info);
+ }
+
+ return FALSE;
+}
+
+void
+tracker_mimetype_info_free (TrackerMimetypeInfo *info)
+{
+ g_return_if_fail (info != NULL);
- return info != NULL;
+ g_slice_free (TrackerMimetypeInfo, info);
}
diff --git a/src/libtracker-extract/tracker-module-manager.h b/src/libtracker-extract/tracker-module-manager.h
index 2839548..bc44411 100644
--- a/src/libtracker-extract/tracker-module-manager.h
+++ b/src/libtracker-extract/tracker-module-manager.h
@@ -38,6 +38,8 @@ typedef enum {
TRACKER_MODULE_MULTI_THREAD
} TrackerModuleThreadAwareness;
+typedef struct _TrackerMimetypeInfo TrackerMimetypeInfo;
+
typedef gboolean (* TrackerExtractInitFunc) (TrackerModuleThreadAwareness *thread_awareness_ret,
GError **error);
typedef void (* TrackerExtractShutdownFunc) (void);
@@ -54,8 +56,18 @@ GModule * tracker_extract_module_manager_get_for_mimetype (const gchar
TrackerExtractInitFunc *init_func,
TrackerExtractShutdownFunc *shutdown_func,
TrackerExtractMetadataFunc *extract_func);
+
gboolean tracker_extract_module_manager_mimetype_is_handled (const gchar *mimetype);
+
+TrackerMimetypeInfo * tracker_extract_module_manager_get_mimetype_handlers (const gchar *mimetype);
+
+GModule * tracker_mimetype_info_get_module (TrackerMimetypeInfo *info,
+ TrackerExtractMetadataFunc *extract_func,
+ TrackerModuleThreadAwareness *thread_awareness);
+gboolean tracker_mimetype_info_iter_next (TrackerMimetypeInfo *info);
+void tracker_mimetype_info_free (TrackerMimetypeInfo *info);
+
G_END_DECLS
#endif /* __TRACKER_EXTRACT_MODULE_MANAGER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]