diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-08-29 23:45:45 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-08-29 23:45:45 -0400 |
commit | a30b3f503bede87043262343ed26d6995b0a85d9 (patch) | |
tree | e24031938af531e2d2b308ae0c48f5c2639775b7 /darray.c | |
parent | c14a376ef6effe089d98e2211cb15e4b66e57fc1 (diff) | |
download | bfs-a30b3f503bede87043262343ed26d6995b0a85d9.tar.xz |
darray: New dynamic array library
Diffstat (limited to 'darray.c')
-rw-r--r-- | darray.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/darray.c b/darray.c new file mode 100644 index 0000000..459eb4d --- /dev/null +++ b/darray.c @@ -0,0 +1,95 @@ +/**************************************************************************** + * bfs * + * Copyright (C) 2019 Tavian Barnes <tavianator@tavianator.com> * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted. * + * * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ****************************************************************************/ + +#include "darray.h" +#include <stdlib.h> +#include <string.h> + +/** + * The darray header. + */ +struct darray { + size_t capacity; + size_t length; +}; + +/** Get the header for a darray. */ +static struct darray *darray_header(const void *da) { + return (struct darray *)da - 1; +} + +/** Get the array from a darray header. */ +static char *darray_data(struct darray *header) { + return (char *)(header + 1); +} + +size_t darray_length(const void *da) { + if (da) { + return darray_header(da)->length; + } else { + return 0; + } +} + +void *darray_push(void *da, const void *item, size_t size) { + struct darray *header; + if (da) { + header = darray_header(da); + } else { + header = malloc(sizeof(*header) + size); + if (!header) { + return NULL; + } + header->capacity = 1; + header->length = 0; + } + + size_t capacity = header->capacity; + size_t i = header->length++; + if (i >= capacity) { + capacity *= 2; + header = realloc(header, sizeof(*header) + capacity*size); + if (!header) { + // This failure will be detected by darray_check() + return da; + } + header->capacity = capacity; + } + + char *data = darray_data(header); + memcpy(data + i*size, item, size); + return data; +} + +int darray_check(void *da) { + if (!da) { + return -1; + } + + struct darray *header = darray_header(da); + if (header->length <= header->capacity) { + return 0; + } else { + header->length = header->capacity; + return -1; + } +} + +void darray_free(void *da) { + if (da) { + free(darray_header(da)); + } +} |