2019-08-21 15:16:13 +03:00
|
|
|
/* WirePlumber
|
|
|
|
|
*
|
|
|
|
|
* Copyright © 2019 Collabora Ltd.
|
|
|
|
|
* @author George Kiagiadakis <george.kiagiadakis@collabora.com>
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
|
*/
|
|
|
|
|
|
2021-05-21 18:40:43 +03:00
|
|
|
#include "properties.h"
|
log: implement a log topics system, like pipewire
The intention is to make checks for enabled log topics faster.
Every topic has its own structure that is statically defined in the file
where the logs are printed from. The structure is initialized transparently
when it is first used and it contains all the log level flags for the levels
that this topic should print messages. It is then checked on the wp_log()
macro before printing the message.
Topics from SPA/PipeWire are also handled natively, so messages are printed
directly without checking if the topic is enabled, since the PipeWire and SPA
macros do the checking themselves.
Messages coming from GLib are checked inside the handler.
An internal WpLogFields object is used to manage the state of each log
message, populating all the fields appropriately from the place they
are coming from (wp_log, spa_log, glib log), formatting the message and
then printing it. For printing to the journald, we still use the glib
message handler, converting all the needed fields to GLogField on demand.
That message handler does not do any checks for the topic or the level, so
we can just call it to send the message.
2023-05-16 11:51:29 +03:00
|
|
|
#include "log.h"
|
2021-05-21 18:40:43 +03:00
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <pipewire/properties.h>
|
|
|
|
|
|
log: implement a log topics system, like pipewire
The intention is to make checks for enabled log topics faster.
Every topic has its own structure that is statically defined in the file
where the logs are printed from. The structure is initialized transparently
when it is first used and it contains all the log level flags for the levels
that this topic should print messages. It is then checked on the wp_log()
macro before printing the message.
Topics from SPA/PipeWire are also handled natively, so messages are printed
directly without checking if the topic is enabled, since the PipeWire and SPA
macros do the checking themselves.
Messages coming from GLib are checked inside the handler.
An internal WpLogFields object is used to manage the state of each log
message, populating all the fields appropriately from the place they
are coming from (wp_log, spa_log, glib log), formatting the message and
then printing it. For printing to the journald, we still use the glib
message handler, converting all the needed fields to GLogField on demand.
That message handler does not do any checks for the topic or the level, so
we can just call it to send the message.
2023-05-16 11:51:29 +03:00
|
|
|
WP_DEFINE_LOCAL_LOG_TOPIC ("wp-properties")
|
|
|
|
|
|
2021-05-21 18:40:43 +03:00
|
|
|
/*! \defgroup wpproperties WpProperties */
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \struct WpProperties
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* WpProperties is a data structure that contains string key-value pairs,
|
|
|
|
|
* which are used to send/receive/attach arbitrary properties to PipeWire objects.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
|
|
|
|
* This could be thought of as a hash table with strings as both keys and
|
|
|
|
|
* values. However, the reason that this class exists instead of using
|
2021-05-21 18:40:43 +03:00
|
|
|
* GHashTable directly is that in reality it wraps the PipeWire native
|
2020-02-17 15:39:19 +02:00
|
|
|
* `struct spa_dict` and `struct pw_properties` and therefore it can be
|
|
|
|
|
* easily passed to PipeWire function calls that require a `struct spa_dict *`
|
|
|
|
|
* or a `struct pw_properties *` as arguments. Or alternatively, it can easily
|
|
|
|
|
* wrap a `struct spa_dict *` or a `struct pw_properties *` that was given
|
|
|
|
|
* from the PipeWire API without necessarily doing an expensive copy operation.
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* WpProperties normally wraps a `struct pw_properties`, unless it was created
|
|
|
|
|
* with wp_properties_new_wrap_dict(), in which case it wraps a
|
2020-02-17 15:39:19 +02:00
|
|
|
* `struct spa_dict` and it is immutable (you cannot add/remove/modify any
|
|
|
|
|
* key-value pair).
|
|
|
|
|
*
|
|
|
|
|
* In most cases, it actually owns the `struct pw_properties`
|
|
|
|
|
* internally and manages its lifetime. The exception to that rule is when
|
2021-05-21 18:40:43 +03:00
|
|
|
* WpProperties is constructed with wp_properties_new_wrap(), in which case
|
|
|
|
|
* the ownership of the `struct pw_properties` remains outside. This must
|
2020-02-17 15:39:19 +02:00
|
|
|
* be used with care, as the `struct pw_properties` may be free'ed externally.
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* WpProperties is reference-counted with wp_properties_ref() and
|
2020-02-17 15:39:19 +02:00
|
|
|
* wp_properties_unref().
|
|
|
|
|
*/
|
|
|
|
|
|
2019-08-21 15:16:13 +03:00
|
|
|
enum {
|
|
|
|
|
FLAG_IS_DICT = (1<<1),
|
|
|
|
|
FLAG_NO_OWNERSHIP = (1<<2),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _WpProperties
|
|
|
|
|
{
|
2020-03-31 12:51:32 +03:00
|
|
|
grefcount ref;
|
2019-08-21 15:16:13 +03:00
|
|
|
guint32 flags;
|
|
|
|
|
union {
|
|
|
|
|
struct pw_properties *props;
|
|
|
|
|
const struct spa_dict *dict;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
G_DEFINE_BOXED_TYPE(WpProperties, wp_properties, wp_properties_ref, wp_properties_unref)
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Creates a new empty properties set
|
|
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_new_empty (void)
|
|
|
|
|
{
|
2020-03-31 12:51:32 +03:00
|
|
|
WpProperties * self = g_slice_new0 (WpProperties);
|
|
|
|
|
g_ref_count_init (&self->ref);
|
2019-08-21 15:16:13 +03:00
|
|
|
self->flags = 0;
|
|
|
|
|
self->props = pw_properties_new (NULL, NULL);
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Constructs a new properties set that contains the given properties
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param key a property name
|
|
|
|
|
* \param ... a property value, followed by any number of further property
|
|
|
|
|
* key-value pairs, followed by NULL
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_new (const gchar * key, ...)
|
|
|
|
|
{
|
|
|
|
|
WpProperties * self;
|
|
|
|
|
va_list varargs;
|
|
|
|
|
|
|
|
|
|
va_start(varargs, key);
|
|
|
|
|
self = wp_properties_new_valist (key, varargs);
|
|
|
|
|
va_end(varargs);
|
|
|
|
|
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief This is the `va_list` version of wp_properties_new()
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param key a property name
|
|
|
|
|
* \param args the variable arguments passed to wp_properties_new()
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
2020-02-17 15:39:19 +02:00
|
|
|
wp_properties_new_valist (const gchar * key, va_list args)
|
2019-08-21 15:16:13 +03:00
|
|
|
{
|
|
|
|
|
WpProperties * self = wp_properties_new_empty ();
|
|
|
|
|
const gchar *value;
|
|
|
|
|
|
|
|
|
|
while (key != NULL) {
|
2020-02-17 15:39:19 +02:00
|
|
|
value = va_arg(args, gchar *);
|
2019-08-21 15:16:13 +03:00
|
|
|
if (value && key[0])
|
|
|
|
|
wp_properties_set (self, key, value);
|
2020-02-17 15:39:19 +02:00
|
|
|
key = va_arg(args, gchar *);
|
2019-08-21 15:16:13 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Constructs a new properties set that contains the properties that can
|
2020-02-17 15:39:19 +02:00
|
|
|
* be parsed from the given string
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
2023-11-07 20:24:12 +02:00
|
|
|
* \param str a string containing either a whitespace separated list of key=value
|
|
|
|
|
* pairs (ex. "key1=value1 key2=value2") or a JSON object (ex. '{"key1":"value1"}')
|
2021-05-21 18:40:43 +03:00
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_new_string (const gchar * str)
|
|
|
|
|
{
|
|
|
|
|
WpProperties * self;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (str != NULL, NULL);
|
|
|
|
|
|
2020-03-31 12:51:32 +03:00
|
|
|
self = g_slice_new0 (WpProperties);
|
|
|
|
|
g_ref_count_init (&self->ref);
|
2019-08-21 15:16:13 +03:00
|
|
|
self->flags = 0;
|
|
|
|
|
self->props = pw_properties_new_string (str);
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-12 23:44:00 +03:00
|
|
|
/*!
|
|
|
|
|
* \brief Constructs a new properties set that contains the properties that can
|
|
|
|
|
* be parsed from the given JSON object
|
|
|
|
|
*
|
|
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param json a JSON object
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
|
|
|
|
*/
|
|
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_new_json (const WpSpaJson * json)
|
|
|
|
|
{
|
|
|
|
|
WpProperties * self;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (json != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
self = wp_properties_new_empty ();
|
|
|
|
|
wp_properties_update_from_json (self, json);
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Constructs a new WpProperties that wraps the given \a props structure,
|
|
|
|
|
* allowing reading properties on that \a props structure through
|
|
|
|
|
* the WpProperties API.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* Care must be taken when using this function, since the returned WpProperties
|
|
|
|
|
* object does not own the \a props structure. Therefore, if the owner decides
|
|
|
|
|
* to free \a props, the returned WpProperties will crash when used. In addition,
|
|
|
|
|
* the returned WpProperties object will not try to free \a props when destroyed.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* Furthermore, note that the returned WpProperties object is immutable. That
|
2020-06-15 17:20:10 +03:00
|
|
|
* means that you cannot add or modify any properties on it, unless you make
|
|
|
|
|
* a copy first.
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param props a native `pw_properties` structure to wrap
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
2020-06-15 17:20:10 +03:00
|
|
|
wp_properties_new_wrap (const struct pw_properties * props)
|
2019-08-21 15:16:13 +03:00
|
|
|
{
|
|
|
|
|
WpProperties * self;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (props != NULL, NULL);
|
|
|
|
|
|
2020-03-31 12:51:32 +03:00
|
|
|
self = g_slice_new0 (WpProperties);
|
|
|
|
|
g_ref_count_init (&self->ref);
|
2019-08-21 15:16:13 +03:00
|
|
|
self->flags = FLAG_NO_OWNERSHIP;
|
2020-06-15 17:20:10 +03:00
|
|
|
self->props = (struct pw_properties *) props;
|
2019-08-21 15:16:13 +03:00
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Constructs a new WpProperties that wraps the given \a props structure,
|
|
|
|
|
* allowing reading & writing properties on that \a props structure through
|
|
|
|
|
* the WpProperties API.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2024-11-07 21:49:33 +00:00
|
|
|
* In contrast with wp_properties_new_wrap(), this function assumes ownership
|
2021-05-21 18:40:43 +03:00
|
|
|
* of the \a props structure, so it will try to free \a props when it is destroyed.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param props a native `pw_properties` structure to wrap
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_new_take (struct pw_properties * props)
|
|
|
|
|
{
|
|
|
|
|
WpProperties * self;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (props != NULL, NULL);
|
|
|
|
|
|
2020-03-31 12:51:32 +03:00
|
|
|
self = g_slice_new0 (WpProperties);
|
|
|
|
|
g_ref_count_init (&self->ref);
|
2019-08-21 15:16:13 +03:00
|
|
|
self->flags = 0;
|
|
|
|
|
self->props = props;
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Constructs a new WpProperties that contains a copy of all the properties
|
|
|
|
|
* contained in the given \a props structure.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param props a native `pw_properties` structure to copy
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_new_copy (const struct pw_properties * props)
|
|
|
|
|
{
|
|
|
|
|
WpProperties * self;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (props != NULL, NULL);
|
|
|
|
|
|
2020-03-31 12:51:32 +03:00
|
|
|
self = g_slice_new0 (WpProperties);
|
|
|
|
|
g_ref_count_init (&self->ref);
|
2019-08-21 15:16:13 +03:00
|
|
|
self->flags = 0;
|
|
|
|
|
self->props = pw_properties_copy (props);
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Constructs a new WpProperties that wraps the given \a dict structure,
|
|
|
|
|
* allowing reading properties from that \a dict through the WpProperties API.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* Note that the returned object does not own the \a dict, so care must be taken
|
|
|
|
|
* not to free it externally while this WpProperties object is alive.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* In addition, note that the returned WpProperties object is immutable. That
|
2020-02-17 15:39:19 +02:00
|
|
|
* means that you cannot add or modify any properties on it, since there is
|
|
|
|
|
* no defined method for modifying a `struct spa_dict`. If you need to change
|
|
|
|
|
* this properties set later, you should make a copy with wp_properties_copy().
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param dict a native `spa_dict` structure to wrap
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_new_wrap_dict (const struct spa_dict * dict)
|
|
|
|
|
{
|
|
|
|
|
WpProperties * self;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (dict != NULL, NULL);
|
|
|
|
|
|
2020-03-31 12:51:32 +03:00
|
|
|
self = g_slice_new0 (WpProperties);
|
|
|
|
|
g_ref_count_init (&self->ref);
|
2019-08-21 15:16:13 +03:00
|
|
|
self->flags = FLAG_NO_OWNERSHIP | FLAG_IS_DICT;
|
|
|
|
|
self->dict = dict;
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Constructs a new WpProperties that contains a copy of all the
|
|
|
|
|
* properties contained in the given \a dict structure.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param dict a native `spa_dict` structure to copy
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_new_copy_dict (const struct spa_dict * dict)
|
|
|
|
|
{
|
|
|
|
|
WpProperties * self;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (dict != NULL, NULL);
|
|
|
|
|
|
2020-03-31 12:51:32 +03:00
|
|
|
self = g_slice_new0 (WpProperties);
|
|
|
|
|
g_ref_count_init (&self->ref);
|
2019-08-21 15:16:13 +03:00
|
|
|
self->flags = 0;
|
|
|
|
|
self->props = pw_properties_new_dict (dict);
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Constructs and returns a new WpProperties object that contains a copy
|
|
|
|
|
* of all the properties contained in \a other.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param other a properties object
|
|
|
|
|
* \returns (transfer full): the newly constructed properties set
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2021-05-13 17:54:58 +03:00
|
|
|
|
2019-08-29 19:41:04 +03:00
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_copy (WpProperties * other)
|
|
|
|
|
{
|
|
|
|
|
return wp_properties_new_copy_dict (wp_properties_peek_dict (other));
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-21 15:16:13 +03:00
|
|
|
static void
|
|
|
|
|
wp_properties_free (WpProperties * self)
|
|
|
|
|
{
|
|
|
|
|
if (!(self->flags & FLAG_NO_OWNERSHIP))
|
|
|
|
|
pw_properties_free (self->props);
|
2020-03-31 12:51:32 +03:00
|
|
|
g_slice_free (WpProperties, self);
|
2019-08-21 15:16:13 +03:00
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \returns (transfer full): \a self with an additional reference count on it
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_ref (WpProperties * self)
|
|
|
|
|
{
|
2020-03-31 12:51:32 +03:00
|
|
|
g_ref_count_inc (&self->ref);
|
|
|
|
|
return self;
|
2019-08-21 15:16:13 +03:00
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Decreases the reference count on \a self and frees it when the ref
|
|
|
|
|
* count reaches zero.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self (transfer full): a properties object
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
void
|
|
|
|
|
wp_properties_unref (WpProperties * self)
|
|
|
|
|
{
|
2020-03-31 12:51:32 +03:00
|
|
|
if (g_ref_count_dec (&self->ref))
|
|
|
|
|
wp_properties_free (self);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Ensures that the given properties set is uniquely owned.
|
2020-03-31 12:51:32 +03:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* "Uniquely owned" means that:
|
2020-03-31 12:51:32 +03:00
|
|
|
* - its reference count is 1
|
|
|
|
|
* - it is not wrapping a native `spa_dict` or `pw_properties` object
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* If \a self is not uniquely owned already, then it is unrefed and a copy of
|
|
|
|
|
* it is returned instead. You should always consider \a self as unsafe to use
|
2020-03-31 12:51:32 +03:00
|
|
|
* after this call and you should use the returned object instead.
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self (transfer full): a properties object
|
|
|
|
|
* \returns (transfer full): the uniquely owned properties object
|
2020-03-31 12:51:32 +03:00
|
|
|
*/
|
|
|
|
|
WpProperties *
|
|
|
|
|
wp_properties_ensure_unique_owner (WpProperties * self)
|
|
|
|
|
{
|
|
|
|
|
if (!g_ref_count_compare (&self->ref, 1) ||
|
|
|
|
|
self->flags & (FLAG_IS_DICT | FLAG_NO_OWNERSHIP))
|
|
|
|
|
{
|
|
|
|
|
WpProperties *copy = wp_properties_copy (self);
|
|
|
|
|
wp_properties_unref (self);
|
|
|
|
|
return copy;
|
|
|
|
|
}
|
|
|
|
|
return self;
|
2019-08-21 15:16:13 +03:00
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Updates (adds new or modifies existing) properties in \a self,
|
|
|
|
|
* using the given \a props as a source.
|
2020-03-31 11:07:28 +03:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* Any properties that are not contained in \a props are left untouched.
|
2020-03-31 11:07:28 +03:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param props a properties set that contains properties to update
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-03-31 11:07:28 +03:00
|
|
|
*/
|
|
|
|
|
gint
|
|
|
|
|
wp_properties_update (WpProperties * self, WpProperties * props)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, -EINVAL);
|
|
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2020-03-31 11:07:28 +03:00
|
|
|
|
|
|
|
|
return pw_properties_update (self->props, wp_properties_peek_dict (props));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Updates (adds new or modifies existing) properties in \a self,
|
|
|
|
|
* using the given \a dict as a source.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* Any properties that are not contained in \a dict are left untouched.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param dict a `spa_dict` that contains properties to update
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-29 19:41:04 +03:00
|
|
|
gint
|
|
|
|
|
wp_properties_update_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);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2019-08-29 19:41:04 +03:00
|
|
|
|
|
|
|
|
return pw_properties_update (self->props, dict);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-12 23:44:00 +03:00
|
|
|
/*!
|
|
|
|
|
* \brief Updates (adds new or modifies existing) properties in \a self,
|
|
|
|
|
* using the given \a json as a source.
|
|
|
|
|
*
|
|
|
|
|
* Any properties that are not contained in \a json are left untouched.
|
|
|
|
|
*
|
|
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param json a JSON object that contains properties to update
|
|
|
|
|
* \returns the number of properties that were changed
|
|
|
|
|
*/
|
|
|
|
|
gint
|
|
|
|
|
wp_properties_update_from_json (WpProperties * self, const WpSpaJson * json)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, -EINVAL);
|
|
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
|
|
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
|
|
|
|
|
|
|
|
|
return pw_properties_update_string (self->props, wp_spa_json_get_data (json),
|
|
|
|
|
wp_spa_json_get_size (json));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Adds new properties in \a self, using the given \a props as a source.
|
2020-03-31 12:12:21 +03:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* Properties (keys) from \a props that are already contained in \a self
|
2020-03-31 12:12:21 +03:00
|
|
|
* are not modified, unlike what happens with wp_properties_update().
|
2021-05-21 18:40:43 +03:00
|
|
|
* Properties in \a self that are not contained in \a props are left untouched.
|
2020-03-31 12:12:21 +03:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param props a properties set that contains properties to add
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-03-31 12:12:21 +03:00
|
|
|
*/
|
|
|
|
|
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);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2020-03-31 12:12:21 +03:00
|
|
|
|
|
|
|
|
return pw_properties_add (self->props, wp_properties_peek_dict (props));
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Adds new properties in \a self, using the given \a dict as a source.
|
2020-03-31 12:12:21 +03:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* Properties (keys) from \a dict that are already contained in \a self
|
2020-03-31 12:12:21 +03:00
|
|
|
* are not modified, unlike what happens with wp_properties_update_from_dict().
|
2021-05-21 18:40:43 +03:00
|
|
|
* Properties in \a self that are not contained in \a dict are left untouched.
|
2020-03-31 12:12:21 +03:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param dict a `spa_dict` that contains properties to add
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-03-31 12:12:21 +03:00
|
|
|
*/
|
|
|
|
|
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);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2020-03-31 12:12:21 +03:00
|
|
|
|
|
|
|
|
return pw_properties_add (self->props, dict);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Updates (adds new or modifies existing) properties in \a self,
|
|
|
|
|
* using the given \a props as a source.
|
2020-03-31 12:12:21 +03:00
|
|
|
*
|
|
|
|
|
* Unlike wp_properties_update(), this function only updates properties that
|
|
|
|
|
* have one of the specified keys; the rest is left untouched.
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties set
|
|
|
|
|
* \param props a properties set that contains properties to update
|
|
|
|
|
* \param key1 a property to update
|
|
|
|
|
* \param ... a list of additional properties to update, followed by NULL
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-03-31 12:12:21 +03:00
|
|
|
*/
|
|
|
|
|
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);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2020-03-31 12:12:21 +03:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2021-06-15 17:43:22 +03:00
|
|
|
va_end (args);
|
2020-03-31 12:12:21 +03:00
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Updates (adds new or modifies existing) properties in \a self,
|
|
|
|
|
* using the given \a dict as a source.
|
2020-03-31 12:12:21 +03:00
|
|
|
*
|
|
|
|
|
* Unlike wp_properties_update_from_dict(), this function only updates
|
|
|
|
|
* properties that have one of the specified keys; the rest is left untouched.
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties set
|
|
|
|
|
* \param dict a `spa_dict` that contains properties to update
|
|
|
|
|
* \param key1 a property to update
|
|
|
|
|
* \param ... a list of additional properties to update, followed by NULL
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-03-31 12:12:21 +03:00
|
|
|
*/
|
|
|
|
|
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);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2020-03-31 12:12:21 +03:00
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
2021-06-15 17:43:22 +03:00
|
|
|
va_end (args);
|
2020-03-31 12:12:21 +03:00
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief The same as wp_properties_update_keys(), using a NULL-terminated array
|
2020-03-31 12:12:21 +03:00
|
|
|
* for specifying the keys to update
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties set
|
|
|
|
|
* \param props a properties set that contains properties to update
|
|
|
|
|
* \param keys (array zero-terminated=1): the properties to update
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-09-12 16:05:40 +03:00
|
|
|
gint
|
2020-03-31 12:12:21 +03:00
|
|
|
wp_properties_update_keys_array (WpProperties * self, WpProperties * props,
|
|
|
|
|
const gchar * keys[])
|
2019-09-12 16:05:40 +03:00
|
|
|
{
|
2020-03-31 12:12:21 +03:00
|
|
|
g_return_val_if_fail (self != NULL, -EINVAL);
|
|
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2020-03-31 12:12:21 +03:00
|
|
|
|
|
|
|
|
return pw_properties_update_keys (self->props,
|
|
|
|
|
wp_properties_peek_dict (props), keys);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Adds new properties in \a self, using the given \a props as a source.
|
2020-03-31 12:12:21 +03:00
|
|
|
*
|
|
|
|
|
* Unlike wp_properties_add(), this function only adds properties that
|
|
|
|
|
* have one of the specified keys; the rest is left untouched.
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties set
|
|
|
|
|
* \param props a properties set that contains properties to add
|
|
|
|
|
* \param key1 a property to add
|
|
|
|
|
* \param ... a list of additional properties to add, followed by NULL
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-03-31 12:12:21 +03:00
|
|
|
*/
|
|
|
|
|
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);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2020-03-31 12:12:21 +03:00
|
|
|
|
2019-09-12 16:05:40 +03:00
|
|
|
va_list args;
|
|
|
|
|
va_start (args, key1);
|
2020-03-31 12:12:21 +03:00
|
|
|
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);
|
|
|
|
|
}
|
2021-06-15 17:43:22 +03:00
|
|
|
va_end (args);
|
2020-03-31 12:12:21 +03:00
|
|
|
return changed;
|
2019-09-12 16:05:40 +03:00
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Adds new properties in \a self, using the given \a dict as a source.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2020-03-31 12:12:21 +03:00
|
|
|
* Unlike wp_properties_add_from_dict(), this function only adds
|
|
|
|
|
* properties that have one of the specified keys; the rest is left untouched.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties set
|
|
|
|
|
* \param dict a `spa_dict` that contains properties to add
|
|
|
|
|
* \param key1 a property to add
|
|
|
|
|
* \param ... a list of additional properties to add, followed by NULL
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-09-12 16:05:40 +03:00
|
|
|
gint
|
2020-03-31 12:12:21 +03:00
|
|
|
wp_properties_add_keys_from_dict (WpProperties * self,
|
|
|
|
|
const struct spa_dict * dict, const gchar * key1, ...)
|
2019-09-12 16:05:40 +03:00
|
|
|
{
|
|
|
|
|
gint changed = 0;
|
|
|
|
|
const gchar *value;
|
|
|
|
|
|
2020-03-31 12:12:21 +03:00
|
|
|
g_return_val_if_fail (self != NULL, -EINVAL);
|
|
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2020-03-31 12:12:21 +03:00
|
|
|
|
|
|
|
|
va_list args;
|
|
|
|
|
va_start (args, key1);
|
2019-09-12 16:05:40 +03:00
|
|
|
for (; key1; key1 = va_arg (args, const gchar *)) {
|
2020-03-31 12:12:21 +03:00
|
|
|
if ((value = spa_dict_lookup (dict, key1)) == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
if (wp_properties_get (self, key1) == NULL)
|
|
|
|
|
changed += wp_properties_set (self, key1, value);
|
2019-09-12 16:05:40 +03:00
|
|
|
}
|
2021-06-15 17:43:22 +03:00
|
|
|
va_end (args);
|
2019-09-12 16:05:40 +03:00
|
|
|
return changed;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief The same as wp_properties_add_keys(), using a NULL-terminated array
|
2020-03-31 12:12:21 +03:00
|
|
|
* for specifying the keys to add
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties set
|
|
|
|
|
* \param props a properties set that contains properties to add
|
|
|
|
|
* \param keys (array zero-terminated=1): the properties to add
|
|
|
|
|
* \returns the number of properties that were changed
|
2020-03-31 12:12:21 +03:00
|
|
|
*/
|
|
|
|
|
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);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2020-03-31 12:12:21 +03:00
|
|
|
|
|
|
|
|
return pw_properties_add_keys (self->props,
|
|
|
|
|
wp_properties_peek_dict (props), keys);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-06-01 19:39:13 -04:00
|
|
|
* \brief Looks up a given property value from a key
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param key a property key
|
|
|
|
|
* \returns (transfer none) (nullable): the value of the property identified
|
|
|
|
|
* with \a key, or NULL if this property is not contained in \a self
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
const gchar *
|
|
|
|
|
wp_properties_get (WpProperties * self, const gchar * key)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
g_return_val_if_fail (key != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
return spa_dict_lookup (wp_properties_peek_dict (self), key);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Sets the given property \a key - \a value pair on \a self.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* If the property already existed, the value is overwritten with the new one.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* If the \a value is NULL, then the specified property is removed from \a self
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param key a property key
|
|
|
|
|
* \param value (nullable): a property value
|
|
|
|
|
* \returns 1 if the property was changed. 0 if nothing was changed because
|
2020-02-17 15:39:19 +02:00
|
|
|
* the property already existed with the same value or because the key to
|
|
|
|
|
* remove did not exist.
|
|
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
gint
|
|
|
|
|
wp_properties_set (WpProperties * self, const gchar * key,
|
|
|
|
|
const gchar * value)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, -EINVAL);
|
|
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2019-08-21 15:16:13 +03:00
|
|
|
|
|
|
|
|
return pw_properties_set (self->props, key, value);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Formats the given \a format string with the specified arguments
|
|
|
|
|
* and sets the result as a value of the property specified with \a key
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param key a property key
|
|
|
|
|
* \param format a printf-style format to be formatted and set as a value for
|
|
|
|
|
* this property \a key
|
|
|
|
|
* \param ... arguments for \a format
|
|
|
|
|
* \returns 1 if the property was changed. 0 if nothing was changed because
|
2020-02-17 15:39:19 +02:00
|
|
|
* the property already existed with the same value
|
|
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
gint
|
|
|
|
|
wp_properties_setf (WpProperties * self, const gchar * key,
|
|
|
|
|
const gchar * format, ...)
|
|
|
|
|
{
|
|
|
|
|
gint res;
|
|
|
|
|
va_list varargs;
|
|
|
|
|
|
|
|
|
|
va_start (varargs, format);
|
|
|
|
|
res = wp_properties_setf_valist (self, key, format, varargs);
|
|
|
|
|
va_end (varargs);
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief This is the `va_list` version of wp_properties_setf()
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param key a property key
|
|
|
|
|
* \param format a printf-style format to be formatted and set as a value for
|
|
|
|
|
* this property \a key
|
|
|
|
|
* \param args the variable arguments passed to wp_properties_setf()
|
|
|
|
|
* \returns 1 if the property was changed. 0 if nothing was changed because
|
2020-02-17 15:39:19 +02:00
|
|
|
* the property already existed with the same value
|
|
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
gint
|
|
|
|
|
wp_properties_setf_valist (WpProperties * self, const gchar * key,
|
|
|
|
|
const gchar * format, va_list args)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, -EINVAL);
|
|
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_IS_DICT), -EINVAL);
|
2020-06-15 17:20:10 +03:00
|
|
|
g_return_val_if_fail (!(self->flags & FLAG_NO_OWNERSHIP), -EINVAL);
|
2019-08-21 15:16:13 +03:00
|
|
|
|
|
|
|
|
return pw_properties_setva (self->props, key, format, args);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-14 11:28:23 -04:00
|
|
|
struct _WpPropertiesItem
|
|
|
|
|
{
|
|
|
|
|
WpProperties *props;
|
|
|
|
|
const struct spa_dict_item *item;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
G_DEFINE_BOXED_TYPE (WpPropertiesItem, wp_properties_item,
|
|
|
|
|
wp_properties_item_ref, wp_properties_item_unref)
|
|
|
|
|
|
|
|
|
|
static WpPropertiesItem *
|
|
|
|
|
wp_properties_item_new (WpProperties *props, const struct spa_dict_item *item)
|
|
|
|
|
{
|
|
|
|
|
WpPropertiesItem *self = g_rc_box_new0 (WpPropertiesItem);
|
|
|
|
|
self->props = wp_properties_ref (props);
|
|
|
|
|
self->item = item;
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
wp_properties_item_free (gpointer p)
|
|
|
|
|
{
|
|
|
|
|
WpPropertiesItem *self = p;
|
|
|
|
|
wp_properties_unref (self->props);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* \brief Increases the reference count of a properties item object
|
|
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties item object
|
|
|
|
|
* \returns (transfer full): \a self with an additional reference count on it
|
2021-08-10 12:05:28 +03:00
|
|
|
* \since 0.4.2
|
2021-07-14 11:28:23 -04:00
|
|
|
*/
|
|
|
|
|
WpPropertiesItem *
|
|
|
|
|
wp_properties_item_ref (WpPropertiesItem *self)
|
|
|
|
|
{
|
|
|
|
|
return g_rc_box_acquire (self);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* \brief Decreases the reference count on \a self and frees it when the ref
|
|
|
|
|
* count reaches zero.
|
|
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self (transfer full): a properties item object
|
2021-08-10 12:05:28 +03:00
|
|
|
* \since 0.4.2
|
2021-07-14 11:28:23 -04:00
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
wp_properties_item_unref (WpPropertiesItem *self)
|
|
|
|
|
{
|
|
|
|
|
g_rc_box_release_full (self, wp_properties_item_free);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* \brief Gets the key from a properties item
|
|
|
|
|
*
|
|
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self the item held by the GValue that was returned from the WpIterator
|
|
|
|
|
* of wp_properties_new_iterator()
|
|
|
|
|
* \returns (transfer none): the property key of the \a item
|
2021-08-10 12:05:28 +03:00
|
|
|
* \since 0.4.2
|
2021-07-14 11:28:23 -04:00
|
|
|
*/
|
|
|
|
|
const gchar *
|
|
|
|
|
wp_properties_item_get_key (WpPropertiesItem * self)
|
|
|
|
|
{
|
|
|
|
|
return self->item->key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
* \brief Gets the value from a properties item
|
|
|
|
|
*
|
|
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self the item held by the GValue that was returned from the WpIterator
|
|
|
|
|
* of wp_properties_new_iterator()
|
|
|
|
|
* \returns (transfer none): the property value of the \a item
|
2021-08-10 12:05:28 +03:00
|
|
|
* \since 0.4.2
|
2021-07-14 11:28:23 -04:00
|
|
|
*/
|
|
|
|
|
const gchar *
|
|
|
|
|
wp_properties_item_get_value (WpPropertiesItem * self)
|
|
|
|
|
{
|
|
|
|
|
return self->item->value;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-01 12:07:36 +03:00
|
|
|
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) {
|
2021-07-14 11:28:23 -04:00
|
|
|
g_value_init (item, WP_TYPE_PROPERTIES_ITEM);
|
|
|
|
|
g_autoptr (WpPropertiesItem) pi = wp_properties_item_new (
|
|
|
|
|
it_data->properties, it_data->item);
|
|
|
|
|
g_value_take_boxed (item, g_steal_pointer (&pi));
|
2020-06-01 12:07:36 +03:00
|
|
|
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;
|
2021-07-14 11:28:23 -04:00
|
|
|
g_autoptr (WpPropertiesItem) pi = wp_properties_item_new (
|
|
|
|
|
it_data->properties, i);
|
|
|
|
|
g_value_init (&item, WP_TYPE_PROPERTIES_ITEM);
|
|
|
|
|
g_value_take_boxed (&item, g_steal_pointer (&pi));
|
2020-06-01 12:07:36 +03:00
|
|
|
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 = {
|
2020-11-16 11:16:35 +02:00
|
|
|
.version = WP_ITERATOR_METHODS_VERSION,
|
2020-06-01 12:07:36 +03:00
|
|
|
.reset = dict_iterator_reset,
|
|
|
|
|
.next = dict_iterator_next,
|
|
|
|
|
.fold = dict_iterator_fold,
|
|
|
|
|
.finalize = dict_iterator_finalize,
|
|
|
|
|
};
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-06-01 19:39:13 -04:00
|
|
|
* \brief Iterates through all the properties in the properties object
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \returns (transfer full): an iterator that iterates over the properties.
|
2021-08-10 12:05:28 +03:00
|
|
|
* The items in the iterator are of type WpPropertiesItem.
|
|
|
|
|
* Use wp_properties_item_get_key() and
|
|
|
|
|
* wp_properties_item_get_value() to retrieve their contents.
|
2020-06-01 12:07:36 +03:00
|
|
|
*/
|
|
|
|
|
WpIterator *
|
2021-02-05 10:20:33 -05:00
|
|
|
wp_properties_new_iterator (WpProperties * self)
|
2020-06-01 12:07:36 +03:00
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-23 10:02:48 +05:30
|
|
|
/*!
|
2022-05-10 15:27:31 +03:00
|
|
|
* \brief Gets the number of properties contained in this object
|
2022-03-23 10:02:48 +05:30
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
2022-05-10 15:27:31 +03:00
|
|
|
* \returns the number of properties contained in this object
|
|
|
|
|
* \since 0.4.10
|
2022-03-23 10:02:48 +05:30
|
|
|
*/
|
|
|
|
|
guint
|
|
|
|
|
wp_properties_get_count (WpProperties * self)
|
|
|
|
|
{
|
|
|
|
|
const struct spa_dict *dict = wp_properties_peek_dict(self);
|
|
|
|
|
g_return_val_if_fail (dict != NULL, 0);
|
|
|
|
|
|
|
|
|
|
return dict->n_items;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Sorts the keys in alphabetical order
|
|
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
2021-05-13 17:54:58 +03:00
|
|
|
*/
|
2021-03-26 19:06:06 +02:00
|
|
|
void
|
|
|
|
|
wp_properties_sort (WpProperties * self)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail (self != NULL);
|
|
|
|
|
g_return_if_fail (!(self->flags & FLAG_IS_DICT));
|
|
|
|
|
g_return_if_fail (!(self->flags & FLAG_NO_OWNERSHIP));
|
|
|
|
|
|
|
|
|
|
return spa_dict_qsort (&self->props->dict);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-06-01 19:39:13 -04:00
|
|
|
* \brief Gets the dictionary wrapped by a properties object
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \returns (transfer none): the internal properties set as a `struct spa_dict *`
|
2020-02-17 15:39:19 +02:00
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
const struct spa_dict *
|
|
|
|
|
wp_properties_peek_dict (WpProperties * self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
return (self->flags & FLAG_IS_DICT) ? self->dict : &self->props->dict;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-06-01 19:39:13 -04:00
|
|
|
* \brief Gets a copy of the properties object as a `struct pw_properties`
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \returns (transfer full): a copy of the properties in \a self
|
2020-02-17 15:39:19 +02:00
|
|
|
* as a `struct pw_properties`
|
|
|
|
|
*/
|
2019-08-21 15:16:13 +03:00
|
|
|
struct pw_properties *
|
|
|
|
|
wp_properties_to_pw_properties (WpProperties * self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
return pw_properties_new_dict (wp_properties_peek_dict (self));
|
|
|
|
|
}
|
2019-11-19 14:21:42 -05:00
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Similar to wp_properties_to_pw_properties(), but this method avoids making
|
2020-06-15 17:22:47 +03:00
|
|
|
* a copy of the properties by returning the `struct pw_properties` that is
|
2021-05-21 18:40:43 +03:00
|
|
|
* stored internally and then freeing the WpProperties wrapper.
|
2020-06-15 17:22:47 +03:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* If \a self is not uniquely owned (see wp_properties_ensure_unique_owner()),
|
2020-06-15 17:22:47 +03:00
|
|
|
* then this method does make a copy and is the same as
|
|
|
|
|
* wp_properties_to_pw_properties(), performance-wise.
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self (transfer full): a properties object
|
|
|
|
|
* \returns (transfer full): the properties in \a self as a `struct pw_properties`
|
2020-06-15 17:22:47 +03:00
|
|
|
*/
|
|
|
|
|
struct pw_properties *
|
|
|
|
|
wp_properties_unref_and_take_pw_properties (WpProperties * self)
|
|
|
|
|
{
|
|
|
|
|
g_return_val_if_fail (self != NULL, NULL);
|
|
|
|
|
|
|
|
|
|
g_autoptr (WpProperties) unique = wp_properties_ensure_unique_owner (self);
|
2021-05-21 18:40:43 +03:00
|
|
|
/* set the flag so that unref-ing \a unique will not destroy unique->props */
|
2020-06-15 17:22:47 +03:00
|
|
|
unique->flags = FLAG_NO_OWNERSHIP;
|
|
|
|
|
return unique->props;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 17:54:58 +03:00
|
|
|
/*!
|
2021-05-21 18:40:43 +03:00
|
|
|
* \brief Checks if all property values contained in \a other are matching with
|
|
|
|
|
* the values in \a self.
|
2020-02-17 15:39:19 +02:00
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* If a property is contained in \a other and not in \a self, the result is not
|
2020-06-10 09:58:33 -04:00
|
|
|
* matched. If a property is contained in both sets, then the value of the
|
2021-05-21 18:40:43 +03:00
|
|
|
* property in \a other is interpreted as a glob-style pattern
|
|
|
|
|
* (using g_pattern_match_simple()) and the value in \a self is checked to
|
2020-02-17 15:39:19 +02:00
|
|
|
* see if it matches with this pattern.
|
|
|
|
|
*
|
2021-05-21 18:40:43 +03:00
|
|
|
* \ingroup wpproperties
|
|
|
|
|
* \param self a properties object
|
|
|
|
|
* \param other a set of properties to match
|
2024-11-07 21:49:33 +00:00
|
|
|
* \returns TRUE if all matches were successful, FALSE if at least one
|
2020-02-17 15:39:19 +02:00
|
|
|
* property value did not match
|
|
|
|
|
*/
|
2019-11-19 14:21:42 -05:00
|
|
|
gboolean
|
|
|
|
|
wp_properties_matches (WpProperties * self, WpProperties *other)
|
|
|
|
|
{
|
|
|
|
|
const struct spa_dict * dict;
|
|
|
|
|
const struct spa_dict_item *item;
|
|
|
|
|
const gchar *value;
|
|
|
|
|
|
|
|
|
|
g_return_val_if_fail (self != NULL, FALSE);
|
|
|
|
|
|
2020-06-10 09:58:33 -04:00
|
|
|
/* Check if the property values match the ones from 'self' */
|
|
|
|
|
dict = wp_properties_peek_dict (other);
|
2019-11-19 14:21:42 -05:00
|
|
|
spa_dict_for_each(item, dict) {
|
2020-06-10 09:58:33 -04:00
|
|
|
value = wp_properties_get (self, item->key);
|
|
|
|
|
if (!value || !g_pattern_match_simple (value, item->value))
|
2019-11-19 14:21:42 -05:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
2021-05-21 18:40:43 +03:00
|
|
|
}
|