mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	SPDX tags make the licensing information easy to understand and clear, and they are machine parseable. See https://spdx.dev for more information.
		
			
				
	
	
		
			191 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* ALSA Card Profile */
 | 
						|
/* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */
 | 
						|
/* SPDX-License-Identifier: MIT */
 | 
						|
 | 
						|
#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 */
 |