From 1f1c690b42b10f2db1b99254ef14ce56a433f9b4 Mon Sep 17 00:00:00 2001
From: George Kiagiadakis <george.kiagiadakis@collabora.com>
Date: Tue, 31 Mar 2020 12:12:21 +0300
Subject: [PATCH] properties: remove _copy_keys and add update/add methods
 similar to the ones in pw_properties

---
 lib/wp/properties.c         | 217 ++++++++++++++++++++++++++++++++----
 lib/wp/properties.h         |  47 +++++++-
 modules/module-monitor.c    |   6 +-
 modules/module-si-adapter.c |   2 +-
 4 files changed, 242 insertions(+), 30 deletions(-)

diff --git a/lib/wp/properties.c b/lib/wp/properties.c
index 8f173b35..79302e14 100644
--- a/lib/wp/properties.c
+++ b/lib/wp/properties.c
@@ -362,53 +362,226 @@ wp_properties_update_from_dict (WpProperties * self,
 }
 
 /**
- * wp_properties_copy_keys:
- * @src: the source properties set
- * @dst: the destination properties set
- * @key1: a property to copy
- * @...: a list of additional properties to copy, followed by %NULL
+ * wp_properties_add:
+ * @self: a properties object
+ * @props: a properties set that contains properties to add
+ *
+ * Adds new properties in @self, using the given @props as a source.
+ * Properties (keys) from @props that are already contained in @self
+ * are not modified, unlike what happens with wp_properties_update().
+ * Properties in @self that are not contained in @props are left untouched.
+ *
+ * Returns: the number of properties that were changed
+ */
+gint
+wp_properties_add (WpProperties * self, WpProperties * props)
+{
+  g_return_val_if_fail (self != NULL, -EINVAL);
+  g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
+
+  return pw_properties_add (self->props, wp_properties_peek_dict (props));
+}
+
+/**
+ * wp_properties_add_from_dict:
+ * @self: a properties object
+ * @dict: a `spa_dict` that contains properties to add
+ *
+ * Adds new properties in @self, using the given @dict as a source.
+ * Properties (keys) from @dict that are already contained in @self
+ * are not modified, unlike what happens with wp_properties_update_from_dict().
+ * Properties in @self that are not contained in @dict are left untouched.
+ *
+ * Returns: the number of properties that were changed
+ */
+gint
+wp_properties_add_from_dict (WpProperties * self,
+    const struct spa_dict * dict)
+{
+  g_return_val_if_fail (self != NULL, -EINVAL);
+  g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
+
+  return pw_properties_add (self->props, dict);
+}
+
+/**
+ * wp_properties_update_keys:
+ * @self: a properties set
+ * @props: a properties set that contains properties to update
+ * @key1: a property to update
+ * @...: a list of additional properties to update, followed by %NULL
+ *
+ * Updates (adds new or modifies existing) properties in @self, using the
+ * given @props as a source.
+ * Unlike wp_properties_update(), this function only updates properties that
+ * have one of the specified keys; the rest is left untouched.
+ *
+ * Returns: the number of properties that were changed
+ */
+gint
+wp_properties_update_keys (WpProperties * self, WpProperties * props,
+    const gchar * key1, ...)
+{
+  gint changed = 0;
+  const gchar *value;
+
+  g_return_val_if_fail (self != NULL, -EINVAL);
+  g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
+
+  va_list args;
+  va_start (args, key1);
+  for (; key1; key1 = va_arg (args, const gchar *)) {
+    if ((value = wp_properties_get (props, key1)) != NULL)
+      changed += wp_properties_set (self, key1, value);
+  }
+  return changed;
+}
+
+/**
+ * wp_properties_update_keys_from_dict:
+ * @self: a properties set
+ * @dict: a `spa_dict` that contains properties to update
+ * @key1: a property to update
+ * @...: a list of additional properties to update, followed by %NULL
+ *
+ * Updates (adds new or modifies existing) properties in @self, using the
+ * given @dict as a source.
+ * Unlike wp_properties_update_from_dict(), this function only updates
+ * properties that have one of the specified keys; the rest is left untouched.
+ *
+ * Returns: the number of properties that were changed
+ */
+gint
+wp_properties_update_keys_from_dict (WpProperties * self,
+    const struct spa_dict * dict, const gchar * key1, ...)
+{
+  gint changed = 0;
+  const gchar *value;
+
+  g_return_val_if_fail (self != NULL, -EINVAL);
+  g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
+
+  va_list args;
+  va_start (args, key1);
+  for (; key1; key1 = va_arg (args, const gchar *)) {
+    if ((value = spa_dict_lookup (dict, key1)) != NULL)
+      changed += wp_properties_set (self, key1, value);
+  }
+  return changed;
+}
+
+/**
+ * wp_properties_update_keys_array:
+ * @self: a properties set
+ * @props: a properties set that contains properties to update
+ * @keys: (array zero-terminated=1): the properties to update
  *
- * Copies the specified properties from @src to @dst.
+ * The same as wp_properties_update_keys(), using a NULL-terminated array
+ * for specifying the keys to update
  *
  * Returns: the number of properties that were changed
  */
 gint
