array.h revision 6ef7e31619edfaa17ed044b45861d106a86191ef
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#ifndef __ARRAY_H
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#define __ARRAY_H
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen/* Array is a buffer accessible using fixed size elements. If DEBUG is
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen enabled, it also provides compile time type safety:
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen If DEBUG is enabled, an extra variable is defined along with the array
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen itself. This is used to cast array_idx() return value correctly, so
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen compiler gives a warning if it's assigned into variable with a different
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen type.
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen Example usage:
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen struct foo {
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen array_t ARRAY_DEFINE(bars, struct bar);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen ...
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen };
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
bd3714d623d67f7dc8bd70ba39b467762ae409e8Timo Sirainen ARRAY_CREATE(&foo->bars, default_pool, struct bar, 10);
bd3714d623d67f7dc8bd70ba39b467762ae409e8Timo Sirainen ARRAY_CREATE(&foo->bars, default_pool, struct baz, 10); // compiler warning
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
bd3714d623d67f7dc8bd70ba39b467762ae409e8Timo Sirainen struct bar *bar = array_idx(&foo->bars, 5);
bd3714d623d67f7dc8bd70ba39b467762ae409e8Timo Sirainen struct baz *baz = array_idx(&foo->bars, 5); // compiler warning
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen When passing array_t as a parameter to function, or when it's otherwise
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen accessed in a way that the extra variable cannot be accessed, the code
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen won't compile. For situations like those, there's a ARRAY_SET_TYPE() macro.
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen Example:
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen void do_foo(array_t *bars) {
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen ARRAY_SET_TYPE(bars, struct foo);
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen struct foo *foo = array_idx(bars, 0);
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen }
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen*/
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "array-decl.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "buffer.h"
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifdef ARRAY_TYPE_CHECKS
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define ARRAY_CREATE(array, pool, array_type, init_count) STMT_START { \
954dc3045a1df5594a1a7a0bc212ad4a92d62a20Timo Sirainen array_type **_array_tmp = array ## __ ## type; _array_tmp = NULL; \
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen array_create(array, pool, sizeof(array_type), init_count); \
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen } STMT_END
3bc4e3b9f4ce6c3e771fa5ba284daa42828a9ce6Timo Sirainen# define ARRAY_SET_TYPE(array, array_type) \
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen array_type **array ## __ ## type = NULL
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define ARRAY_CREATE(array, pool, array_type, init_count) \
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen array_create(array, pool, sizeof(array_type), init_count)
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen/* The reason we do this for non-ARRAY_TYPE_CHECKS as well is because if we
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen left this empty, some compilers wouldn't like an extra ";" character at
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen the beginning of the function (eg. gcc 2.95).
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen However just declaring the variable gives "unused variable" warning.
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen I couldn't think of anything better, so we just use gcc-specific
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen unused-attribute to get rid of that with gcc. */
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen# define ARRAY_SET_TYPE(array, array_type) \
0bed9236fca9b177d4bc3b4663e938097a73bab2Timo Sirainen array_type **array ## __ ## type __attr_unused__ = NULL
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenarray_create_from_buffer(array_t *array, buffer_t *buffer, size_t element_size)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen array->buffer = buffer;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen array->element_size = element_size;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenarray_create(array_t *array, pool_t pool,
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen size_t element_size, unsigned int init_count)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_t *buffer;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer = buffer_create_dynamic(pool, init_count * element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen array_create_from_buffer(array, buffer, element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenarray_free(array_t *array)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_free(array->buffer);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen array->buffer = NULL;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstatic inline bool
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenarray_is_created(const array_t *array)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen return array->buffer != NULL;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenarray_clear(array_t *array)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_set_used_size(array->buffer, 0);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen_array_append(array_t *array, const void *data, unsigned int count)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_append(array->buffer, data, count * array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifndef ARRAY_TYPE_CHECKS
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_append _array_append
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_append(array, data, count) STMT_START { \
2a7666fd3168ba04c4c027391cdddf0b7fc8074bTimo Sirainen typeof(const typeof(**(array ## __ ## type)) *) _array_tmp = data; \
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen _array_append(array, _array_tmp, count); \
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen } STMT_END
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenarray_append_array(array_t *dest_array, const array_t *src_array)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen i_assert(dest_array->element_size == src_array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_append_buf(dest_array->buffer, src_array->buffer, 0, (size_t)-1);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen_array_insert(array_t *array, unsigned int idx,
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen const void *data, unsigned int count)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_insert(array->buffer, idx * array->element_size,
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen data, count * array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifndef ARRAY_TYPE_CHECKS
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_insert _array_insert
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_insert(array, idx, data, count) STMT_START { \
2a7666fd3168ba04c4c027391cdddf0b7fc8074bTimo Sirainen typeof(const typeof(**(array ## __ ## type)) *) _array_tmp = data; \
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen _array_insert(array, idx, _array_tmp, count); \
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen } STMT_END
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenarray_delete(array_t *array, unsigned int idx, unsigned int count)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_delete(array->buffer, idx * array->element_size,
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen count * array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline const void *
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen_array_get(const array_t *array, unsigned int *count_r)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen if (count_r != NULL)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen *count_r = array->buffer->used / array->element_size;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen return array->buffer->data;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifndef ARRAY_TYPE_CHECKS
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_get _array_get
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_get(array, count) \
2a7666fd3168ba04c4c027391cdddf0b7fc8074bTimo Sirainen (typeof(typeof(**array ## __ ## type) const *))_array_get(array, count)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline const void *
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen_array_idx(const array_t *array, unsigned int idx)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen i_assert(idx * array->element_size < array->buffer->used);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen return CONST_PTR_OFFSET(array->buffer->data, idx * array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifndef ARRAY_TYPE_CHECKS
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_idx _array_idx
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_idx(array, idx) \
2a7666fd3168ba04c4c027391cdddf0b7fc8074bTimo Sirainen (typeof(typeof(**array ## __ ## type) const *))_array_idx(array, idx)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void *
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen_array_get_modifyable(array_t *array, unsigned int *count_r)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen if (count_r != NULL)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen *count_r = array->buffer->used / array->element_size;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen return buffer_get_modifyable_data(array->buffer, NULL);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifndef ARRAY_TYPE_CHECKS
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_get_modifyable _array_get_modifyable
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_get_modifyable(array, count) \
2a7666fd3168ba04c4c027391cdddf0b7fc8074bTimo Sirainen (typeof(*array ## __ ## type))_array_get_modifyable(array, count)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void *
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen_array_idx_modifyable(array_t *array, unsigned int idx)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen size_t pos;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen pos = idx * array->element_size;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen if (pos >= array->buffer->used) {
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen /* index doesn't exist yet, initialize with zero */
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_append_zero(array->buffer, pos + array->element_size -
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen array->buffer->used);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen }
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen return buffer_get_space_unsafe(array->buffer, pos, array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifndef ARRAY_TYPE_CHECKS
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen# define array_idx_modifyable _array_idx_modifyable
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen# define array_idx_modifyable(array, count) \
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen (typeof(*array ## __ ## type))_array_idx_modifyable(array, count)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen_array_idx_set(array_t *array, unsigned int idx, const void *data)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen size_t pos;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen pos = idx * array->element_size;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen if (pos > array->buffer->used) {
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen /* index doesn't exist yet, initialize with zero */
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_append_zero(array->buffer, pos - array->buffer->used);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen }
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_write(array->buffer, pos, data, array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifndef ARRAY_TYPE_CHECKS
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_idx_set _array_idx_set
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen# define array_idx_set(array, idx, data) STMT_START { \
2a7666fd3168ba04c4c027391cdddf0b7fc8074bTimo Sirainen typeof(const typeof(**(array ## __ ## type)) *) _array_tmp = data; \
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen _array_idx_set(array, idx, _array_tmp); \
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen } STMT_END
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void *
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen_array_append_space(array_t *array)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen void *data;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen data = buffer_append_space_unsafe(array->buffer, array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen memset(data, 0, array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen return data;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifndef ARRAY_TYPE_CHECKS
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen# define array_append_space _array_append_space
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen# define array_append_space(array) \
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen (typeof(*array ## __ ## type))_array_append_space(array)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline void *
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen_array_insert_space(array_t *array, unsigned int idx)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen void *data;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen size_t pos;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen pos = idx * array->element_size;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen buffer_copy(array->buffer, pos + array->element_size,
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen array->buffer, pos, (size_t)-1);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen data = buffer_get_space_unsafe(array->buffer, pos, array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen memset(data, 0, array->element_size);
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen return data;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
7c8d2127479db2f10e434af218d29a21b86132e9Timo Sirainen#ifndef ARRAY_TYPE_CHECKS
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen# define array_insert_space _array_insert_space
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#else
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen# define array_insert_space(array, idx) \
053843989f13d9013b265fb401a4bde7e0e6568eTimo Sirainen (typeof(*array ## __ ## type))_array_insert_space(array, idx)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenstatic inline unsigned int
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainenarray_count(const array_t *array)
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen{
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen return array->buffer->used / array->element_size;
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen}
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenstatic inline bool
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenarray_cmp(const array_t *array1, const array_t *array2)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (!array_is_created(array1) || array1->buffer->used == 0)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return !array_is_created(array2) || array2->buffer->used == 0;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (!array_is_created(array2))
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return FALSE;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return buffer_cmp(array1->buffer, array2->buffer);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
30972f343b285b6214ea053e1939b92cfe79040cTimo Sirainen#endif