/**************************************************************************1*2* Copyright 2010 LunarG, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR18* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,19* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL20* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER21* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING22* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER23* DEALINGS IN THE SOFTWARE.24*25**************************************************************************/262728#include <assert.h>29#include <stdlib.h>30#include <string.h>3132#include "egllog.h"33#include "eglarray.h"343536/**37* Grow the size of the array.38*/39static EGLBoolean40_eglGrowArray(_EGLArray *array)41{42EGLint new_size;43void **elems;4445new_size = array->MaxSize;46while (new_size <= array->Size)47new_size *= 2;4849elems = realloc(array->Elements, new_size * sizeof(array->Elements[0]));50if (!elems) {51_eglLog(_EGL_DEBUG, "failed to grow %s array to %d",52array->Name, new_size);53return EGL_FALSE;54}5556array->Elements = elems;57array->MaxSize = new_size;5859return EGL_TRUE;60}616263/**64* Create an array.65*/66_EGLArray *67_eglCreateArray(const char *name, EGLint init_size)68{69_EGLArray *array;7071array = calloc(1, sizeof(*array));72if (array) {73array->Name = name;74array->MaxSize = (init_size > 0) ? init_size : 1;75if (!_eglGrowArray(array)) {76free(array);77array = NULL;78}79}8081return array;82}838485/**86* Destroy an array, optionally free the data.87*/88void89_eglDestroyArray(_EGLArray *array, void (*free_cb)(void *))90{91if (free_cb) {92EGLint i;93for (i = 0; i < array->Size; i++)94free_cb(array->Elements[i]);95}96free(array->Elements);97free(array);98}99100101/**102* Append a element to an array.103*/104void105_eglAppendArray(_EGLArray *array, void *elem)106{107if (array->Size >= array->MaxSize && !_eglGrowArray(array))108return;109110array->Elements[array->Size++] = elem;111}112113114/**115* Erase an element from an array.116*/117void118_eglEraseArray(_EGLArray *array, EGLint i, void (*free_cb)(void *))119{120if (free_cb)121free_cb(array->Elements[i]);122if (i < array->Size - 1) {123memmove(&array->Elements[i], &array->Elements[i + 1],124(array->Size - i - 1) * sizeof(array->Elements[0]));125}126array->Size--;127}128129130/**131* Find in an array for the given element.132*/133void *134_eglFindArray(_EGLArray *array, void *elem)135{136EGLint i;137138if (!array)139return NULL;140141for (i = 0; i < array->Size; i++)142if (array->Elements[i] == elem)143return elem;144return NULL;145}146147148/**149* Filter an array and return the number of filtered elements.150*/151EGLint152_eglFilterArray(_EGLArray *array, void **data, EGLint size,153_EGLArrayForEach filter, void *filter_data)154{155EGLint count = 0, i;156157if (!array)158return 0;159160assert(filter);161for (i = 0; i < array->Size; i++) {162if (filter(array->Elements[i], filter_data)) {163if (data && count < size)164data[count] = array->Elements[i];165count++;166}167if (data && count >= size)168break;169}170171return count;172}173174175/**176* Flatten an array by converting array elements into another form and store177* them in a buffer.178*/179EGLint180_eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size,181_EGLArrayForEach flatten)182{183EGLint i, count;184185if (!array)186return 0;187188count = array->Size;189if (buffer) {190/* clamp size to 0 */191if (size < 0)192size = 0;193/* do not exceed buffer size */194if (count > size)195count = size;196for (i = 0; i < count; i++)197flatten(array->Elements[i],198(void *) ((char *) buffer + elem_size * i));199}200201return count;202}203204205