From 15cdb30e3125ce542289fe385f559799e5abf220 Mon Sep 17 00:00:00 2001 From: John Mark Bell Date: Mon, 24 Aug 2009 08:06:29 +0000 Subject: Beginnings of port to core buildsystem svn path=/trunk/libsvgtiny/; revision=9419 --- src/svgtiny_list.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/svgtiny_list.c (limited to 'src/svgtiny_list.c') diff --git a/src/svgtiny_list.c b/src/svgtiny_list.c new file mode 100644 index 0000000..53cfb34 --- /dev/null +++ b/src/svgtiny_list.c @@ -0,0 +1,125 @@ +/* + * This file is part of Libsvgtiny + * Licensed under the MIT License, + * http://opensource.org/licenses/mit-license.php + * Copyright 2008 James Bursa + */ + +/** + * A svgtiny_list is a managed array of objects. It grows in chunks to reduce + * calls to realloc(), but keeps wasted space low. + */ + +#include +#include "svgtiny.h" +#include "svgtiny_internal.h" + + +struct svgtiny_list { + unsigned int size; /* number of slots used */ + unsigned int allocated; /* number of slots allocated (>= size) */ + size_t item_size; /* size of each slot / bytes */ + char *items; /* array of slots */ +}; + + +/** + * Create an empty svgtiny_list. + */ + +struct svgtiny_list *svgtiny_list_create(size_t item_size) +{ + struct svgtiny_list *list = malloc(sizeof *list); + if (!list) + return 0; + list->size = 0; + list->allocated = 0; + list->item_size = item_size; + list->items = 0; + return list; +} + + +/** + * Return the number of objects in a list. + */ + +unsigned int svgtiny_list_size(struct svgtiny_list *list) +{ + return list->size; +} + + +/** + * Set the number of objects in a list. If the size is increased, the new + * objects are not initialized in any way. + * + * The allocation size formula is taken from Python's list: + * http://svn.python.org/view/python/trunk/Objects/listobject.c?view=markup + * + * Objects may have moved after this call. Use svgtiny_list_get() to get new + * pointers. + */ + +svgtiny_code svgtiny_list_resize(struct svgtiny_list *list, + unsigned int new_size) +{ + unsigned int new_allocated; + void *new_items; + + if (new_size <= list->allocated) { + list->size = new_size; + return svgtiny_OK; + } + + new_allocated = (new_size >> 3) + (new_size < 9 ? 3 : 6) + new_size; + if (new_size == 0) + new_allocated = 0; + new_items = realloc(list->items, new_allocated * list->item_size); + if (!new_items) + return svgtiny_OUT_OF_MEMORY; + + list->size = new_size; + list->allocated = new_allocated; + list->items = new_items; + + return svgtiny_OK; +} + + +/** + * Return a pointer to an object in a list. + */ + +void *svgtiny_list_get(struct svgtiny_list *list, + unsigned int i) +{ + assert(i < list->size); + return (void *) (list->items + i * list->item_size); +} + + +/** + * Add space for one object to a list and return a pointer to it. + */ + +void *svgtiny_list_push(struct svgtiny_list *list) +{ + svgtiny_code code; + code = svgtiny_list_resize(list, list->size + 1); + if (code != svgtiny_OK) + return 0; + return svgtiny_list_get(list, list->size - 1); +} + + +/** + * Free an entire list. + */ + +void svgtiny_list_free(struct svgtiny_list *list) +{ + free(list->items); + free(list); +} + -- cgit v1.2.3