• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2010 LunarG, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24  * DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 
29 #include <assert.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include "egllog.h"
34 #include "eglarray.h"
35 
36 
37 /**
38  * Grow the size of the array.
39  */
40 static EGLBoolean
_eglGrowArray(_EGLArray * array)41 _eglGrowArray(_EGLArray *array)
42 {
43    EGLint new_size;
44    void **elems;
45 
46    new_size = array->MaxSize;
47    while (new_size <= array->Size)
48       new_size *= 2;
49 
50    elems = realloc(array->Elements, new_size * sizeof(array->Elements[0]));
51    if (!elems) {
52       _eglLog(_EGL_DEBUG, "failed to grow %s array to %d",
53             array->Name, new_size);
54       return EGL_FALSE;
55    }
56 
57    array->Elements = elems;
58    array->MaxSize = new_size;
59 
60    return EGL_TRUE;
61 }
62 
63 
64 /**
65  * Create an array.
66  */
67 _EGLArray *
_eglCreateArray(const char * name,EGLint init_size)68 _eglCreateArray(const char *name, EGLint init_size)
69 {
70    _EGLArray *array;
71 
72    array = calloc(1, sizeof(*array));
73    if (array) {
74       array->Name = name;
75       array->MaxSize = (init_size > 0) ? init_size : 1;
76       if (!_eglGrowArray(array)) {
77          free(array);
78          array = NULL;
79       }
80    }
81 
82    return array;
83 }
84 
85 
86 /**
87  * Destroy an array, optionally free the data.
88  */
89 void
_eglDestroyArray(_EGLArray * array,void (* free_cb)(void *))90 _eglDestroyArray(_EGLArray *array, void (*free_cb)(void *))
91 {
92    if (free_cb) {
93       EGLint i;
94       for (i = 0; i < array->Size; i++)
95          free_cb(array->Elements[i]);
96    }
97    free(array->Elements);
98    free(array);
99 }
100 
101 
102 /**
103  * Append a element to an array.
104  */
105 void
_eglAppendArray(_EGLArray * array,void * elem)106 _eglAppendArray(_EGLArray *array, void *elem)
107 {
108    if (array->Size >= array->MaxSize && !_eglGrowArray(array))
109       return;
110 
111    array->Elements[array->Size++] = elem;
112 }
113 
114 
115 /**
116  * Erase an element from an array.
117  */
118 void
_eglEraseArray(_EGLArray * array,EGLint i,void (* free_cb)(void *))119 _eglEraseArray(_EGLArray *array, EGLint i, void (*free_cb)(void *))
120 {
121    if (free_cb)
122       free_cb(array->Elements[i]);
123    if (i < array->Size - 1) {
124       memmove(&array->Elements[i], &array->Elements[i + 1],
125             (array->Size - i - 1) * sizeof(array->Elements[0]));
126    }
127    array->Size--;
128 }
129 
130 
131 /**
132  * Find in an array for the given element.
133  */
134 void *
_eglFindArray(_EGLArray * array,void * elem)135 _eglFindArray(_EGLArray *array, void *elem)
136 {
137    EGLint i;
138 
139    if (!array)
140       return NULL;
141 
142    for (i = 0; i < array->Size; i++)
143       if (array->Elements[i] == elem)
144          return elem;
145    return NULL;
146 }
147 
148 
149 /**
150  * Filter an array and return the number of filtered elements.
151  */
152 EGLint
_eglFilterArray(_EGLArray * array,void ** data,EGLint size,_EGLArrayForEach filter,void * filter_data)153 _eglFilterArray(_EGLArray *array, void **data, EGLint size,
154                 _EGLArrayForEach filter, void *filter_data)
155 {
156    EGLint count = 0, i;
157 
158    if (!array)
159       return 0;
160 
161    assert(filter);
162    for (i = 0; i < array->Size; i++) {
163       if (filter(array->Elements[i], filter_data)) {
164          if (data && count < size)
165             data[count] = array->Elements[i];
166          count++;
167       }
168       if (data && count >= size)
169          break;
170    }
171 
172    return count;
173 }
174 
175 
176 /**
177  * Flatten an array by converting array elements into another form and store
178  * them in a buffer.
179  */
180 EGLint
_eglFlattenArray(_EGLArray * array,void * buffer,EGLint elem_size,EGLint size,_EGLArrayForEach flatten)181 _eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size,
182                  _EGLArrayForEach flatten)
183 {
184    EGLint i, count;
185 
186    if (!array)
187       return 0;
188 
189    count = array->Size;
190    if (buffer) {
191       /* clamp size to 0 */
192       if (size < 0)
193          size = 0;
194       /* do not exceed buffer size */
195       if (count > size)
196          count = size;
197       for (i = 0; i < count; i++)
198          flatten(array->Elements[i],
199                (void *) ((char *) buffer + elem_size * i));
200    }
201 
202    return count;
203 }
204