[gtk/file-filter2: 6/6] filefilter: Cleanups and optimizations



commit 5a2f791bddd90f65a2d867ab1df061c3d786b6d2
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jul 5 15:07:36 2020 -0400

    filefilter: Cleanups and optimizations
    
    Make mime-type rules hold multiple types. Store the
    content types, so we don't have to do mime-type -> content-type
    conversion in the match function. Store content types for the
    pixbuf-formats rule as well, so we can avoid memory allocation
    in the match function altogether.

 gtk/gtkfilefilter.c | 256 ++++++++++++++++++++++++++++------------------------
 1 file changed, 136 insertions(+), 120 deletions(-)
---
diff --git a/gtk/gtkfilefilter.c b/gtk/gtkfilefilter.c
index e555190aa4..c2b8bb5537 100644
--- a/gtk/gtkfilefilter.c
+++ b/gtk/gtkfilefilter.c
@@ -108,8 +108,8 @@ struct _FilterRule
   FilterRuleType type;
 
   union {
-    gchar *pattern;
-    gchar *mime_type;
+    char *pattern;
+    char **content_types;
     GSList *pixbuf_formats;
   } u;
 };
@@ -200,14 +200,12 @@ filter_rule_free (FilterRule *rule)
 {
   switch (rule->type)
     {
-    case FILTER_RULE_MIME_TYPE:
-      g_free (rule->u.mime_type);
-      break;
     case FILTER_RULE_PATTERN:
       g_free (rule->u.pattern);
       break;
+    case FILTER_RULE_MIME_TYPE:
     case FILTER_RULE_PIXBUF_FORMATS:
-      g_slist_free (rule->u.pixbuf_formats);
+      g_strfreev (rule->u.content_types);
       break;
     default:
       g_assert_not_reached ();
@@ -541,16 +539,17 @@ file_filter_add_attribute (GtkFileFilter *filter,
  **/
 void
 gtk_file_filter_add_mime_type (GtkFileFilter *filter,
-                              const gchar   *mime_type)
+                               const gchar   *mime_type)
 {
   FilterRule *rule;
-  
+
   g_return_if_fail (GTK_IS_FILE_FILTER (filter));
   g_return_if_fail (mime_type != NULL);
 
   rule = g_slice_new (FilterRule);
   rule->type = FILTER_RULE_MIME_TYPE;
-  rule->u.mime_type = g_strdup (mime_type);
+  rule->u.content_types = g_new0 (char *, 2);
+  rule->u.content_types[0] = g_content_type_from_mime_type (mime_type);
 
   file_filter_add_attribute (filter, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
   file_filter_add_rule (filter, rule);
@@ -594,12 +593,34 @@ void
 gtk_file_filter_add_pixbuf_formats (GtkFileFilter *filter)
 {
   FilterRule *rule;
-  
+  GPtrArray *array;
+  GSList *formats, *l;
+
   g_return_if_fail (GTK_IS_FILE_FILTER (filter));
 
   rule = g_slice_new (FilterRule);
   rule->type = FILTER_RULE_PIXBUF_FORMATS;
-  rule->u.pixbuf_formats = gdk_pixbuf_get_formats ();
+
+  array = g_ptr_array_new ();
+
+  formats = gdk_pixbuf_get_formats ();
+  for (l = formats; l; l = l->next)
+    {
+      int i;
+      char **mime_types;
+
+      mime_types = gdk_pixbuf_format_get_mime_types (l->data);
+
+      for (i = 0; mime_types[i] != NULL; i++)
+        {
+          g_ptr_array_add (array, g_content_type_from_mime_type (mime_types[i]));
+        }
+    }
+  g_slist_free (formats);
+
+  g_ptr_array_add (array, NULL);
+
+  rule->u.content_types = (char **)g_ptr_array_free (array, FALSE);
 
   file_filter_add_attribute (filter, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
   file_filter_add_rule (filter, rule);
@@ -638,61 +659,65 @@ NSArray * _gtk_file_filter_get_as_pattern_nsstrings (GtkFileFilter *filter)
       FilterRule *rule = tmp_list->data;
 
       switch (rule->type)
-       {
-       case FILTER_RULE_MIME_TYPE:
-         {
-           // convert mime-types to UTI
-           NSString *mime_type_nsstring = [NSString stringWithUTF8String: rule->u.mime_type];
-           NSString *uti_nsstring = (NSString *) UTTypeCreatePreferredIdentifierForTag (kUTTagClassMIMEType, 
(CFStringRef) mime_type_nsstring, NULL);
-           if (uti_nsstring == NULL)
-             {
-               [array release];
-               return NULL;
-             }
-           [array addObject:uti_nsstring];
-         }
-         break;
-       case FILTER_RULE_PATTERN:
-         {
-           // patterns will need to be stripped of their leading *.
-           GString *pattern = g_string_new (rule->u.pattern);
-           if (strncmp (pattern->str, "*.", 2) == 0)
-             {
-               pattern = g_string_erase (pattern, 0, 2);
-             }
-           else if (strncmp (pattern->str, "*", 1) == 0)
-             {
-               pattern = g_string_erase (pattern, 0, 1);
-             }
-           gchar *pattern_c = g_string_free (pattern, FALSE);
-           NSString *pattern_nsstring = [NSString stringWithUTF8String:pattern_c];
-           g_free (pattern_c);
-           [pattern_nsstring retain];
-           [array addObject:pattern_nsstring];
-         }
-         break;
-       case FILTER_RULE_PIXBUF_FORMATS:
-         {
-           GSList *list;
-
-           for (list = rule->u.pixbuf_formats; list; list = list->next)
-             {
-               int i;
-               gchar **extensions;
-
-               extensions = gdk_pixbuf_format_get_extensions (list->data);
-
-               for (i = 0; extensions[i] != NULL; i++)
-                 {
-                   NSString *extension = [NSString stringWithUTF8String: extensions[i]];
-                   [extension retain];
-                   [array addObject:extension];
-                 }
-               g_strfreev (extensions);
-             }
-           break;
-         }
-       }
+        {
+        case FILTER_RULE_MIME_TYPE:
+          {
+            // convert mime-types to UTI
+            NSString *mime_type_nsstring = [NSString stringWithUTF8String: rule->u.content_types[0]];
+            NSString *uti_nsstring = (NSString *) UTTypeCreatePreferredIdentifierForTag 
(kUTTagClassMIMEType, (CFStringRef) mime_type_nsstring, NULL);
+            if (uti_nsstring == NULL)
+              {
+                [array release];
+                return NULL;
+              }
+            [array addObject:uti_nsstring];
+          }
+          break;
+
+        case FILTER_RULE_PATTERN:
+          {
+            // patterns will need to be stripped of their leading *.
+            GString *pattern = g_string_new (rule->u.pattern);
+            if (strncmp (pattern->str, "*.", 2) == 0)
+              {
+                pattern = g_string_erase (pattern, 0, 2);
+              }
+            else if (strncmp (pattern->str, "*", 1) == 0)
+              {
+                pattern = g_string_erase (pattern, 0, 1);
+              }
+            gchar *pattern_c = g_string_free (pattern, FALSE);
+            NSString *pattern_nsstring = [NSString stringWithUTF8String:pattern_c];
+            g_free (pattern_c);
+            [pattern_nsstring retain];
+            [array addObject:pattern_nsstring];
+          }
+          break;
+
+        case FILTER_RULE_PIXBUF_FORMATS:
+          {
+            GSList *formats, *l;
+
+            formats = gdk_pixbuf_get_formats ();
+            for (l = formats; l; l = l->next)
+              {
+                int i;
+                gchar **extensions;
+
+                extensions = gdk_pixbuf_format_get_extensions (l->data);
+
+                for (i = 0; extensions[i] != NULL; i++)
+                  {
+                    NSString *extension = [NSString stringWithUTF8String: extensions[i]];
+                    [extension retain];
+                    [array addObject:extension];
+                  }
+                g_strfreev (extensions);
+              }
+            g_slist_free (formats);
+            break;
+          }
+       }
     }
   return array;
 }
@@ -711,35 +736,39 @@ _gtk_file_filter_get_as_patterns (GtkFileFilter      *filter)
       FilterRule *rule = tmp_list->data;
 
       switch (rule->type)
-       {
-       case FILTER_RULE_MIME_TYPE:
+        {
+        case FILTER_RULE_MIME_TYPE:
           g_ptr_array_free (array, TRUE);
           return NULL;
-         break;
-       case FILTER_RULE_PATTERN:
+          break;
+
+        case FILTER_RULE_PATTERN:
           g_ptr_array_add (array, g_strdup (rule->u.pattern));
-         break;
-       case FILTER_RULE_PIXBUF_FORMATS:
-         {
-           GSList *list;
+          break;
+
+        case FILTER_RULE_PIXBUF_FORMATS:
+          {
+            GSList *formats, *l;
 
-           for (list = rule->u.pixbuf_formats; list; list = list->next)
-             {
-               int i;
-               gchar **extensions;
+            formats = gdk_pixbuf_get_formats ();
+            for (l = formats; l; l = l->next)
+              {
+                int i;
+                char **extensions;
 
-               extensions = gdk_pixbuf_format_get_extensions (list->data);
+                extensions = gdk_pixbuf_format_get_extensions (l->data);
 
-               for (i = 0; extensions[i] != NULL; i++)
+                for (i = 0; extensions[i] != NULL; i++)
                   g_ptr_array_add (array, g_strdup_printf ("*.%s", extensions[i]));
 
-               g_strfreev (extensions);
-             }
-           break;
-         }
+                g_strfreev (extensions);
+              }
+            g_slist_free (formats);
+            break;
+          }
         default:
           break;
-       }
+        }
     }
 
   g_ptr_array_add (array, NULL); /* Null terminate */
@@ -786,39 +815,38 @@ gtk_file_filter_match (GtkFilter *filter,
 
       switch (rule->type)
         {
-        case FILTER_RULE_MIME_TYPE:
+        case FILTER_RULE_PATTERN:
           {
-            const char *filter_content_type;
-            char *rule_content_type;
-            gboolean match;
+            const char *display_name;
 
-            filter_content_type = g_file_info_get_content_type (info);
-            if (filter_content_type)
+            display_name = g_file_info_get_display_name (info);
+            if (display_name)
               {
-                rule_content_type = g_content_type_from_mime_type (rule->u.mime_type);
-                match = g_content_type_is_a (filter_content_type, rule_content_type);
-                g_free (rule_content_type);
-
-                if (match)
+                if (_gtk_fnmatch (rule->u.pattern, display_name, FALSE))
                   return TRUE;
               }
           }
           break;
 
-        case FILTER_RULE_PATTERN:
+        case FILTER_RULE_MIME_TYPE:
+        case FILTER_RULE_PIXBUF_FORMATS:
           {
-            const char *display_name;
+            const char *filter_content_type;
 
-            display_name = g_file_info_get_display_name (info);
-            if (display_name)
+            filter_content_type = g_file_info_get_content_type (info);
+            if (filter_content_type)
               {
-                if (_gtk_fnmatch (rule->u.pattern, display_name, FALSE))
-                  return TRUE;
+                int i;
+
+                for (i = 0; rule->u.content_types[i]; i++)
+                  {
+                    if (g_content_type_is_a (filter_content_type, rule->u.content_types[i]))
+                      return TRUE;
+                  }
               }
           }
           break;
 
-        case FILTER_RULE_PIXBUF_FORMATS:
           {
             const char *filter_content_type;
 
@@ -875,32 +903,20 @@ gtk_file_filter_to_gvariant (GtkFileFilter *filter)
   for (l = filter->rules; l; l = l->next)
     {
       FilterRule *rule = l->data;
+      int i;
 
       switch (rule->type)
         {
         case FILTER_RULE_PATTERN:
           g_variant_builder_add (&builder, "(us)", 0, rule->u.pattern);
           break;
+
         case FILTER_RULE_MIME_TYPE:
-          g_variant_builder_add (&builder, "(us)", 1, rule->u.mime_type);
-          break;
         case FILTER_RULE_PIXBUF_FORMATS:
-          {
-           GSList *f;
-
-           for (f = rule->u.pixbuf_formats; f; f = f->next)
-             {
-                GdkPixbufFormat *fmt = f->data;
-                gchar **mime_types;
-                int i;
-
-                mime_types = gdk_pixbuf_format_get_mime_types (fmt);
-                for (i = 0; mime_types[i]; i++)
-                  g_variant_builder_add (&builder, "(us)", 1, mime_types[i]);
-                g_strfreev (mime_types);
-              }
-          }
+          for (i = 0; rule->u.content_types[i]; i++)
+            g_variant_builder_add (&builder, "(us)", 1, rule->u.content_types[i]);
           break;
+
         default:
           break;
         }


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