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