[gtk/file-filter2: 6/6] filefilter: Cleanups and optimizations
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/file-filter2: 6/6] filefilter: Cleanups and optimizations
- Date: Sun, 5 Jul 2020 19:15:23 +0000 (UTC)
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]