diff --git a/lib/wp/properties.c b/lib/wp/properties.c index 225aafdb54b0f87dc7f052e6ccd9c7f3b869bc49..790b632b7b1b12159b69cc90d1a9b199ce3339c1 100644 --- a/lib/wp/properties.c +++ b/lib/wp/properties.c @@ -40,6 +40,7 @@ #define G_LOG_DOMAIN "wp-properties" #include "properties.h" +#include "private.h" #include <errno.h> #include <pipewire/properties.h> @@ -715,6 +716,121 @@ wp_properties_setf_valist (WpProperties * self, const gchar * key, return pw_properties_setva (self->props, key, format, args); } +struct dict_iterator_data +{ + WpProperties *properties; + const struct spa_dict_item *item; +}; + +static void +dict_iterator_reset (WpIterator *it) +{ + struct dict_iterator_data *it_data = wp_iterator_get_user_data (it); + it_data->item = wp_properties_peek_dict (it_data->properties)->items; +} + +static gboolean +dict_iterator_next (WpIterator *it, GValue *item) +{ + struct dict_iterator_data *it_data = wp_iterator_get_user_data (it); + const struct spa_dict *dict = wp_properties_peek_dict (it_data->properties); + + if ((it_data->item - dict->items) < dict->n_items) { + g_value_init (item, G_TYPE_POINTER); + g_value_set_pointer (item, it_data->item); + it_data->item++; + return TRUE; + } + return FALSE; +} + +static gboolean +dict_iterator_fold (WpIterator *it, WpIteratorFoldFunc func, GValue *ret, + gpointer data) +{ + struct dict_iterator_data *it_data = wp_iterator_get_user_data (it); + const struct spa_dict *dict = wp_properties_peek_dict (it_data->properties); + const struct spa_dict_item *i; + + spa_dict_for_each (i, dict) { + g_auto (GValue) item = G_VALUE_INIT; + g_value_init (&item, G_TYPE_POINTER); + g_value_set_pointer (&item, i); + if (!func (&item, ret, data)) + return FALSE; + } + return TRUE; +} + +static void +dict_iterator_finalize (WpIterator *it) +{ + struct dict_iterator_data *it_data = wp_iterator_get_user_data (it); + wp_properties_unref (it_data->properties); +} + +static const WpIteratorMethods dict_iterator_methods = { + .reset = dict_iterator_reset, + .next = dict_iterator_next, + .fold = dict_iterator_fold, + .finalize = dict_iterator_finalize, +}; + +/** + * wp_properties_iterate: + * @self: a properties object + * + * Returns: (transfer full): an iterator that iterates over the properties. + * Use wp_properties_iterator_item_get_key() and + * wp_properties_iterator_item_get_value() to parse the items returned by + * this iterator. + */ +WpIterator * +wp_properties_iterate (WpProperties * self) +{ + g_autoptr (WpIterator) it = NULL; + struct dict_iterator_data *it_data; + + g_return_val_if_fail (self != NULL, NULL); + + it = wp_iterator_new (&dict_iterator_methods, + sizeof (struct dict_iterator_data)); + it_data = wp_iterator_get_user_data (it); + it_data->properties = wp_properties_ref (self); + it_data->item = wp_properties_peek_dict (it_data->properties)->items; + return g_steal_pointer (&it); +} + +/** + * wp_properties_iterator_item_get_key: + * @item: a #GValue that was returned from the #WpIterator of + * wp_properties_iterate() + * + * Returns: (transfer none): the property key of the @item + */ +const gchar * +wp_properties_iterator_item_get_key (const GValue * item) +{ + const struct spa_dict_item *dict_item = g_value_get_pointer (item); + g_return_val_if_fail (dict_item != NULL, NULL); + return dict_item->key; +} + +/** + * wp_properties_iterator_item_get_value: + * @item: a #GValue that was returned from the #WpIterator of + * wp_properties_iterate() + * + * Returns: (transfer none): the property value of the @item + */ +const gchar * +wp_properties_iterator_item_get_value (const GValue * item) +{ + const struct spa_dict_item *dict_item = g_value_get_pointer (item); + g_return_val_if_fail (dict_item != NULL, NULL); + return dict_item->value; +} + /** * wp_properties_peek_dict: * @self: a properties object diff --git a/lib/wp/properties.h b/lib/wp/properties.h index afa8419ed88be0498610bda782cb7f67f3385da2..3687ca145dbd43a025528069ff0559b464465488 100644 --- a/lib/wp/properties.h +++ b/lib/wp/properties.h @@ -11,6 +11,7 @@ #include <glib-object.h> #include "defs.h" +#include "iterator.h" G_BEGIN_DECLS @@ -132,6 +133,17 @@ WP_API gint wp_properties_setf_valist (WpProperties * self, const gchar * key, const gchar * format, va_list args); +/* iterate */ + +WP_API +WpIterator * wp_properties_iterate (WpProperties * self); + +WP_API +const gchar * wp_properties_iterator_item_get_key (const GValue * item); + +WP_API +const gchar * wp_properties_iterator_item_get_value (const GValue * item); + /* convert */ WP_API