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