]> git.sesse.net Git - vlc/blob - modules/codec/cmml/xarray.c
Remove _GNU_SOURCE and string.h too
[vlc] / modules / codec / cmml / xarray.c
1 /*************************************************************************
2  * xarray.c: Mutable (dynamically growable) array
3  *************************************************************************
4  * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
5  *                    Organisation (CSIRO) Australia
6  * Copyright (C) 2004 the VideoLAN team
7  *
8  * $Id$
9  *
10  * Authors: Andre Pang <Andre.Pang@csiro.au>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25  ************************************************************************/
26
27
28 #include "xarray.h"
29
30 #define XARRAY_ASSERT_NOT_NULL(xarray) \
31     { \
32         if (xarray == NULL) return XARRAY_ENULLPOINTER; \
33     }
34
35 #define XARRAY_BOUNDS_CHECK(xarray, index) \
36     { \
37         if (index < 0) \
38             return XARRAY_ENEGATIVEINDEX; \
39         else if (xarray->last_valid_element != -1 && \
40                  (int) index > xarray->last_valid_element) \
41             return XARRAY_EINDEXTOOLARGE; \
42     }
43
44 #define XARRAY_GROW_ARRAY(xarray) \
45     { \
46         xarray->array = (void *) realloc (xarray->array, xarray->size * 2); \
47         if (xarray->array == NULL) return XARRAY_ENOMEM; \
48     }
49
50 XSTATIC XArray * xarray_New (unsigned int initial_size_hint)
51 {
52     XArray *new_xarray = NULL;
53     void *inner_array;
54     unsigned int initial_size;
55
56     new_xarray = (XArray *) malloc (sizeof(XArray));
57     if (new_xarray == NULL) return NULL;
58
59     if (initial_size_hint <= 0)
60         initial_size = XARRAY_DEFAULT_SIZE;
61     else
62         initial_size = initial_size_hint;
63
64     inner_array = calloc (initial_size, sizeof(void *));
65
66     new_xarray->last_valid_element = -1;
67     new_xarray->size = initial_size;
68     new_xarray->last_error = 0;
69
70     if (inner_array == NULL)
71     {
72         free (new_xarray);
73         return NULL;
74     }
75
76     new_xarray->array = inner_array;
77
78     /* Make a dummy reference to other functions, so that we don't get
79      * warnings about unused functions from the compiler.  Ahem :) */
80     while (0)
81     {
82         void *dummy_reference;
83
84         dummy_reference = xarray_AddObject;
85         dummy_reference = xarray_InsertObject;
86         dummy_reference = xarray_RemoveLastObject;
87         dummy_reference = xarray_RemoveObject;
88         dummy_reference = xarray_RemoveObjects;
89         dummy_reference = xarray_RemoveObjectsAfter;
90         dummy_reference = xarray_ReplaceObject;
91
92         dummy_reference = xarray_ObjectAtIndex;
93         dummy_reference = xarray_Count;
94     }
95     
96     return new_xarray;
97 }
98
99 XSTATIC int xarray_ObjectAtIndex (XArray *xarray, unsigned int index,
100         void **out_object)
101 {
102     XARRAY_ASSERT_NOT_NULL (xarray);
103     XARRAY_BOUNDS_CHECK (xarray, index);
104
105     *out_object = xarray->array[index];
106
107     return XARRAY_SUCCESS;
108 }
109
110 XSTATIC int xarray_AddObject (XArray *xarray, void *object)
111 {
112     XARRAY_ASSERT_NOT_NULL (xarray);
113
114     ++xarray->last_valid_element;
115     if (xarray->last_valid_element >= (int) xarray->size)
116     {
117         XARRAY_GROW_ARRAY (xarray);
118     }
119
120     xarray->array[xarray->last_valid_element] = object;
121
122     return XARRAY_SUCCESS;
123 }
124
125 XSTATIC int xarray_InsertObject (XArray *xarray, void *object,
126         unsigned int at_index)
127 {
128     XARRAY_ASSERT_NOT_NULL (xarray);
129     ++xarray->last_valid_element;
130     XARRAY_BOUNDS_CHECK (xarray, at_index);
131     if (xarray->last_valid_element >= (int) xarray->size)
132     {
133         XARRAY_GROW_ARRAY (xarray);
134     }
135
136     /* Shift everything from a[i] onward one pointer forward */
137
138     if ((int) at_index < xarray->last_valid_element)
139     {
140         (void) memmove (&xarray->array[at_index + 1],
141                         &xarray->array[at_index],
142                         (xarray->last_valid_element - at_index) *
143                             sizeof(void *));
144     }
145
146     xarray->array[at_index] = object;
147
148     return XARRAY_SUCCESS;
149 }
150
151 XSTATIC int xarray_RemoveLastObject (XArray *xarray)
152 {
153     XARRAY_ASSERT_NOT_NULL (xarray);
154
155     if (xarray->last_valid_element == -1)
156         return XARRAY_EEMPTYARRAY;
157
158     xarray->array[xarray->last_valid_element] = NULL;
159     --xarray->last_valid_element;
160
161     return XARRAY_SUCCESS;
162 }
163
164 XSTATIC int xarray_RemoveObject (XArray *xarray, unsigned int at_index)
165 {
166     XARRAY_ASSERT_NOT_NULL (xarray);
167     XARRAY_BOUNDS_CHECK (xarray, at_index);
168
169     /* Shift everything from a[i] onward one pointer backward */
170
171     if ((int) at_index < xarray->last_valid_element)
172     {
173         (void) memmove (&xarray->array[at_index],
174                         &xarray->array[at_index + 1],
175                         (xarray->last_valid_element - at_index) *
176                             sizeof(void *));
177     }
178
179     xarray->array[xarray->last_valid_element] = NULL;
180     --xarray->last_valid_element;
181
182     return XARRAY_SUCCESS;    
183 }
184
185 XSTATIC int xarray_RemoveObjects (XArray *xarray, unsigned int at_index,
186         int count)
187 {
188     int i;
189
190     XARRAY_ASSERT_NOT_NULL (xarray);
191     XARRAY_BOUNDS_CHECK (xarray, at_index);
192
193     if (count == 0) return XARRAY_SUCCESS;
194
195     if ((int) at_index + (count - 1) > xarray->last_valid_element)
196         return XARRAY_ECOUNTOUTOFBOUNDS;
197
198     for (i = 0; i < count; i++)
199     {
200         int e = xarray_RemoveObject (xarray, at_index);
201         if (e != XARRAY_SUCCESS) return e;
202     }
203
204     return XARRAY_SUCCESS;
205 }
206
207 XSTATIC int xarray_RemoveObjectsAfter (XArray *xarray, unsigned int index)
208 {
209     XARRAY_ASSERT_NOT_NULL (xarray);
210     XARRAY_BOUNDS_CHECK (xarray, index);
211
212     index++;
213
214     while ((int) index <= xarray->last_valid_element)
215     {
216         int e = xarray_RemoveObject (xarray, index);
217         if (e != XARRAY_SUCCESS) return e;
218     }
219
220     return XARRAY_SUCCESS;
221 }
222
223 XSTATIC int xarray_ReplaceObject (XArray *xarray, unsigned int index,
224         void *new_object)
225 {
226     XARRAY_ASSERT_NOT_NULL (xarray);
227     XARRAY_BOUNDS_CHECK (xarray, index);
228
229     xarray->array[index] = new_object;
230
231     return XARRAY_SUCCESS;
232 }
233
234 XSTATIC int xarray_Count (XArray *xarray, unsigned int *out_count)
235 {
236     XARRAY_ASSERT_NOT_NULL (xarray);
237
238     *out_count = xarray->last_valid_element + 1;
239
240     return XARRAY_SUCCESS;
241 }
242
243
244 #undef XARRAY_ASSERT_NOT_NULL
245 #undef XARRAY_BOUNDS_CHECK
246 #undef XARRAY_GROW_ARRAY
247