summaryrefslogtreecommitdiffstats
path: root/spa/plugins/alsa/acp/dynarray.h
diff options
context:
space:
mode:
Diffstat (limited to 'spa/plugins/alsa/acp/dynarray.h')
-rw-r--r--spa/plugins/alsa/acp/dynarray.h159
1 files changed, 159 insertions, 0 deletions
diff --git a/spa/plugins/alsa/acp/dynarray.h b/spa/plugins/alsa/acp/dynarray.h
new file mode 100644
index 0000000..762c84c
--- /dev/null
+++ b/spa/plugins/alsa/acp/dynarray.h
@@ -0,0 +1,159 @@
+/* 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_DYNARRAY_H
+#define PA_DYNARRAY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "array.h"
+
+typedef struct pa_dynarray_item {
+ void *ptr;
+} pa_dynarray_item;
+
+typedef struct pa_dynarray {
+ pa_array array;
+ pa_free_cb_t free_cb;
+} pa_dynarray;
+
+static inline void pa_dynarray_init(pa_dynarray *array, pa_free_cb_t free_cb)
+{
+ pa_array_init(&array->array, 16);
+ array->free_cb = free_cb;
+}
+
+static inline void pa_dynarray_item_free(pa_dynarray *array, pa_dynarray_item *item)
+{
+ if (array->free_cb)
+ array->free_cb(item->ptr);
+}
+
+static inline void pa_dynarray_clear(pa_dynarray *array)
+{
+ pa_dynarray_item *item;
+ pa_array_for_each(item, &array->array)
+ pa_dynarray_item_free(array, item);
+ pa_array_clear(&array->array);
+}
+
+static inline pa_dynarray* pa_dynarray_new(pa_free_cb_t free_cb)
+{
+ pa_dynarray *d = calloc(1, sizeof(*d));
+ pa_dynarray_init(d, free_cb);
+ return d;
+}
+
+static inline void pa_dynarray_free(pa_dynarray *array)
+{
+ pa_dynarray_clear(array);
+ free(array);
+}
+
+static inline void pa_dynarray_append(pa_dynarray *array, void *p)
+{
+ pa_dynarray_item *item = pa_array_add(&array->array, sizeof(*item));
+ item->ptr = p;
+}
+
+static inline pa_dynarray_item *pa_dynarray_find_item(pa_dynarray *array, void *p)
+{
+ pa_dynarray_item *item;
+ pa_array_for_each(item, &array->array) {
+ if (item->ptr == p)
+ return item;
+ }
+ return NULL;
+}
+
+static inline pa_dynarray_item *pa_dynarray_get_item(pa_dynarray *array, unsigned i)
+{
+ if (!pa_array_check_index(&array->array, i, pa_dynarray_item))
+ return NULL;
+ return pa_array_get_unchecked(&array->array, i, pa_dynarray_item);
+}
+
+static inline void *pa_dynarray_get(pa_dynarray *array, unsigned i)
+{
+ pa_dynarray_item *item = pa_dynarray_get_item(array, i);
+ if (item == NULL)
+ return NULL;
+ return item->ptr;
+}
+
+static inline int pa_dynarray_insert_by_index(pa_dynarray *array, void *p, unsigned i)
+{
+ unsigned j, len;
+ pa_dynarray_item *item;
+
+ len = pa_array_get_len(&array->array, pa_dynarray_item);
+
+ if (i > len)
+ return -EINVAL;
+
+ item = pa_array_add(&array->array, sizeof(*item));
+ for (j = len; j > i; j--) {
+ item--;
+ item[1].ptr = item[0].ptr;
+ }
+ item->ptr = p;
+ return 0;
+}
+
+static inline int pa_dynarray_remove_by_index(pa_dynarray *array, unsigned i)
+{
+ pa_dynarray_item *item = pa_dynarray_get_item(array, i);
+ if (item == NULL)
+ return -ENOENT;
+ pa_dynarray_item_free(array, item);
+ pa_array_remove(&array->array, item);
+ return 0;
+}
+
+static inline int pa_dynarray_remove_by_data(pa_dynarray *array, void *p)
+{
+ pa_dynarray_item *item = pa_dynarray_find_item(array, p);
+ if (item == NULL)
+ return -ENOENT;
+ pa_dynarray_item_free(array, item);
+ pa_array_remove(&array->array, item);
+ return 0;
+}
+
+static inline unsigned pa_dynarray_size(pa_dynarray *array)
+{
+ return pa_array_get_len(&array->array, pa_dynarray_item);
+}
+
+#define PA_DYNARRAY_FOREACH(elem, array, idx) \
+ for ((idx) = 0; ((elem) = pa_dynarray_get(array, idx)); (idx)++)
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* PA_DYNARRAY_H */