From 7b2ba6dfce48c9aa7df7c5e096bc74bd023b2efc Mon Sep 17 00:00:00 2001 From: Søren Sandmann Pedersen Date: Fri, 17 Apr 2009 22:34:03 -0400 Subject: Add prefixes to arrays --- Makefile.am | 6 +++++- array.c | 29 ++++++++++++++++++++++------- libnul.h | 1 + prefix-test.c | 40 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+), 8 deletions(-) create mode 100644 prefix-test.c diff --git a/Makefile.am b/Makefile.am index 530e464..485385a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,13 +25,17 @@ libnul_la_LIBADD = @DEP_LIBS@ libffi/libffi_convenience.la libnul_la_LDFLAGS = -no-undefined -noinst_PROGRAMS = example dbw-example +noinst_PROGRAMS = example dbw-example prefix-test + example_SOURCES = example.c example_LDADD = $(top_builddir)/libnul.la dbw_example_SOURCES = dbw-example.c dbw_example_LDADD = $(top_builddir)/libnul.la +prefix_test_SOURCES = prefix-test.c +prefix_test_LDADD = $(top_builddir)/libnul.la + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnul.pc diff --git a/array.c b/array.c index d436414..f8e9b82 100644 --- a/array.c +++ b/array.c @@ -39,6 +39,7 @@ struct array_t gssize n_elements; /* Number of elements in use, not including * the nul terminator */ + gssize n_prefix_bytes; /* Number of data bytes used for the application prefix */ align_t data[1]; }; @@ -65,7 +66,10 @@ array_free (void *data, const int *magic) static void nul_terminate (array_t *array) { - char *end = (char *)array->data + array->n_elements * array->element_size; + char *end = (char *)array->data; + + end += array->n_prefix_bytes; + end += array->n_elements * array->element_size; memset (end, 0, array->element_size); } @@ -78,6 +82,7 @@ realloc_array (array_t *array, int n_elements) /* FIXME: overflow? */ n_bytes = NUL_STRUCT_OFFSET (array_t, data); n_bytes += (n_elements + 1) * array->element_size; + n_bytes += array->n_prefix_bytes; if (n_bytes > array->n_bytes) { @@ -97,12 +102,13 @@ realloc_array (array_t *array, int n_elements) } static void * -array_new (int element_size, const int *magic) +array_new (int element_size, const int *magic, int n_prefix_bytes) { array_t *array = g_new (array_t, 1); array->magic = magic; array->element_size = element_size; + array->n_prefix_bytes = n_prefix_bytes; array->n_bytes = sizeof (array_t); array->n_elements = 0; @@ -117,13 +123,16 @@ array_delete_head (void *data, const int *magic, gssize n_elements) array_t *array = get_array (data, magic); int n_bytes = n_elements * array->element_size; int n_total = array->n_elements * array->element_size; + char *first; if (n_elements < 0 || n_elements > array->n_elements) n_bytes = n_total; /* FIXME: this should be done in constant time */ + + first = (char *)array->data + array->n_prefix_bytes; - memmove (array->data, (char *)array->data + n_bytes, n_total - n_bytes); + memmove (first, first + n_bytes, n_total - n_bytes); array->n_elements -= n_elements; @@ -158,7 +167,7 @@ array_append_undefined (void *data, nul_terminate (array); if (tail) - *tail = (char *)array->data + array->element_size * (array->n_elements - n_elements); + *tail = (char *)array->data + array->n_prefix_bytes + array->element_size * (array->n_elements - n_elements); return array->data; } @@ -205,7 +214,13 @@ static const int arr_t_magic; nul_ptr_t nul_array_new (int element_size) { - return array_new (element_size, &arr_t_magic); + return array_new (element_size, &arr_t_magic, 0); +} + +nul_ptr_t +nul_array_new_prefix (int element_size, int prefix_size) +{ + return array_new (element_size, &arr_t_magic, prefix_size); } nul_ptr_t @@ -256,7 +271,7 @@ static const int parr_t_magic; void ** nul_ptr_array_new (void) { - return array_new (sizeof (void *), &parr_t_magic); + return array_new (sizeof (void *), &parr_t_magic, 0); } void ** @@ -285,7 +300,7 @@ static const int string_t_magic; nul_string_t * nul_string_new (void) { - return array_new (sizeof (char), &string_t_magic); + return array_new (sizeof (char), &string_t_magic, 0); } void diff --git a/libnul.h b/libnul.h index f22acf7..3bf4106 100644 --- a/libnul.h +++ b/libnul.h @@ -53,6 +53,7 @@ typedef void * const nul_const_ptr_t; * Generic arrays */ nul_ptr_t nul_array_new (int element_size) NUL_UR; +nul_ptr_t nul_array_new_prefix (int element_size, int prefix_size); NUL_UR; nul_ptr_t nul_array_append (nul_ptr_t array, nul_ptr_t element) NUL_UR; gsize nul_array_len (nul_ptr_t array); void nul_array_free (nul_ptr_t array); diff --git a/prefix-test.c b/prefix-test.c new file mode 100644 index 0000000..5c44562 --- /dev/null +++ b/prefix-test.c @@ -0,0 +1,40 @@ +#include +#include + +typedef struct +{ + int a; + int b; + char *x; + + int data[1]; + +} prefixed_t; + + +int +main (void) +{ + int i; + prefixed_t *prefixed = nul_array_new_prefix ( + sizeof (int), NUL_STRUCT_OFFSET (prefixed_t, data)); + + prefixed->a = 0xaaaaaaaa; + prefixed->b = 0xbbbbbbbb; + prefixed->x = "HI!"; + + i = 0; + prefixed = nul_array_append (prefixed, &i); i++; + prefixed = nul_array_append (prefixed, &i); i++; + prefixed = nul_array_append (prefixed, &i); i++; + prefixed = nul_array_append (prefixed, &i); i++; + prefixed = nul_array_append (prefixed, &i); i++; + prefixed = nul_array_append (prefixed, &i); i++; + + for (i = 0; i < nul_array_len (prefixed); ++i) + { + printf ("%d\n", prefixed->data[i]); + } + + return 0; +} -- cgit v1.2.3