From 911ef7fb4b3bdda8acd6cf57715b9020c65e274c Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Thu, 15 Mar 2018 10:10:54 +0000 Subject: Add as_utils_unique_id_match() This allows us to whitelist the sections that have to match. --- libappstream-glib/as-self-test.c | 16 +++++++++++++++ libappstream-glib/as-utils.c | 42 +++++++++++++++++++++++++++++++++------- libappstream-glib/as-utils.h | 27 ++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 7 deletions(-) diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c index a6edd49..8f4e6e9 100644 --- a/libappstream-glib/as-self-test.c +++ b/libappstream-glib/as-self-test.c @@ -5249,6 +5249,22 @@ as_test_utils_unique_id_func (void) } duration_ns = g_timer_elapsed (timer, NULL) * 1000000000.f; g_print ("%.0f ns: ", duration_ns / (loops * 4)); + + /* allow ignoring using bitfields */ + g_assert (as_utils_unique_id_match ("aa/bb/cc/dd/ee/ff", + "aa/bb/cc/dd/ee/XXXXXXXXXXXXX", + AS_UNIQUE_ID_MATCH_FLAG_SCOPE | + AS_UNIQUE_ID_MATCH_FLAG_BUNDLE_KIND | + AS_UNIQUE_ID_MATCH_FLAG_ORIGIN | + AS_UNIQUE_ID_MATCH_FLAG_KIND | + AS_UNIQUE_ID_MATCH_FLAG_ID)); + g_assert (as_utils_unique_id_match ("XXXXXXXXXXXXX/bb/cc/dd/ee/ff", + "aa/bb/cc/dd/ee/ff", + AS_UNIQUE_ID_MATCH_FLAG_BUNDLE_KIND | + AS_UNIQUE_ID_MATCH_FLAG_ORIGIN | + AS_UNIQUE_ID_MATCH_FLAG_KIND | + AS_UNIQUE_ID_MATCH_FLAG_ID | + AS_UNIQUE_ID_MATCH_FLAG_BRANCH)); } static void diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c index b4e2d8c..eab3242 100644 --- a/libappstream-glib/as-utils.c +++ b/libappstream-glib/as-utils.c @@ -1877,20 +1877,23 @@ as_utils_unique_id_is_wildcard_part (const gchar *str, guint len) } /** - * as_utils_unique_id_equal: + * as_utils_unique_id_match: * @unique_id1: a unique ID * @unique_id2: another unique ID + * @match_flags: a #AsUniqueIdMatchFlags bitfield, e.g. %AS_UNIQUE_ID_MATCH_FLAG_ID * - * Checks two unique IDs for equality allowing globs to match. + * Checks two unique IDs for equality allowing globs to match, whilst also + * allowing clients to whitelist sections that have to match. * * Returns: %TRUE if the ID's should be considered equal. * - * Since: 0.6.1 + * Since: 0.7.8 */ gboolean -as_utils_unique_id_equal (const gchar *unique_id1, const gchar *unique_id2) +as_utils_unique_id_match (const gchar *unique_id1, + const gchar *unique_id2, + AsUniqueIdMatchFlags match_flags) { - guint i; guint last1 = 0; guint last2 = 0; guint len1; @@ -1906,7 +1909,7 @@ as_utils_unique_id_equal (const gchar *unique_id1, const gchar *unique_id2) return g_strcmp0 (unique_id1, unique_id2) == 0; /* look at each part */ - for (i = 0; i < AS_UTILS_UNIQUE_ID_PARTS; i++) { + for (guint i = 0; i < AS_UTILS_UNIQUE_ID_PARTS; i++) { const gchar *tmp1 = unique_id1 + last1; const gchar *tmp2 = unique_id2 + last2; @@ -1915,7 +1918,8 @@ as_utils_unique_id_equal (const gchar *unique_id1, const gchar *unique_id2) len2 = as_utils_unique_id_find_part (tmp2); /* either string was a wildcard */ - if (!as_utils_unique_id_is_wildcard_part (tmp1, len1) && + if (match_flags & (1 << i) && + !as_utils_unique_id_is_wildcard_part (tmp1, len1) && !as_utils_unique_id_is_wildcard_part (tmp2, len2)) { /* are substrings the same */ if (len1 != len2) @@ -1931,6 +1935,30 @@ as_utils_unique_id_equal (const gchar *unique_id1, const gchar *unique_id2) return TRUE; } +/** + * as_utils_unique_id_equal: + * @unique_id1: a unique ID + * @unique_id2: another unique ID + * + * Checks two unique IDs for equality allowing globs to match. + * + * Returns: %TRUE if the ID's should be considered equal. + * + * Since: 0.6.1 + */ +gboolean +as_utils_unique_id_equal (const gchar *unique_id1, const gchar *unique_id2) +{ + return as_utils_unique_id_match (unique_id1, + unique_id2, + AS_UNIQUE_ID_MATCH_FLAG_SCOPE | + AS_UNIQUE_ID_MATCH_FLAG_BUNDLE_KIND | + AS_UNIQUE_ID_MATCH_FLAG_ORIGIN | + AS_UNIQUE_ID_MATCH_FLAG_KIND | + AS_UNIQUE_ID_MATCH_FLAG_ID | + AS_UNIQUE_ID_MATCH_FLAG_BRANCH); +} + /** * as_utils_unique_id_hash: * @unique_id: a unique ID diff --git a/libappstream-glib/as-utils.h b/libappstream-glib/as-utils.h index a8d56a0..ecb7cdd 100644 --- a/libappstream-glib/as-utils.h +++ b/libappstream-glib/as-utils.h @@ -95,6 +95,30 @@ typedef enum { AS_VERSION_PARSE_FLAG_LAST } AsVersionParseFlag; +/** + * AsUniqueIdMatchFlags: + * @AS_UNIQUE_ID_MATCH_FLAG_NONE: No flags set + * @AS_UNIQUE_ID_MATCH_FLAG_SCOPE: Scope, e.g. a #AsAppScope + * @AS_UNIQUE_ID_MATCH_FLAG_BUNDLE_KIND: Bundle kind, e.g. a #AsBundleKind + * @AS_UNIQUE_ID_MATCH_FLAG_ORIGIN: Origin + * @AS_UNIQUE_ID_MATCH_FLAG_KIND: Component kind, e.g. a #AsAppKind + * @AS_UNIQUE_ID_MATCH_FLAG_ID: Component AppStream ID + * @AS_UNIQUE_ID_MATCH_FLAG_BRANCH: Branch + * + * The flags used when matching unique IDs. + **/ +typedef enum { + AS_UNIQUE_ID_MATCH_FLAG_NONE = 0, + AS_UNIQUE_ID_MATCH_FLAG_SCOPE = 1 << 0, + AS_UNIQUE_ID_MATCH_FLAG_BUNDLE_KIND = 1 << 1, /* Since: 0.7.8 */ + AS_UNIQUE_ID_MATCH_FLAG_ORIGIN = 1 << 2, /* Since: 0.7.8 */ + AS_UNIQUE_ID_MATCH_FLAG_KIND = 1 << 3, /* Since: 0.7.8 */ + AS_UNIQUE_ID_MATCH_FLAG_ID = 1 << 4, /* Since: 0.7.8 */ + AS_UNIQUE_ID_MATCH_FLAG_BRANCH = 1 << 5, /* Since: 0.7.8 */ + /*< private >*/ + AS_UNIQUE_ID_MATCH_FLAG_LAST +} AsUniqueIdMatchFlags; + GQuark as_utils_error_quark (void); gboolean as_utils_is_stock_icon_name (const gchar *name); gboolean as_utils_is_spdx_license_id (const gchar *license_id); @@ -146,6 +170,9 @@ gchar *as_utils_unique_id_build (AsAppScope scope, const gchar *branch); gboolean as_utils_unique_id_equal (const gchar *unique_id1, const gchar *unique_id2); +gboolean as_utils_unique_id_match (const gchar *unique_id1, + const gchar *unique_id2, + AsUniqueIdMatchFlags match_flags); gboolean as_utils_unique_id_valid (const gchar *unique_id); guint as_utils_unique_id_hash (const gchar *unique_id); gchar *as_utils_appstream_id_build (const gchar *str); -- cgit v1.2.1