summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2014-04-23 15:06:15 +0100
committerRichard Hughes <richard@hughsie.com>2014-04-23 15:43:18 +0100
commitba2da8a9d4e4e0b06597ba26355101273655571b (patch)
tree398b8b176ec440a687efe63efae7d29c5ac528c9
parentb8f1771ba609adf99bb9ee6c77947de0d2272969 (diff)
downloadappstream-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.c112
-rw-r--r--libappstream-glib/as-app.h19
-rw-r--r--libappstream-glib/as-self-test.c18
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);
}