scons: Updates for targets/egl-static.
[mesa.git] / src / egl / main / eglarray.c
1 #include <stdlib.h>
2 #include <string.h>
3
4 #include "egllog.h"
5 #include "eglarray.h"
6
7
8 /**
9 * Grow the size of the array.
10 */
11 static EGLBoolean
12 _eglGrowArray(_EGLArray *array)
13 {
14 EGLint new_size;
15 void **elems;
16
17 new_size = array->MaxSize;
18 while (new_size <= array->Size)
19 new_size *= 2;
20
21 elems = realloc(array->Elements, new_size * sizeof(array->Elements[0]));
22 if (!elems) {
23 _eglLog(_EGL_DEBUG, "failed to grow %s array to %d",
24 array->Name, new_size);
25 return EGL_FALSE;
26 }
27
28 array->Elements = elems;
29 array->MaxSize = new_size;
30
31 return EGL_TRUE;
32 }
33
34
35 /**
36 * Create an array.
37 */
38 _EGLArray *
39 _eglCreateArray(const char *name, EGLint init_size)
40 {
41 _EGLArray *array;
42
43 array = calloc(1, sizeof(*array));
44 if (array) {
45 array->Name = name;
46 array->MaxSize = (init_size > 0) ? init_size : 1;
47 if (!_eglGrowArray(array)) {
48 free(array);
49 array = NULL;
50 }
51 }
52
53 return array;
54 }
55
56
57 /**
58 * Destroy an array, optionally free the data.
59 */
60 void
61 _eglDestroyArray(_EGLArray *array, void (*free_cb)(void *))
62 {
63 if (free_cb) {
64 EGLint i;
65 for (i = 0; i < array->Size; i++)
66 free_cb(array->Elements[i]);
67 }
68 free(array->Elements);
69 free(array);
70 }
71
72
73 /**
74 * Append a element to an array.
75 */
76 void
77 _eglAppendArray(_EGLArray *array, void *elem)
78 {
79 if (array->Size >= array->MaxSize && !_eglGrowArray(array))
80 return;
81
82 array->Elements[array->Size++] = elem;
83 }
84
85
86 /**
87 * Erase an element from an array.
88 */
89 void
90 _eglEraseArray(_EGLArray *array, EGLint i, void (*free_cb)(void *))
91 {
92 if (free_cb)
93 free_cb(array->Elements[i]);
94 if (i < array->Size - 1) {
95 memmove(&array->Elements[i], &array->Elements[i + 1],
96 (array->Size - i - 1) * sizeof(array->Elements[0]));
97 }
98 array->Size--;
99 }
100
101
102 /**
103 * Find in an array for the given element.
104 */
105 void *
106 _eglFindArray(_EGLArray *array, void *elem)
107 {
108 EGLint i;
109
110 if (!array)
111 return NULL;
112
113 for (i = 0; i < array->Size; i++)
114 if (array->Elements[i] == elem)
115 return elem;
116 return NULL;
117 }
118
119
120 /**
121 * Filter an array and return the number of filtered elements.
122 */
123 EGLint
124 _eglFilterArray(_EGLArray *array, void **data, EGLint size,
125 _EGLArrayForEach filter, void *filter_data)
126 {
127 EGLint count = 0, i;
128
129 if (!array)
130 return 0;
131
132 if (filter) {
133 for (i = 0; i < array->Size; i++) {
134 if (filter(array->Elements[i], filter_data)) {
135 if (data && count < size)
136 data[count] = array->Elements[i];
137 count++;
138 }
139 if (data && count >= size)
140 break;
141 }
142 }
143 else {
144 if (data) {
145 count = (size < array->Size) ? size : array->Size;
146 memcpy(data, array->Elements, count * sizeof(array->Elements[0]));
147 }
148 else {
149 count = array->Size;
150 }
151 }
152
153 return count;
154 }
155
156
157 /**
158 * Flatten an array by converting array elements into another form and store
159 * them in a buffer.
160 */
161 EGLint
162 _eglFlattenArray(_EGLArray *array, void *buffer, EGLint elem_size, EGLint size,
163 _EGLArrayForEach flatten)
164 {
165 EGLint i, count;
166
167 if (!array)
168 return 0;
169
170 count = array->Size;
171 if (buffer) {
172 /* do not exceed buffer size */
173 if (count > size)
174 count = size;
175 for (i = 0; i < count; i++)
176 flatten(array->Elements[i],
177 (void *) ((char *) buffer + elem_size * i));
178 }
179
180 return count;
181 }