1
0
Fork 0
pipewire/spa/plugins/alsa/acp/hashmap.h
Daniel Baumann 6b016a712f
Adding upstream version 1.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 21:40:42 +02:00

199 lines
4.7 KiB
C

/* ALSA Card Profile */
/* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */
/* SPDX-License-Identifier: MIT */
#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 */