/* * Copyright (c) 2011 Collabora Ltd. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above * copyright notice, this list of conditions and the * following disclaimer. * * Redistributions in binary form must reproduce the * above copyright notice, this list of conditions and * the following disclaimer in the documentation and/or * other materials provided with the distribution. * * The names of contributors to this software may not be * used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ #include "config.h" #include "ptr-array.h" #include #include struct ptr_array { void **memory; unsigned int length; unsigned int allocated; ptr_array_destroy_func destroy; }; static int maybe_expand_array (ptr_array_t *array, unsigned int length) { unsigned int new_allocated; void **new_memory; if (length <= array->allocated) return 1; new_allocated = array->allocated + 16; if (new_allocated < length) new_allocated = length; new_memory = realloc (array->memory, new_allocated * sizeof (void*)); if (new_memory == NULL) return 0; array->memory = new_memory; array->allocated = new_allocated; return 1; } ptr_array_t* ptr_array_create (ptr_array_destroy_func destroy_func) { ptr_array_t *array; array = calloc (1, sizeof (ptr_array_t)); if (array == NULL) return NULL; if (!maybe_expand_array (array, 2)) { ptr_array_free (array); return NULL; } array->destroy = destroy_func; return array; } void ptr_array_free (ptr_array_t *array) { unsigned int i; if (array == NULL) return; if (array->destroy) { for (i = 0; i < array->length; i++) (array->destroy) (array->memory[i]); } free (array->memory); free (array); } unsigned int ptr_array_count (ptr_array_t *array) { return array->length; } int ptr_array_add (ptr_array_t *array, void *value) { if (!maybe_expand_array (array, array->length + 1)) return 0; array->memory[array->length] = value; array->length++; return 1; } void ptr_array_remove (ptr_array_t *array, unsigned int index) { if (array->destroy) (array->destroy) (array->memory[index]); memmove (array->memory + index, array->memory + index + 1, (array->length - (index + 1)) * sizeof (void*)); array->length--; } void* ptr_array_at (ptr_array_t *array, unsigned int index) { return array->memory[index]; } void** ptr_array_snapshot (ptr_array_t *array) { void **snapshot; size_t bytes; bytes = array->length * sizeof (void*); snapshot = malloc (bytes); if (!snapshot) return NULL; memcpy (snapshot, array->memory, bytes); return snapshot; }