mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-18 07:00:06 -05:00
array: improve pw_array
Handle extend == 0 and don't expand the array but return -ENOSPC. This makes it possible to handle static arrays, make a function to make this easier. Remove pw_array_add_fixed() now that we support this with extend==0 and because it was not used. Round up the required space to next extend so that the total allocated size if always a multiple of the extend. Make pw_array_add_ptr() check for allocation errors instead of crashing.
This commit is contained in:
parent
0f533c6d64
commit
adbd081b12
1 changed files with 26 additions and 26 deletions
|
|
@ -29,7 +29,8 @@ struct pw_array {
|
||||||
void *data; /**< pointer to array data */
|
void *data; /**< pointer to array data */
|
||||||
size_t size; /**< length of array in bytes */
|
size_t size; /**< length of array in bytes */
|
||||||
size_t alloc; /**< number of allocated memory in \a data */
|
size_t alloc; /**< number of allocated memory in \a data */
|
||||||
size_t extend; /**< number of bytes to extend with */
|
size_t extend; /**< number of bytes to extend with, 0 when the
|
||||||
|
* data should not expand */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Initialize an array. The new array is empty. */
|
/** Initialize an array. The new array is empty. */
|
||||||
|
|
@ -68,7 +69,8 @@ struct pw_array {
|
||||||
SPA_PTRDIFF(pw_array_end(a),(p))); \
|
SPA_PTRDIFF(pw_array_end(a),(p))); \
|
||||||
})
|
})
|
||||||
|
|
||||||
/** Initialize the array with given extend */
|
/** Initialize the array with given extend. Extend needs to be > 0 or else
|
||||||
|
* the array will not be able to expand. */
|
||||||
static inline void pw_array_init(struct pw_array *arr, size_t extend)
|
static inline void pw_array_init(struct pw_array *arr, size_t extend)
|
||||||
{
|
{
|
||||||
arr->data = NULL;
|
arr->data = NULL;
|
||||||
|
|
@ -76,13 +78,22 @@ static inline void pw_array_init(struct pw_array *arr, size_t extend)
|
||||||
arr->extend = extend;
|
arr->extend = extend;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Clear the array */
|
/** Clear the array. This should be called when pw_array_init() was called. */
|
||||||
static inline void pw_array_clear(struct pw_array *arr)
|
static inline void pw_array_clear(struct pw_array *arr)
|
||||||
{
|
{
|
||||||
free(arr->data);
|
if (arr->extend > 0)
|
||||||
|
free(arr->data);
|
||||||
pw_array_init(arr, arr->extend);
|
pw_array_init(arr, arr->extend);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Initialize a static array. */
|
||||||
|
static inline void pw_array_init_static(struct pw_array *arr, void *data, size_t size)
|
||||||
|
{
|
||||||
|
arr->data = data;
|
||||||
|
arr->alloc = size;
|
||||||
|
arr->size = arr->extend = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Reset the array */
|
/** Reset the array */
|
||||||
static inline void pw_array_reset(struct pw_array *arr)
|
static inline void pw_array_reset(struct pw_array *arr)
|
||||||
{
|
{
|
||||||
|
|
@ -99,10 +110,9 @@ static inline int pw_array_ensure_size(struct pw_array *arr, size_t size)
|
||||||
|
|
||||||
if (SPA_UNLIKELY(alloc < need)) {
|
if (SPA_UNLIKELY(alloc < need)) {
|
||||||
void *data;
|
void *data;
|
||||||
alloc = SPA_MAX(alloc, arr->extend);
|
if (arr->extend == 0)
|
||||||
spa_assert(alloc != 0); /* forgot pw_array_init */
|
return -ENOSPC;
|
||||||
while (alloc < need)
|
alloc = SPA_ROUND_UP(need, arr->extend);
|
||||||
alloc *= 2;
|
|
||||||
if (SPA_UNLIKELY((data = realloc(arr->data, alloc)) == NULL))
|
if (SPA_UNLIKELY((data = realloc(arr->data, alloc)) == NULL))
|
||||||
return -errno;
|
return -errno;
|
||||||
arr->data = data;
|
arr->data = data;
|
||||||
|
|
@ -127,27 +137,17 @@ static inline void *pw_array_add(struct pw_array *arr, size_t size)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add \a ref size bytes to \a arr. When there is not enough memory to
|
/** Add a pointer to array. Returns 0 on success and a negative errno style
|
||||||
* hold \a size bytes, NULL is returned */
|
* error on failure. */
|
||||||
static inline void *pw_array_add_fixed(struct pw_array *arr, size_t size)
|
static inline int pw_array_add_ptr(struct pw_array *arr, void *ptr)
|
||||||
{
|
{
|
||||||
void *p;
|
void **p = (void **)pw_array_add(arr, sizeof(void*));
|
||||||
|
if (p == NULL)
|
||||||
if (SPA_UNLIKELY(arr->alloc < arr->size + size)) {
|
return -errno;
|
||||||
errno = ENOSPC;
|
*p = ptr;
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
p = SPA_PTROFF(arr->data, arr->size, void);
|
|
||||||
arr->size += size;
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Add a pointer to array */
|
|
||||||
#define pw_array_add_ptr(a,p) \
|
|
||||||
*((void**) pw_array_add(a, sizeof(void*))) = (p)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \}
|
* \}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue