diff options
author | Richard Hughes <richard@hughsie.com> | 2014-04-23 15:06:15 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2014-04-23 15:43:18 +0100 |
commit | ba2da8a9d4e4e0b06597ba26355101273655571b (patch) | |
tree | 398b8b176ec440a687efe63efae7d29c5ac528c9 | |
parent | b8f1771ba609adf99bb9ee6c77947de0d2272969 (diff) | |
download | appstream-glib-ba2da8a9d4e4e0b06597ba26355101273655571b.tar.gz |
Add as_app_subsume_full()
This allows us to specify if we want to overwrite values or if the merge should
be a two-way merge.
-rw-r--r-- | libappstream-glib/as-app.c | 112 | ||||
-rw-r--r-- | libappstream-glib/as-app.h | 19 | ||||
-rw-r--r-- | libappstream-glib/as-self-test.c | 18 |
3 files changed, 130 insertions, 19 deletions
diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c index afa4f9d..1708bb5 100644 --- a/libappstream-glib/as-app.c +++ b/libappstream-glib/as-app.c @@ -1279,27 +1279,51 @@ as_app_remove_metadata (AsApp *app, const gchar *key) /******************************************************************************/ + /** - * as_app_subsume: - * @app: a #AsApp instance. - * @donor: the donor. - * - * Copies information from the donor to the application object. - * - * Since: 0.1.0 + * as_app_subsume_dict: **/ -void -as_app_subsume (AsApp *app, AsApp *donor) +static void +as_app_subsume_dict (GHashTable *dest, GHashTable *src, gboolean overwrite) +{ + GList *l; + GList *keys; + const gchar *tmp; + const gchar *key; + const gchar *value; + + keys = g_hash_table_get_keys (src); + for (l = keys; l != NULL; l = l->next) { + key = l->data; + if (!overwrite) { + tmp = g_hash_table_lookup (dest, key); + if (tmp != NULL) + continue; + } + value = g_hash_table_lookup (src, key); + g_hash_table_insert (dest, g_strdup (key), g_strdup (value)); + } + g_list_free (keys); +} + +/** + * as_app_subsume_private: + **/ +static void +as_app_subsume_private (AsApp *app, AsApp *donor, AsAppSubsumeFlags flags) { AsAppPrivate *priv = GET_PRIVATE (donor); + AsAppPrivate *papp = GET_PRIVATE (app); AsScreenshot *ss; const gchar *tmp; + const gchar *key; + gboolean overwrite; guint i; gint percentage; GList *l; - GList *langs; + GList *keys; - g_assert (app != donor); + overwrite = (flags & AS_APP_SUBSUME_FLAG_NO_OVERWRITE) == 0; /* pkgnames */ for (i = 0; i < priv->pkgnames->len; i++) { @@ -1314,13 +1338,25 @@ as_app_subsume (AsApp *app, AsApp *donor) } /* languages */ - langs = g_hash_table_get_keys (priv->languages); - for (l = langs; l != NULL; l = l->next) { - tmp = l->data; - percentage = GPOINTER_TO_INT (g_hash_table_lookup (priv->languages, tmp)); - as_app_add_language (app, percentage, tmp, -1); + keys = g_hash_table_get_keys (priv->languages); + for (l = keys; l != NULL; l = l->next) { + key = l->data; + if (flags & AS_APP_SUBSUME_FLAG_NO_OVERWRITE) { + percentage = as_app_get_language (app, key); + if (percentage > 0) + continue; + } + percentage = GPOINTER_TO_INT (g_hash_table_lookup (priv->languages, key)); + as_app_add_language (app, percentage, key, -1); } - g_list_free (langs); + g_list_free (keys); + + /* dictionaries */ + as_app_subsume_dict (papp->names, priv->names, overwrite); + as_app_subsume_dict (papp->comments, priv->comments, overwrite); + as_app_subsume_dict (papp->descriptions, priv->descriptions, overwrite); + as_app_subsume_dict (papp->metadata, priv->metadata, overwrite); + as_app_subsume_dict (papp->urls, priv->urls, overwrite); /* icon */ if (priv->icon != NULL) @@ -1328,6 +1364,48 @@ as_app_subsume (AsApp *app, AsApp *donor) } /** + * as_app_subsume_full: + * @app: a #AsApp instance. + * @donor: the donor. + * @flags: any optional flags, e.g. %AS_APP_SUBSUME_FLAG_NO_OVERWRITE + * + * Copies information from the donor to the application object. + * + * Since: 0.1.4 + **/ +void +as_app_subsume_full (AsApp *app, AsApp *donor, AsAppSubsumeFlags flags) +{ + g_assert (app != donor); + + /* two way sync implies no overwriting */ + if ((flags & AS_APP_SUBSUME_FLAG_BOTH_WAYS) > 0) + flags |= AS_APP_SUBSUME_FLAG_NO_OVERWRITE; + + /* one way sync */ + as_app_subsume_private (app, donor, flags); + + /* and back again */ + if ((flags & AS_APP_SUBSUME_FLAG_BOTH_WAYS) > 0) + as_app_subsume_private (donor, app, flags); +} + +/** + * as_app_subsume: + * @app: a #AsApp instance. + * @donor: the donor. + * + * Copies information from the donor to the application object. + * + * Since: 0.1.0 + **/ +void +as_app_subsume (AsApp *app, AsApp *donor) +{ + as_app_subsume_full (app, donor, AS_APP_SUBSUME_FLAG_NONE); +} + +/** * gs_app_node_language_sort_cb: **/ static gint diff --git a/libappstream-glib/as-app.h b/libappstream-glib/as-app.h index 16dc027..dcbb2a3 100644 --- a/libappstream-glib/as-app.h +++ b/libappstream-glib/as-app.h @@ -78,6 +78,22 @@ typedef enum { } AsAppParseFlags; /** + * AsAppSubsumeFlags: + * @AS_APP_SUBSUME_FLAG_NONE: No special actions to use + * @AS_APP_SUBSUME_FLAG_NO_OVERWRITE: Do not overwrite already set properties + * @AS_APP_SUBSUME_FLAG_BOTH_WAYS: Copy unset properties both ways + * + * The flags to use when subsuming applications. + **/ +typedef enum { + AS_APP_SUBSUME_FLAG_NONE, + AS_APP_SUBSUME_FLAG_NO_OVERWRITE = 1, /* Since: 0.1.4 */ + AS_APP_SUBSUME_FLAG_BOTH_WAYS = 2, /* Since: 0.1.4 */ + /*< private >*/ + AS_APP_SUBSUME_FLAG_LAST, +} AsAppSubsumeFlags; + +/** * AsAppError: * @AS_APP_ERROR_FAILED: Generic failure * @AS_APP_ERROR_INVALID_TYPE: Invalid type @@ -251,6 +267,9 @@ GPtrArray *as_app_validate (AsApp *app, GError **error); void as_app_subsume (AsApp *app, AsApp *donor); +void as_app_subsume_full (AsApp *app, + AsApp *donor, + AsAppSubsumeFlags flags); guint as_app_search_matches_all (AsApp *app, gchar **search); guint as_app_search_matches (AsApp *app, diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c index d829c53..2b8b369 100644 --- a/libappstream-glib/as-self-test.c +++ b/libappstream-glib/as-self-test.c @@ -945,21 +945,35 @@ ch_test_app_subsume_func (void) AsApp *donor; GList *list; - app = as_app_new (); donor = as_app_new (); as_app_set_icon (donor, "gtk-find", -1); as_app_add_pkgname (donor, "hal", -1); as_app_add_language (donor, -1, "en_GB", -1); + as_app_add_metadata (donor, "donor", "true", -1); + as_app_add_metadata (donor, "overwrite", "1111", -1); /* copy all useful properties */ - as_app_subsume (app, donor); + app = as_app_new (); + as_app_add_metadata (app, "overwrite", "2222", -1); + as_app_add_metadata (app, "recipient", "true", -1); + as_app_subsume_full (app, donor, AS_APP_SUBSUME_FLAG_NO_OVERWRITE); g_assert_cmpstr (as_app_get_icon (app), ==, "gtk-find"); + g_assert_cmpstr (as_app_get_metadata_item (app, "donor"), ==, "true"); + g_assert_cmpstr (as_app_get_metadata_item (app, "overwrite"), ==, "2222"); + g_assert_cmpstr (as_app_get_metadata_item (donor, "recipient"), ==, NULL); g_assert_cmpint (as_app_get_pkgnames(app)->len, ==, 1); list = as_app_get_languages (app); g_assert_cmpint (g_list_length (list), ==, 1); g_list_free (list); + /* test both ways */ + as_app_subsume_full (app, donor, AS_APP_SUBSUME_FLAG_BOTH_WAYS); + g_assert_cmpstr (as_app_get_metadata_item (app, "donor"), ==, "true"); + g_assert_cmpstr (as_app_get_metadata_item (app, "recipient"), ==, "true"); + g_assert_cmpstr (as_app_get_metadata_item (donor, "donor"), ==, "true"); + g_assert_cmpstr (as_app_get_metadata_item (donor, "recipient"), ==, "true"); + g_object_unref (app); g_object_unref (donor); } |