-wp_properties_copy_keys (WpProperties * src, WpProperties * dst,
-    const gchar *key1, ...)
+wp_properties_update_keys_array (WpProperties * self, WpProperties * props,
+    const gchar * keys[])
 {
-  gint ret;
+  g_return_val_if_fail (self != NULL, -EINVAL);
+  g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
+
+  return pw_properties_update_keys (self->props,
+      wp_properties_peek_dict (props), keys);
+}
+
+/**
+ * wp_properties_add_keys:
+ * @self: a properties set
+ * @props: a properties set that contains properties to add
+ * @key1: a property to add
+ * @...: a list of additional properties to add, followed by %NULL
+ *
+ * Adds new properties in @self, using the given @props as a source.
+ * Unlike wp_properties_add(), this function only adds properties that
+ * have one of the specified keys; the rest is left untouched.
+ *
+ * Returns: the number of properties that were changed
+ */
+gint
+wp_properties_add_keys (WpProperties * self, WpProperties * props,
+    const gchar * key1, ...)
+{
+  gint changed = 0;
+  const gchar *value;
+
+  g_return_val_if_fail (self != NULL, -EINVAL);
+  g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
+
   va_list args;
   va_start (args, key1);
-  ret = wp_properties_copy_keys_valist (src, dst, key1, args);
-  va_end (args);
-  return ret;
+  for (; key1; key1 = va_arg (args, const gchar *)) {
+    if ((value = wp_properties_get (props, key1)) == NULL)
+      continue;
+    if (wp_properties_get (self, key1) == NULL)
+      changed += wp_properties_set (self, key1, value);
+  }
+  return changed;
 }
 
 /**
- * wp_properties_copy_keys_valist:
- * @src: the source properties set
- * @dst: the destination properties set
- * @key1: a property to copy
- * @args: the variable arguments passed to wp_properties_copy_keys()
+ * wp_properties_add_keys_from_dict:
+ * @self: a properties set
+ * @dict: a `spa_dict` that contains properties to add
+ * @key1: a property to add
+ * @...: a list of additional properties to add, followed by %NULL
  *
- * This is the `va_list` version of wp_properties_copy_keys()
+ * Adds new properties in @self, using the given @dict as a source.
+ * Unlike wp_properties_add_from_dict(), this function only adds
+ * properties that have one of the specified keys; the rest is left untouched.
  *
  * Returns: the number of properties that were changed
  */
 gint
-wp_properties_copy_keys_valist (WpProperties * src, WpProperties * dst,
-    const gchar *key1, va_list args)
+wp_properties_add_keys_from_dict (WpProperties * self,
+    const struct spa_dict * dict, const gchar * key1, ...)
 {
   gint changed = 0;
   const gchar *value;
 
+  g_return_val_if_fail (self != NULL, -EINVAL);
+  g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
+
+  va_list args;
+  va_start (args, key1);
   for (; key1; key1 = va_arg (args, const gchar *)) {
-    if ((value = wp_properties_get (src, key1)) != NULL)
-      changed += wp_properties_set (dst, key1, value);
+    if ((value = spa_dict_lookup (dict, key1)) == NULL)
+      continue;
+    if (wp_properties_get (self, key1) == NULL)
+      changed += wp_properties_set (self, key1, value);
   }
   return changed;
 }
 
+/**
+ * wp_properties_add_keys_array:
+ * @self: a properties set
+ * @props: a properties set that contains properties to add
+ * @keys: (array zero-terminated=1): the properties to add
+ *
+ * The same as wp_properties_add_keys(), using a NULL-terminated array
+ * for specifying the keys to add
+ *
+ * Returns: the number of properties that were changed
+ */
+gint
+wp_properties_add_keys_array (WpProperties * self, WpProperties * props,
+    const gchar * keys[])
+{
+  g_return_val_if_fail (self != NULL, -EINVAL);
+  g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
+
+  return pw_properties_add_keys (self->props,
+      wp_properties_peek_dict (props), keys);
+}
+
 /**
  * wp_properties_get:
  * @self: a properties object
diff --git a/lib/wp/properties.h b/lib/wp/properties.h
index 8a5d471e..8d224ce6 100644
--- a/lib/wp/properties.h
+++ b/lib/wp/properties.h
@@ -58,12 +58,16 @@ WpProperties * wp_properties_new_copy_dict (const struct spa_dict * dict);
 WP_API
 WpProperties * wp_properties_copy (WpProperties * other);
 
+/* ref counting */
+
 WP_API
 WpProperties * wp_properties_ref (WpProperties * self);
 
 WP_API
 void wp_properties_unref (WpProperties * self);
 
