diff options
Diffstat (limited to 'spa/plugins/alsa/acp/proplist.h')
-rw-r--r-- | spa/plugins/alsa/acp/proplist.h | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/spa/plugins/alsa/acp/proplist.h b/spa/plugins/alsa/acp/proplist.h new file mode 100644 index 0000000..ed4cc5d --- /dev/null +++ b/spa/plugins/alsa/acp/proplist.h @@ -0,0 +1,211 @@ +/* ALSA Card Profile + * + * Copyright © 2020 Wim Taymans + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef PA_PROPLIST_H +#define PA_PROPLIST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdio.h> + +#include "array.h" +#include "acp.h" + +#define PA_PROP_DEVICE_DESCRIPTION "device.description" + +#define PA_PROP_DEVICE_CLASS "device.class" + +#define PA_PROP_DEVICE_FORM_FACTOR "device.form_factor" + +#define PA_PROP_DEVICE_INTENDED_ROLES "device.intended_roles" + +#define PA_PROP_DEVICE_PROFILE_NAME "device.profile.name" + +#define PA_PROP_DEVICE_STRING "device.string" + +#define PA_PROP_DEVICE_API "device.api" + +#define PA_PROP_DEVICE_PRODUCT_NAME "device.product.name" + +#define PA_PROP_DEVICE_PROFILE_DESCRIPTION "device.profile.description" + +typedef struct pa_proplist_item { + char *key; + char *value; +} pa_proplist_item; + +typedef struct pa_proplist { + struct pa_array array; +} pa_proplist; + +static inline pa_proplist* pa_proplist_new(void) +{ + pa_proplist *p = calloc(1, sizeof(*p)); + pa_array_init(&p->array, 16); + return p; +} +static inline pa_proplist_item* pa_proplist_item_find(const pa_proplist *p, const void *key) +{ + pa_proplist_item *item; + pa_array_for_each(item, &p->array) { + if (strcmp(key, item->key) == 0) + return item; + } + return NULL; +} + +static inline void pa_proplist_item_free(pa_proplist_item* it) +{ + free(it->key); + free(it->value); +} + +static inline void pa_proplist_clear(pa_proplist* p) +{ + pa_proplist_item *item; + pa_array_for_each(item, &p->array) + pa_proplist_item_free(item); + pa_array_reset(&p->array); +} + +static inline void pa_proplist_free(pa_proplist* p) +{ + pa_proplist_clear(p); + pa_array_clear(&p->array); + free(p); +} + +static inline unsigned pa_proplist_size(const pa_proplist *p) +{ + return pa_array_get_len(&p->array, pa_proplist_item); +} + +static inline int pa_proplist_contains(const pa_proplist *p, const char *key) +{ + return pa_proplist_item_find(p, key) ? 1 : 0; +} + +static inline int pa_proplist_sets(pa_proplist *p, const char *key, const char *value) +{ + pa_proplist_item *item = pa_proplist_item_find(p, key); + if (item != NULL) + pa_proplist_item_free(item); + else + item = pa_array_add(&p->array, sizeof(*item)); + item->key = strdup(key); + item->value = strdup(value); + return 0; +} + +static inline int pa_proplist_unset(pa_proplist *p, const char *key) +{ + pa_proplist_item *item = pa_proplist_item_find(p, key); + if (item == NULL) + return -ENOENT; + pa_proplist_item_free(item); + pa_array_remove(&p->array, item); + return 0; +} + +static PA_PRINTF_FUNC(3,4) inline int pa_proplist_setf(pa_proplist *p, const char *key, const char *format, ...) +{ + pa_proplist_item *item = pa_proplist_item_find(p, key); + va_list args; + int res; + + va_start(args, format); + if (item != NULL) + pa_proplist_item_free(item); + else + item = pa_array_add(&p->array, sizeof(*item)); + item->key = strdup(key); + if ((res = vasprintf(&item->value, format, args)) < 0) + res = -errno; + va_end(args); + return res; +} + +static inline const char *pa_proplist_gets(const pa_proplist *p, const char *key) +{ + pa_proplist_item *item = pa_proplist_item_find(p, key); + return item ? item->value : NULL; +} + +typedef enum pa_update_mode { + PA_UPDATE_SET + /**< Replace the entire property list with the new one. Don't keep + * any of the old data around. */, + PA_UPDATE_MERGE + /**< Merge new property list into the existing one, not replacing + * any old entries if they share a common key with the new + * property list. */, + PA_UPDATE_REPLACE + /**< Merge new property list into the existing one, replacing all + * old entries that share a common key with the new property + * list. */ +} pa_update_mode_t; + + +static inline void pa_proplist_update(pa_proplist *p, pa_update_mode_t mode, const pa_proplist *other) +{ + pa_proplist_item *item; + + if (mode == PA_UPDATE_SET) + pa_proplist_clear(p); + + pa_array_for_each(item, &other->array) { + if (mode == PA_UPDATE_MERGE && pa_proplist_contains(p, item->key)) + continue; + pa_proplist_sets(p, item->key, item->value); + } +} + +static inline pa_proplist* pa_proplist_new_dict(const struct acp_dict *dict) +{ + pa_proplist *p = pa_proplist_new(); + if (dict) { + const struct acp_dict_item *item; + struct acp_dict_item *it; + acp_dict_for_each(item, dict) { + it = pa_array_add(&p->array, sizeof(*it)); + it->key = strdup(item->key); + it->value = strdup(item->value); + } + } + return p; +} + +static inline void pa_proplist_as_dict(const pa_proplist *p, struct acp_dict *dict) +{ + dict->n_items = pa_proplist_size(p); + dict->items = p->array.data; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PA_PROPLIST_H */ |