diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:28:17 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:28:17 +0000 |
commit | 7a46c07230b8d8108c0e8e80df4522d0ac116538 (patch) | |
tree | d483300dab478b994fe199a5d19d18d74153718a /spa/plugins/alsa/acp/hashmap.h | |
parent | Initial commit. (diff) | |
download | pipewire-7a46c07230b8d8108c0e8e80df4522d0ac116538.tar.xz pipewire-7a46c07230b8d8108c0e8e80df4522d0ac116538.zip |
Adding upstream version 0.3.65.upstream/0.3.65upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'spa/plugins/alsa/acp/hashmap.h')
-rw-r--r-- | spa/plugins/alsa/acp/hashmap.h | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/spa/plugins/alsa/acp/hashmap.h b/spa/plugins/alsa/acp/hashmap.h new file mode 100644 index 0000000..d8dbadb --- /dev/null +++ b/spa/plugins/alsa/acp/hashmap.h @@ -0,0 +1,219 @@ +/* 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_HASHMAP_H +#define PA_HASHMAP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "array.h" + +typedef unsigned (*pa_hash_func_t)(const void *p); +typedef int (*pa_compare_func_t)(const void *a, const void *b); + +typedef struct pa_hashmap_item { + void *key; + void *value; +} pa_hashmap_item; + +typedef struct pa_hashmap { + pa_array array; + pa_hash_func_t hash_func; + pa_compare_func_t compare_func; + pa_free_cb_t key_free_func; + pa_free_cb_t value_free_func; +} pa_hashmap; + +static inline pa_hashmap *pa_hashmap_new(pa_hash_func_t hash_func, pa_compare_func_t compare_func) +{ + pa_hashmap *m = calloc(1, sizeof(pa_hashmap)); + pa_array_init(&m->array, 16); + m->hash_func = hash_func; + m->compare_func = compare_func; + return m; +} + +static inline pa_hashmap *pa_hashmap_new_full(pa_hash_func_t hash_func, pa_compare_func_t compare_func, + pa_free_cb_t key_free_func, pa_free_cb_t value_free_func) +{ + pa_hashmap *m = pa_hashmap_new(hash_func, compare_func); + m->key_free_func = key_free_func; + m->value_free_func = value_free_func; + return m; +} + +static inline void pa_hashmap_item_free(pa_hashmap *h, pa_hashmap_item *item) +{ + if (h->key_free_func && item->key) + h->key_free_func(item->key); + if (h->value_free_func && item->value) + h->value_free_func(item->value); +} + +static inline void pa_hashmap_remove_all(pa_hashmap *h) +{ + pa_hashmap_item *item; + pa_array_for_each(item, &h->array) + pa_hashmap_item_free(h, item); + pa_array_reset(&h->array); +} + +static inline void pa_hashmap_free(pa_hashmap *h) +{ + pa_hashmap_remove_all(h); + pa_array_clear(&h->array); + free(h); +} + +static inline pa_hashmap_item* pa_hashmap_find_free(pa_hashmap *h) +{ + pa_hashmap_item *item; + pa_array_for_each(item, &h->array) { + if (item->key == NULL) + return item; + } + return pa_array_add(&h->array, sizeof(*item)); +} + +static inline pa_hashmap_item* pa_hashmap_find(const pa_hashmap *h, const void *key) +{ + pa_hashmap_item *item = NULL; + pa_array_for_each(item, &h->array) { + if (item->key != NULL && h->compare_func(item->key, key) == 0) + return item; + } + return NULL; +} + +static inline void* pa_hashmap_get(const pa_hashmap *h, const void *key) +{ + const pa_hashmap_item *item = pa_hashmap_find(h, key); + if (item == NULL) + return NULL; + return item->value; +} + +static inline int pa_hashmap_put(pa_hashmap *h, void *key, void *value) +{ + pa_hashmap_item *item = pa_hashmap_find(h, key); + if (item != NULL) + return -1; + item = pa_hashmap_find_free(h); + item->key = key; + item->value = value; + return 0; +} + +static inline void* pa_hashmap_remove(pa_hashmap *h, const void *key) +{ + pa_hashmap_item *item = pa_hashmap_find(h, key); + void *value; + if (item == NULL) + return NULL; + value = item->value; + if (h->key_free_func) + h->key_free_func(item->key); + item->key = NULL; + item->value = NULL; + return value; +} + +static inline int pa_hashmap_remove_and_free(pa_hashmap *h, const void *key) +{ + void *val = pa_hashmap_remove(h, key); + if (val && h->value_free_func) + h->value_free_func(val); + return val ? 0 : -1; +} + +static inline void *pa_hashmap_first(const pa_hashmap *h) +{ + pa_hashmap_item *item; + pa_array_for_each(item, &h->array) { + if (item->key != NULL) + return item->value; + } + return NULL; +} + +static inline void *pa_hashmap_iterate(const pa_hashmap *h, void **state, const void **key) +{ + pa_hashmap_item *it = *state; + if (it == NULL) + *state = pa_array_first(&h->array); + do { + it = *state; + if (!pa_array_check(&h->array, it)) + return NULL; + *state = it + 1; + } while (it->key == NULL); + if (key) + *key = it->key; + return it->value; +} + +static inline bool pa_hashmap_isempty(const pa_hashmap *h) +{ + pa_hashmap_item *item; + pa_array_for_each(item, &h->array) + if (item->key != NULL) + return false; + return true; +} + +static inline unsigned pa_hashmap_size(const pa_hashmap *h) +{ + unsigned count = 0; + pa_hashmap_item *item; + pa_array_for_each(item, &h->array) + if (item->key != NULL) + count++; + return count; +} + +static inline void pa_hashmap_sort(pa_hashmap *h, + int (*compar)(const void *, const void *)) +{ + qsort((void*)h->array.data, + pa_array_get_len(&h->array, pa_hashmap_item), + sizeof(pa_hashmap_item), compar); +} + +#define PA_HASHMAP_FOREACH(e, h, state) \ + for ((state) = NULL, (e) = pa_hashmap_iterate((h), &(state), NULL); \ + (e); (e) = pa_hashmap_iterate((h), &(state), NULL)) + +/* A macro to ease iteration through all key, value pairs */ +#define PA_HASHMAP_FOREACH_KV(k, e, h, state) \ + for ((state) = NULL, (e) = pa_hashmap_iterate((h), &(state), (const void **) &(k)); \ + (e); (e) = pa_hashmap_iterate((h), &(state), (const void **) &(k))) + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* PA_HASHMAP_H */ |