]> git.sesse.net Git - vlc/blob - modules/codec/cmml/xarray.c
Usefull coment instead of "Gruik" (evenif I like the previous one...)
[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 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <stddef.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include "xarray.h"
34
35 /* local prototypes */
36 XSTATIC XArray * xarray_New (unsigned int);
37
38
39 #define XARRAY_ASSERT_NOT_NULL(xarray) \
40     { \
41         if (xarray == NULL) return XARRAY_ENULLPOINTER; \
42     }
43
44 #define XARRAY_BOUNDS_CHECK(xarray, index) \
45     { \
46         if (xarray->last_valid_element != -1 && \
47                  (int) index > xarray->last_valid_element) \
48             return XARRAY_EINDEXTOOLARGE; \
49     }
50
51 #define XARRAY_GROW_ARRAY(xarray) \
52     { \
53         xarray->array = (void *) realloc (xarray->array, xarray->size * 2); \
54         if (xarray->array == NULL) return XARRAY_ENOMEM; \
55     }
56
57 XSTATIC XArray * xarray_New (unsigned int initial_size_hint)
58 {
59     XArray *new_xarray = NULL;
60     void *inner_array;
61     unsigned int initial_size;
62
63     new_xarray = (XArray *) malloc (sizeof(XArray));
64     if (new_xarray == NULL) return NULL;
65
66     if (initial_size_hint == 0)
67         initial_size = XARRAY_DEFAULT_SIZE;
68     else
69         initial_size = initial_size_hint;
70
71     inner_array = calloc (initial_size, sizeof(void *));
72
73     new_xarray->last_valid_element = -1;
74     new_xarray->size = initial_size;
75     new_xarray->last_error = 0;
76
77     if (inner_array == NULL)
78     {
79         free (new_xarray);
80         return NULL;
81     }
82
83     new_xarray->array = inner_array;
84
85     /* Make a dummy reference to other functions, so that we don't get
86      * warnings about unused functions from the compiler.  Ahem :) */
87     while (0)
88     {
89         void *dummy_reference;
90
91         dummy_reference = xarray_AddObject;
92         dummy_reference = xarray_InsertObject;
93         dummy_reference = xarray_RemoveLastObject;
94         dummy_reference = xarray_RemoveObject;
95         dummy_reference = xarray_RemoveObjects;
96         dummy_reference = xarray_RemoveObjectsAfter;
97         dummy_reference = xarray_ReplaceObject;
98
99         dummy_reference = xarray_ObjectAtIndex;
100         dummy_reference = xarray_Count;
101     }
102  
103     return new_xarray;
104 }
105
106 XSTATIC int xarray_ObjectAtIndex (XArray *xarray, unsigned int index,
107         void **out_object)
108 {
109     XARRAY_ASSERT_NOT_NULL (xarray);
110     XARRAY_BOUNDS_CHECK (xarray, index);
111
112     *out_object = xarray->array[index];
113
114     return XARRAY_SUCCESS;
115 }
116
117 XSTATIC int xarray_AddObject (XArray *xarray, void *object)
118 {
119     XARRAY_ASSERT_NOT_NULL (xarray);
120
121     ++xarray->last_valid_element;
122     if (xarray->last_valid_element >= (int) xarray->size)
123     {
124         XARRAY_GROW_ARRAY (xarray);
125     }
126
127     xarray->array[xarray->last_valid_element] = object;
128
129     return XARRAY_SUCCESS;
130 }
131
132 XSTATIC int xarray_InsertObject (XArray *xarray, void *object,
133         unsigned int at_index)
134 {
135     XARRAY_ASSERT_NOT_NULL (xarray);
136     ++xarray->last_valid_element;
137     XARRAY_BOUNDS_CHECK (xarray, at_index);
138     if (xarray->last_valid_element >= (int) xarray->size)
139     {
140         XARRAY_GROW_ARRAY (xarray);
141     }
142
143     /* Shift everything from a[i] onward one pointer forward */
144
145     if ((int) at_index < xarray->last_valid_element)
146     {
147         (void) memmove (&xarray->array[at_index + 1],
148                         &xarray->array[at_index],
149                         (xarray->last_valid_element - at_index) *
150                             sizeof(void *));
151     }
152
153     xarray->array[at_index] = object;
154
155     return XARRAY_SUCCESS;
156 }
157
158 XSTATIC int xarray_RemoveLastObject (XArray *xarray)
159 {
160     XARRAY_ASSERT_NOT_NULL (xarray);
161
162     if (xarray->last_valid_element == -1)
163         return XARRAY_EEMPTYARRAY;
164
165     xarray->array[xarray->last_valid_element] = NULL;
166     --xarray->last_valid_element;
167
168     return XARRAY_SUCCESS;
169 }
170
171 XSTATIC int xarray_RemoveObject (XArray *xarray, unsigned int at_index)
172 {
173     XARRAY_ASSERT_NOT_NULL (xarray);
174     XARRAY_BOUNDS_CHECK (xarray, at_index);
175
176     /* Shift everything from a[i] onward one pointer backward */
177
178     if ((int) at_index < xarray->last_valid_element)
179     {
180         (void) memmove (&xarray->array[at_index],
181                         &xarray->array[at_index + 1],
182                         (xarray->last_valid_element - at_index) *
183                             sizeof(void *));
184     }
185
186     xarray->array[xarray->last_valid_element] = NULL;
187     --xarray->last_valid_element;
188
189     return XARRAY_SUCCESS;
190 }
191
192 XSTATIC int xarray_RemoveObjects (XArray *xarray, unsigned int at_index,
193         int count)
194 {
195     int i;
196
197     XARRAY_ASSERT_NOT_NULL (xarray);
198     XARRAY_BOUNDS_CHECK (xarray, at_index);
199
200     if (count == 0) return XARRAY_SUCCESS;
201
202     if ((int) at_index + (count - 1) > xarray->last_valid_element)
203         return XARRAY_ECOUNTOUTOFBOUNDS;
204
205     for (i = 0; i < count; i++)
206     {
207         int e = xarray_RemoveObject (xarray, at_index);
208         if (e != XARRAY_SUCCESS) return e;
209     }
210
211     return XARRAY_SUCCESS;
212 }
213
214 XSTATIC int xarray_RemoveObjectsAfter (XArray *xarray, unsigned int index)
215 {
216     XARRAY_ASSERT_NOT_NULL (xarray);
217     XARRAY_BOUNDS_CHECK (xarray, index);
218
219     index++;
220
221     while ((int) index <= xarray->last_valid_element)
222     {
223         int e = xarray_RemoveObject (xarray, index);
224         if (e != XARRAY_SUCCESS) return e;
225     }
226
227     return XARRAY_SUCCESS;
228 }
229
230 XSTATIC int xarray_ReplaceObject (XArray *xarray, unsigned int index,
231         void *new_object)
232 {
233     XARRAY_ASSERT_NOT_NULL (xarray);
234     XARRAY_BOUNDS_CHECK (xarray, index);
235
236     xarray->array[index] = new_object;
237
238     return XARRAY_SUCCESS;
239 }
240
241 XSTATIC int xarray_Count (XArray *xarray, unsigned int *out_count)
242 {
243     XARRAY_ASSERT_NOT_NULL (xarray);
244
245     *out_count = xarray->last_valid_element + 1;
246
247     return XARRAY_SUCCESS;
248 }
249
250
251 #undef XARRAY_ASSERT_NOT_NULL
252 #undef XARRAY_BOUNDS_CHECK
253 #undef XARRAY_GROW_ARRAY
254