diff options
Diffstat (limited to 'spa/plugins/alsa/acp/idxset.h')
-rw-r--r-- | spa/plugins/alsa/acp/idxset.h | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/spa/plugins/alsa/acp/idxset.h b/spa/plugins/alsa/acp/idxset.h new file mode 100644 index 0000000..6e88a84 --- /dev/null +++ b/spa/plugins/alsa/acp/idxset.h @@ -0,0 +1,200 @@ +/* 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_IDXSET_H +#define PA_IDXSET_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "array.h" + +#define PA_IDXSET_INVALID ((uint32_t) -1) + +typedef unsigned (*pa_hash_func_t)(const void *p); +typedef int (*pa_compare_func_t)(const void *a, const void *b); + +typedef struct pa_idxset_item { + void *ptr; +} pa_idxset_item; + +typedef struct pa_idxset { + pa_array array; + pa_hash_func_t hash_func; + pa_compare_func_t compare_func; +} pa_idxset; + +static inline unsigned pa_idxset_trivial_hash_func(const void *p) +{ + return PA_PTR_TO_UINT(p); +} + +static inline int pa_idxset_trivial_compare_func(const void *a, const void *b) +{ + return a < b ? -1 : (a > b ? 1 : 0); +} + +static inline unsigned pa_idxset_string_hash_func(const void *p) +{ + unsigned hash = 0; + const char *c; + for (c = p; *c; c++) + hash = 31 * hash + (unsigned) *c; + return hash; +} + +static inline int pa_idxset_string_compare_func(const void *a, const void *b) +{ + return strcmp(a, b); +} + +static inline pa_idxset *pa_idxset_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func) +{ + pa_idxset *s = calloc(1, sizeof(pa_idxset)); + pa_array_init(&s->array, 16); + s->hash_func = hash_func; + s->compare_func = compare_func; + return s; +} + +static inline void pa_idxset_free(pa_idxset *s, pa_free_cb_t free_cb) +{ + if (free_cb) { + pa_idxset_item *item; + pa_array_for_each(item, &s->array) + free_cb(item->ptr); + } + pa_array_clear(&s->array); + free(s); +} + +static inline pa_idxset_item* pa_idxset_find(const pa_idxset *s, const void *ptr) +{ + pa_idxset_item *item; + pa_array_for_each(item, &s->array) { + if (item->ptr == ptr) + return item; + } + return NULL; +} + +static inline int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx) +{ + pa_idxset_item *item = pa_idxset_find(s, p); + int res = item ? -1 : 0; + if (item == NULL) { + item = pa_idxset_find(s, NULL); + if (item == NULL) + item = pa_array_add(&s->array, sizeof(*item)); + item->ptr = p; + } + if (idx) + *idx = item - (pa_idxset_item*)s->array.data; + return res; +} + +static inline pa_idxset *pa_idxset_copy(pa_idxset *s, pa_copy_func_t copy_func) +{ + pa_idxset_item *item; + pa_idxset *copy = pa_idxset_new(s->hash_func, s->compare_func); + pa_array_for_each(item, &s->array) { + if (item->ptr) + pa_idxset_put(copy, copy_func ? copy_func(item->ptr) : item->ptr, NULL); + } + return copy; +} + +static inline bool pa_idxset_isempty(const pa_idxset *s) +{ + pa_idxset_item *item; + pa_array_for_each(item, &s->array) + if (item->ptr != NULL) + return false; + return true; +} +static inline unsigned pa_idxset_size(pa_idxset*s) +{ + unsigned count = 0; + pa_idxset_item *item; + pa_array_for_each(item, &s->array) + if (item->ptr != NULL) + count++; + return count; +} + +static inline void *pa_idxset_search(pa_idxset *s, uint32_t *idx) +{ + pa_idxset_item *item; + for (item = pa_array_get_unchecked(&s->array, *idx, pa_idxset_item); + pa_array_check(&s->array, item); item++, (*idx)++) { + if (item->ptr != NULL) + return item->ptr; + } + *idx = PA_IDXSET_INVALID; + return NULL; +} + +static inline void *pa_idxset_next(pa_idxset *s, uint32_t *idx) +{ + (*idx)++;; + return pa_idxset_search(s, idx); +} + +static inline void* pa_idxset_first(pa_idxset *s, uint32_t *idx) +{ + uint32_t i = 0; + void *ptr = pa_idxset_search(s, &i); + if (idx) + *idx = i; + return ptr; +} + +static inline void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx) +{ + pa_idxset_item *item = pa_idxset_find(s, p); + if (item == NULL) + return NULL; + if (idx) + *idx = item - (pa_idxset_item*)s->array.data; + return item->ptr; +} + +static inline void* pa_idxset_get_by_index(pa_idxset*s, uint32_t idx) +{ + pa_idxset_item *item; + if (!pa_array_check_index(&s->array, idx, pa_idxset_item)) + return NULL; + item = pa_array_get_unchecked(&s->array, idx, pa_idxset_item); + return item->ptr; +} + +#define PA_IDXSET_FOREACH(e, s, idx) \ + for ((e) = pa_idxset_first((s), &(idx)); (e); (e) = pa_idxset_next((s), &(idx))) + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PA_IDXSET_H */ |