[glib: 3/11] Don't give up too early when collecting mime types




commit a1bfe899abe2e0fab2e8697a5ec30da315117559
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Oct 25 02:55:46 2009 -0400

    Don't give up too early when collecting mime types
    
    Since returning exactly one match has special significance, don't
    give up matching before we've found at least 2 types. Also, make
    sure that we don't return the same mime type more than once.
    Bug 541236.

 gio/xdgmime/xdgmimecache.c | 49 +++++++++++++++++++++++++++++++++++++---------
 gio/xdgmime/xdgmimeglob.c  | 42 +++++++++++++++++++++++++++++++++++----
 2 files changed, 78 insertions(+), 13 deletions(-)
---
diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c
index acaed9d47..58a845b15 100644
--- a/gio/xdgmime/xdgmimecache.c
+++ b/gio/xdgmime/xdgmimecache.c
@@ -428,11 +428,11 @@ cache_glob_lookup_fnmatch (const char *file_name,
            }
        }
 
-      if (n > 0)
-       return n;
+      if (n == n_mime_types)
+       break;
     }
-  
-  return 0;
+
+  return n;
 }
 
 static int
@@ -524,6 +524,7 @@ cache_glob_lookup_suffix (const char *file_name,
 {
   int i, n;
 
+  n = 0;
   for (i = 0; _caches[i]; i++)
     {
       XdgMimeCache *cache = _caches[i];
@@ -570,7 +571,35 @@ ascii_tolower (const char *str)
 }
 
 static int
-cache_glob_lookup_file_name (const char *file_name, 
+filter_out_dupes (MimeWeight mimes[], int n_mimes)
+{
+  int last;
+  int i, j;
+
+  last = n_mimes;
+
+  for (i = 0; i < last; i++)
+    {
+      j = i + 1;
+      while (j < last)
+        {
+          if (strcmp (mimes[i].mime, mimes[j].mime) == 0)
+            {
+              mimes[i].weight = MAX (mimes[i].weight, mimes[j].weight);
+              last--;
+              mimes[j].mime = mimes[last].mime;
+              mimes[j].weight = mimes[last].weight;
+            }
+          else
+            j++;
+        }
+    }
+
+  return last;
+}
+
+static int
+cache_glob_lookup_file_name (const char *file_name,
                             const char *mime_types[],
                             int         n_mime_types)
 {
@@ -603,14 +632,16 @@ cache_glob_lookup_file_name (const char *file_name,
 
   len = strlen (file_name);
   n = cache_glob_lookup_suffix (lower_case, len, FALSE, mimes, n_mimes);
-  if (n == 0)
-    n = cache_glob_lookup_suffix (file_name, len, TRUE, mimes, n_mimes);
+  if (n < 2)
+    n += cache_glob_lookup_suffix (file_name, len, TRUE, mimes + n, n_mimes - n);
 
   /* Last, try fnmatch */
   if (n == 0)
     n = cache_glob_lookup_fnmatch (lower_case, mimes, n_mimes, FALSE);
-  if (n == 0)
-    n = cache_glob_lookup_fnmatch (file_name, mimes, n_mimes, TRUE);
+  if (n < 2)
+    n += cache_glob_lookup_fnmatch (file_name, mimes + n, n_mimes - n, TRUE);
+
+  n = filter_out_dupes (mimes, n);
 
   free (lower_case);
 
diff --git a/gio/xdgmime/xdgmimeglob.c b/gio/xdgmime/xdgmimeglob.c
index 5071418cc..6463837db 100644
--- a/gio/xdgmime/xdgmimeglob.c
+++ b/gio/xdgmime/xdgmimeglob.c
@@ -37,6 +37,10 @@
 #include <string.h>
 #include <fnmatch.h>
 
+#ifndef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
 #ifndef        FALSE
 #define        FALSE   (0)
 #endif
@@ -400,6 +404,34 @@ ascii_tolower (const char *str)
   return lower;
 }
 
+static int
+filter_out_dupes (MimeWeight mimes[], int n_mimes)
+{
+  int last;
+  int i, j;
+
+  last = n_mimes;
+
+  for (i = 0; i < last; i++)
+    {
+      j = i + 1;
+      while (j < last)
+        {
+          if (strcmp (mimes[i].mime, mimes[j].mime) == 0)
+            {
+              mimes[i].weight = MAX (mimes[i].weight, mimes[j].weight);
+              last--;
+              mimes[j].mime = mimes[last].mime;
+              mimes[j].weight = mimes[last].weight;
+            }
+          else
+            j++;
+        }
+    }
+
+  return last;
+}
+
 int
 _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
                                 const char  *file_name,
@@ -446,11 +478,11 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
   len = strlen (file_name);
   n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, lower_case, len, FALSE,
                                            mimes, n_mimes);
-  if (n == 0)
-    n = _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE,
-                                             mimes, n_mimes);
+  if (n < 2)
+    n += _xdg_glob_hash_node_lookup_file_name (glob_hash->simple_node, file_name, len, TRUE,
+                                              mimes + n, n_mimes - n);
 
-  if (n == 0)
+  if (n < 2)
     {
       for (list = glob_hash->full_list; list && n < n_mime_types; list = list->next)
         {
@@ -464,6 +496,8 @@ _xdg_glob_hash_lookup_file_name (XdgGlobHash *glob_hash,
     }
   free (lower_case);
 
+  n = filter_out_dupes (mimes, n);
+
   qsort (mimes, n, sizeof (MimeWeight), compare_mime_weight);
 
   if (n_mime_types < n)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]