153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2004-2008 Lennart Poettering 553a5a1b3Sopenharmony_ci 653a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 753a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as 853a5a1b3Sopenharmony_ci published by the Free Software Foundation; either version 2.1 of the 953a5a1b3Sopenharmony_ci License, or (at your option) any later version. 1053a5a1b3Sopenharmony_ci 1153a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1253a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1353a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1453a5a1b3Sopenharmony_ci Lesser General Public License for more details. 1553a5a1b3Sopenharmony_ci 1653a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public 1753a5a1b3Sopenharmony_ci License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1853a5a1b3Sopenharmony_ci***/ 1953a5a1b3Sopenharmony_ci 2053a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2153a5a1b3Sopenharmony_ci#include <config.h> 2253a5a1b3Sopenharmony_ci#endif 2353a5a1b3Sopenharmony_ci 2453a5a1b3Sopenharmony_ci#include <string.h> 2553a5a1b3Sopenharmony_ci#include <stdlib.h> 2653a5a1b3Sopenharmony_ci 2753a5a1b3Sopenharmony_ci#include <pulse/xmalloc.h> 2853a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 2953a5a1b3Sopenharmony_ci 3053a5a1b3Sopenharmony_ci#include "dynarray.h" 3153a5a1b3Sopenharmony_ci 3253a5a1b3Sopenharmony_cistruct pa_dynarray { 3353a5a1b3Sopenharmony_ci void **data; 3453a5a1b3Sopenharmony_ci unsigned n_allocated, n_entries; 3553a5a1b3Sopenharmony_ci pa_free_cb_t free_cb; 3653a5a1b3Sopenharmony_ci}; 3753a5a1b3Sopenharmony_ci 3853a5a1b3Sopenharmony_cipa_dynarray* pa_dynarray_new(pa_free_cb_t free_cb) { 3953a5a1b3Sopenharmony_ci pa_dynarray *array; 4053a5a1b3Sopenharmony_ci 4153a5a1b3Sopenharmony_ci array = pa_xnew0(pa_dynarray, 1); 4253a5a1b3Sopenharmony_ci array->free_cb = free_cb; 4353a5a1b3Sopenharmony_ci 4453a5a1b3Sopenharmony_ci return array; 4553a5a1b3Sopenharmony_ci} 4653a5a1b3Sopenharmony_ci 4753a5a1b3Sopenharmony_civoid pa_dynarray_free(pa_dynarray *array) { 4853a5a1b3Sopenharmony_ci unsigned i; 4953a5a1b3Sopenharmony_ci pa_assert(array); 5053a5a1b3Sopenharmony_ci 5153a5a1b3Sopenharmony_ci if (array->free_cb) 5253a5a1b3Sopenharmony_ci for (i = 0; i < array->n_entries; i++) 5353a5a1b3Sopenharmony_ci array->free_cb(array->data[i]); 5453a5a1b3Sopenharmony_ci 5553a5a1b3Sopenharmony_ci pa_xfree(array->data); 5653a5a1b3Sopenharmony_ci pa_xfree(array); 5753a5a1b3Sopenharmony_ci} 5853a5a1b3Sopenharmony_ci 5953a5a1b3Sopenharmony_civoid pa_dynarray_append(pa_dynarray *array, void *p) { 6053a5a1b3Sopenharmony_ci pa_assert(array); 6153a5a1b3Sopenharmony_ci pa_assert(p); 6253a5a1b3Sopenharmony_ci 6353a5a1b3Sopenharmony_ci if (array->n_entries == array->n_allocated) { 6453a5a1b3Sopenharmony_ci unsigned n = PA_MAX(array->n_allocated * 2, 25U); 6553a5a1b3Sopenharmony_ci 6653a5a1b3Sopenharmony_ci array->data = pa_xrealloc(array->data, sizeof(void *) * n); 6753a5a1b3Sopenharmony_ci array->n_allocated = n; 6853a5a1b3Sopenharmony_ci } 6953a5a1b3Sopenharmony_ci 7053a5a1b3Sopenharmony_ci array->data[array->n_entries++] = p; 7153a5a1b3Sopenharmony_ci} 7253a5a1b3Sopenharmony_ci 7353a5a1b3Sopenharmony_civoid *pa_dynarray_get(pa_dynarray *array, unsigned i) { 7453a5a1b3Sopenharmony_ci pa_assert(array); 7553a5a1b3Sopenharmony_ci 7653a5a1b3Sopenharmony_ci if (i >= array->n_entries) 7753a5a1b3Sopenharmony_ci return NULL; 7853a5a1b3Sopenharmony_ci 7953a5a1b3Sopenharmony_ci return array->data[i]; 8053a5a1b3Sopenharmony_ci} 8153a5a1b3Sopenharmony_ci 8253a5a1b3Sopenharmony_civoid *pa_dynarray_last(pa_dynarray *array) { 8353a5a1b3Sopenharmony_ci pa_assert(array); 8453a5a1b3Sopenharmony_ci 8553a5a1b3Sopenharmony_ci if (array->n_entries == 0) 8653a5a1b3Sopenharmony_ci return NULL; 8753a5a1b3Sopenharmony_ci 8853a5a1b3Sopenharmony_ci return array->data[array->n_entries - 1]; 8953a5a1b3Sopenharmony_ci} 9053a5a1b3Sopenharmony_ci 9153a5a1b3Sopenharmony_ciint pa_dynarray_remove_by_index(pa_dynarray *array, unsigned i) { 9253a5a1b3Sopenharmony_ci void *entry; 9353a5a1b3Sopenharmony_ci 9453a5a1b3Sopenharmony_ci pa_assert(array); 9553a5a1b3Sopenharmony_ci 9653a5a1b3Sopenharmony_ci if (i >= array->n_entries) 9753a5a1b3Sopenharmony_ci return -PA_ERR_NOENTITY; 9853a5a1b3Sopenharmony_ci 9953a5a1b3Sopenharmony_ci entry = array->data[i]; 10053a5a1b3Sopenharmony_ci array->data[i] = array->data[array->n_entries - 1]; 10153a5a1b3Sopenharmony_ci array->n_entries--; 10253a5a1b3Sopenharmony_ci 10353a5a1b3Sopenharmony_ci if (array->free_cb) 10453a5a1b3Sopenharmony_ci array->free_cb(entry); 10553a5a1b3Sopenharmony_ci 10653a5a1b3Sopenharmony_ci return 0; 10753a5a1b3Sopenharmony_ci} 10853a5a1b3Sopenharmony_ci 10953a5a1b3Sopenharmony_ciint pa_dynarray_remove_by_data(pa_dynarray *array, void *p) { 11053a5a1b3Sopenharmony_ci unsigned i; 11153a5a1b3Sopenharmony_ci 11253a5a1b3Sopenharmony_ci pa_assert(array); 11353a5a1b3Sopenharmony_ci pa_assert(p); 11453a5a1b3Sopenharmony_ci 11553a5a1b3Sopenharmony_ci /* Iterate backwards, with the assumption that recently appended entries 11653a5a1b3Sopenharmony_ci * are likely to be removed first. */ 11753a5a1b3Sopenharmony_ci i = array->n_entries; 11853a5a1b3Sopenharmony_ci while (i > 0) { 11953a5a1b3Sopenharmony_ci i--; 12053a5a1b3Sopenharmony_ci if (array->data[i] == p) { 12153a5a1b3Sopenharmony_ci pa_dynarray_remove_by_index(array, i); 12253a5a1b3Sopenharmony_ci return 0; 12353a5a1b3Sopenharmony_ci } 12453a5a1b3Sopenharmony_ci } 12553a5a1b3Sopenharmony_ci 12653a5a1b3Sopenharmony_ci return -PA_ERR_NOENTITY; 12753a5a1b3Sopenharmony_ci} 12853a5a1b3Sopenharmony_ci 12953a5a1b3Sopenharmony_civoid *pa_dynarray_steal_last(pa_dynarray *array) { 13053a5a1b3Sopenharmony_ci pa_assert(array); 13153a5a1b3Sopenharmony_ci 13253a5a1b3Sopenharmony_ci if (array->n_entries > 0) 13353a5a1b3Sopenharmony_ci return array->data[--array->n_entries]; 13453a5a1b3Sopenharmony_ci else 13553a5a1b3Sopenharmony_ci return NULL; 13653a5a1b3Sopenharmony_ci} 13753a5a1b3Sopenharmony_ci 13853a5a1b3Sopenharmony_ciunsigned pa_dynarray_size(pa_dynarray *array) { 13953a5a1b3Sopenharmony_ci pa_assert(array); 14053a5a1b3Sopenharmony_ci 14153a5a1b3Sopenharmony_ci return array->n_entries; 14253a5a1b3Sopenharmony_ci} 14353a5a1b3Sopenharmony_ci 14453a5a1b3Sopenharmony_ciint pa_dynarray_insert_by_index(pa_dynarray *array, void *p, unsigned i) { 14553a5a1b3Sopenharmony_ci void *entry; 14653a5a1b3Sopenharmony_ci unsigned j; 14753a5a1b3Sopenharmony_ci 14853a5a1b3Sopenharmony_ci pa_assert(array); 14953a5a1b3Sopenharmony_ci 15053a5a1b3Sopenharmony_ci if (i > array->n_entries) 15153a5a1b3Sopenharmony_ci return -PA_ERR_NOENTITY; 15253a5a1b3Sopenharmony_ci 15353a5a1b3Sopenharmony_ci if (i == array->n_entries) 15453a5a1b3Sopenharmony_ci pa_dynarray_append(array, p); 15553a5a1b3Sopenharmony_ci else { 15653a5a1b3Sopenharmony_ci entry = pa_dynarray_last(array); 15753a5a1b3Sopenharmony_ci pa_dynarray_append(array, entry); 15853a5a1b3Sopenharmony_ci j = array->n_entries - 2; 15953a5a1b3Sopenharmony_ci for (;j > i; j--) 16053a5a1b3Sopenharmony_ci array->data[j] = array->data[j-1]; 16153a5a1b3Sopenharmony_ci array->data[i] = p; 16253a5a1b3Sopenharmony_ci } 16353a5a1b3Sopenharmony_ci 16453a5a1b3Sopenharmony_ci return 0; 16553a5a1b3Sopenharmony_ci} 166