+/* update */
+
 WP_API
 gint wp_properties_update (WpProperties * self, WpProperties * props);
 
@@ -71,13 +75,44 @@ WP_API
 gint wp_properties_update_from_dict (WpProperties * self,
     const struct spa_dict * dict);
 
+/* add */
+
 WP_API
-gint wp_properties_copy_keys (WpProperties * src, WpProperties * dst,
-    const gchar *key1, ...) G_GNUC_NULL_TERMINATED;
+gint wp_properties_add (WpProperties * self, WpProperties * props);
 
 WP_API
-gint wp_properties_copy_keys_valist (WpProperties * src, WpProperties * dst,
-    const gchar *key1, va_list args);
+gint wp_properties_add_from_dict (WpProperties * self,
+    const struct spa_dict * dict);
+
+/* update keys */
+
+WP_API
+gint wp_properties_update_keys (WpProperties * self, WpProperties * props,
+    const gchar * key1, ...) G_GNUC_NULL_TERMINATED;
+
+WP_API
+gint wp_properties_update_keys_from_dict (WpProperties * self,
+    const struct spa_dict * dict, const gchar * key1, ...) G_GNUC_NULL_TERMINATED;
+
+WP_API
+gint wp_properties_update_keys_array (WpProperties * self, WpProperties * props,
+    const gchar * keys[]);
+
+/* add keys */
+
+WP_API
+gint wp_properties_add_keys (WpProperties * self, WpProperties * props,
+    const gchar * key1, ...) G_GNUC_NULL_TERMINATED;
+
+WP_API
+gint wp_properties_add_keys_from_dict (WpProperties * self,
+    const struct spa_dict * dict, const gchar * key1, ...) G_GNUC_NULL_TERMINATED;
+
+WP_API
+gint wp_properties_add_keys_array (WpProperties * self, WpProperties * props,
+    const gchar * keys[]);
+
+/* get/set */
 
 WP_API
 const gchar * wp_properties_get (WpProperties * self, const gchar * key);
@@ -94,12 +129,16 @@ WP_API
 gint wp_properties_setf_valist (WpProperties * self, const gchar * key,
     const gchar * format, va_list args);
 
+/* convert */
+
 WP_API
 const struct spa_dict * wp_properties_peek_dict (WpProperties * self);
 
 WP_API
 struct pw_properties * wp_properties_to_pw_properties (WpProperties * self);
 
+/* comparison */
+
 WP_API
 gboolean wp_properties_matches (WpProperties * self, WpProperties *other);
 
diff --git a/modules/module-monitor.c b/modules/module-monitor.c
index a8da7e4b..91715be0 100644
--- a/modules/module-monitor.c
+++ b/modules/module-monitor.c
@@ -143,7 +143,7 @@ setup_node_props (WpProperties *dev_props, WpProperties *node_props)
   const gchar *api, *name, *description, *factory;
 
   /* Make the device properties directly available on the node */
-  wp_properties_copy_keys (dev_props, node_props,
+  wp_properties_update_keys (node_props, dev_props,
       SPA_KEY_DEVICE_API,
       SPA_KEY_DEVICE_NAME,
       SPA_KEY_DEVICE_ALIAS,
@@ -198,7 +198,7 @@ setup_node_props (WpProperties *dev_props, WpProperties *node_props)
     wp_properties_setf (node_props, PW_KEY_NODE_DESCRIPTION, "%s: %s",
         description, str);
 
-    wp_properties_copy_keys (dev_props, node_props,
+    wp_properties_update_keys (node_props, dev_props,
         SPA_KEY_API_ALSA_CARD,
         SPA_KEY_API_ALSA_CARD_ID,
         SPA_KEY_API_ALSA_CARD_COMPONENTS,
@@ -221,7 +221,7 @@ setup_node_props (WpProperties *dev_props, WpProperties *node_props)
     wp_properties_setf (node_props, PW_KEY_NODE_DESCRIPTION, "%s (%s)",
         description, profile);
 
-    wp_properties_copy_keys (dev_props, node_props,
+    wp_properties_update_keys (node_props, dev_props,
         SPA_KEY_API_BLUEZ5_PATH,
         SPA_KEY_API_BLUEZ5_ADDRESS,
         NULL);
diff --git a/modules/module-si-adapter.c b/modules/module-si-adapter.c
index e715f172..d38fef7b 100644
--- a/modules/module-si-adapter.c
+++ b/modules/module-si-adapter.c
@@ -424,7 +424,7 @@ si_adapter_get_properties (WpSiEndpoint * item)
 
   /* copy useful properties from the node */
   node_props = wp_proxy_get_properties (WP_PROXY (self->node));
-  wp_properties_copy_keys (node_props, result,
+  wp_properties_update_keys (result, node_props,
       PW_KEY_DEVICE_ID,
       NULL);
 
-- 
GitLab