mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-21 14:49:16 +02:00
fileinfo: Add g_file_attribute_matcher_subtract()
Added as public API so I can write tests, the use case is local.
This commit is contained in:
parent
60c42f6648
commit
1985d54bb2
@ -365,6 +365,7 @@ g_file_info_set_symlink_target
|
|||||||
g_file_info_set_sort_order
|
g_file_info_set_sort_order
|
||||||
g_file_attribute_matcher_new
|
g_file_attribute_matcher_new
|
||||||
g_file_attribute_matcher_ref
|
g_file_attribute_matcher_ref
|
||||||
|
g_file_attribute_matcher_subtract
|
||||||
g_file_attribute_matcher_unref
|
g_file_attribute_matcher_unref
|
||||||
g_file_attribute_matcher_matches
|
g_file_attribute_matcher_matches
|
||||||
g_file_attribute_matcher_matches_only
|
g_file_attribute_matcher_matches_only
|
||||||
|
@ -2136,7 +2136,7 @@ sub_matcher_matches (SubMatcher *matcher,
|
|||||||
/* Call this function after modifying a matcher.
|
/* Call this function after modifying a matcher.
|
||||||
* It will ensure all the invariants other functions rely on.
|
* It will ensure all the invariants other functions rely on.
|
||||||
*/
|
*/
|
||||||
static void
|
static GFileAttributeMatcher *
|
||||||
matcher_optimize (GFileAttributeMatcher *matcher)
|
matcher_optimize (GFileAttributeMatcher *matcher)
|
||||||
{
|
{
|
||||||
SubMatcher *submatcher, *compare;
|
SubMatcher *submatcher, *compare;
|
||||||
@ -2153,6 +2153,12 @@ matcher_optimize (GFileAttributeMatcher *matcher)
|
|||||||
return matcher;
|
return matcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (matcher->sub_matchers->len == 0)
|
||||||
|
{
|
||||||
|
g_file_attribute_matcher_unref (matcher);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* sort sub_matchers by id (and then mask), so we can bsearch
|
/* sort sub_matchers by id (and then mask), so we can bsearch
|
||||||
* and compare matchers in O(N) instead of O(N²) */
|
* and compare matchers in O(N) instead of O(N²) */
|
||||||
g_array_sort (matcher->sub_matchers, compare_sub_matchers);
|
g_array_sort (matcher->sub_matchers, compare_sub_matchers);
|
||||||
@ -2175,6 +2181,8 @@ matcher_optimize (GFileAttributeMatcher *matcher)
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_array_set_size (matcher->sub_matchers, j + 1);
|
g_array_set_size (matcher->sub_matchers, j + 1);
|
||||||
|
|
||||||
|
return matcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2257,11 +2265,82 @@ g_file_attribute_matcher_new (const char *attributes)
|
|||||||
|
|
||||||
g_strfreev (split);
|
g_strfreev (split);
|
||||||
|
|
||||||
matcher_optimize (matcher);
|
matcher = matcher_optimize (matcher);
|
||||||
|
|
||||||
return matcher;
|
return matcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_file_attribute_matcher_subtract:
|
||||||
|
* @matcher: Matcher to subtract from
|
||||||
|
* @subtract: The matcher to subtract
|
||||||
|
*
|
||||||
|
* Subtracts all attributes of @subtract from @matcher and returns
|
||||||
|
* a matcher that supports those attributes.
|
||||||
|
*
|
||||||
|
* Note that currently it is not possible to remove a single
|
||||||
|
* attribute when the @matcher matches the whole namespace - or remove
|
||||||
|
* a namespace or attribute when the matcher matches everything. This
|
||||||
|
* is a limitation of the current implementation, but may be fixed
|
||||||
|
* in the future.
|
||||||
|
*
|
||||||
|
* Returns: A file attribute matcher matching all attributes of
|
||||||
|
* @matcher that are not matched by @subtract
|
||||||
|
**/
|
||||||
|
GFileAttributeMatcher *
|
||||||
|
g_file_attribute_matcher_subtract (GFileAttributeMatcher *matcher,
|
||||||
|
GFileAttributeMatcher *subtract)
|
||||||
|
{
|
||||||
|
GFileAttributeMatcher *result;
|
||||||
|
guint mi, si;
|
||||||
|
SubMatcher *msub, *ssub;
|
||||||
|
|
||||||
|
if (matcher == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (subtract == NULL)
|
||||||
|
return g_file_attribute_matcher_ref (matcher);
|
||||||
|
if (subtract->all)
|
||||||
|
return NULL;
|
||||||
|
if (matcher->all)
|
||||||
|
return g_file_attribute_matcher_ref (matcher);
|
||||||
|
|
||||||
|
result = g_malloc0 (sizeof (GFileAttributeMatcher));
|
||||||
|
result->ref = 1;
|
||||||
|
result->sub_matchers = g_array_new (FALSE, FALSE, sizeof (SubMatcher));
|
||||||
|
|
||||||
|
si = 0;
|
||||||
|
g_assert (subtract->sub_matchers->len > 0);
|
||||||
|
ssub = &g_array_index (subtract->sub_matchers, SubMatcher, si);
|
||||||
|
|
||||||
|
for (mi = 0; mi < matcher->sub_matchers->len; mi++)
|
||||||
|
{
|
||||||
|
msub = &g_array_index (matcher->sub_matchers, SubMatcher, mi);
|
||||||
|
|
||||||
|
retry:
|
||||||
|
if (sub_matcher_matches (ssub, msub))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
si++;
|
||||||
|
if (si >= subtract->sub_matchers->len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ssub = &g_array_index (subtract->sub_matchers, SubMatcher, si);
|
||||||
|
if (ssub->id <= msub->id)
|
||||||
|
goto retry;
|
||||||
|
|
||||||
|
g_array_append_val (result->sub_matchers, *msub);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mi < matcher->sub_matchers->len)
|
||||||
|
g_array_append_vals (result->sub_matchers,
|
||||||
|
&g_array_index (matcher->sub_matchers, SubMatcher, mi),
|
||||||
|
matcher->sub_matchers->len - mi);
|
||||||
|
|
||||||
|
result = matcher_optimize (result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_file_attribute_matcher_ref:
|
* g_file_attribute_matcher_ref:
|
||||||
* @matcher: a #GFileAttributeMatcher.
|
* @matcher: a #GFileAttributeMatcher.
|
||||||
|
@ -939,6 +939,8 @@ GType g_file_attribute_matcher_get_type (void) G_GNUC_CON
|
|||||||
GFileAttributeMatcher *g_file_attribute_matcher_new (const char *attributes);
|
GFileAttributeMatcher *g_file_attribute_matcher_new (const char *attributes);
|
||||||
GFileAttributeMatcher *g_file_attribute_matcher_ref (GFileAttributeMatcher *matcher);
|
GFileAttributeMatcher *g_file_attribute_matcher_ref (GFileAttributeMatcher *matcher);
|
||||||
void g_file_attribute_matcher_unref (GFileAttributeMatcher *matcher);
|
void g_file_attribute_matcher_unref (GFileAttributeMatcher *matcher);
|
||||||
|
GFileAttributeMatcher *g_file_attribute_matcher_subtract (GFileAttributeMatcher *matcher,
|
||||||
|
GFileAttributeMatcher *subtract);
|
||||||
gboolean g_file_attribute_matcher_matches (GFileAttributeMatcher *matcher,
|
gboolean g_file_attribute_matcher_matches (GFileAttributeMatcher *matcher,
|
||||||
const char *attribute);
|
const char *attribute);
|
||||||
gboolean g_file_attribute_matcher_matches_only (GFileAttributeMatcher *matcher,
|
gboolean g_file_attribute_matcher_matches_only (GFileAttributeMatcher *matcher,
|
||||||
|
@ -431,6 +431,7 @@ g_file_info_set_symlink_target
|
|||||||
g_file_info_set_sort_order
|
g_file_info_set_sort_order
|
||||||
g_file_attribute_matcher_get_type
|
g_file_attribute_matcher_get_type
|
||||||
g_file_attribute_matcher_new
|
g_file_attribute_matcher_new
|
||||||
|
g_file_attribute_matcher_subtract
|
||||||
g_file_attribute_matcher_ref
|
g_file_attribute_matcher_ref
|
||||||
g_file_attribute_matcher_unref
|
g_file_attribute_matcher_unref
|
||||||
g_file_attribute_matcher_matches
|
g_file_attribute_matcher_matches
|
||||||
|
Loading…
x
Reference in New Issue
Block a user