Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

xarray.c

00001 /*************************************************************************
00002  * xarray.c: Mutable (dynamically growable) array
00003  *************************************************************************
00004  * Copyright (C) 2004 Commonwealth Scientific and Industrial Research
00005  *                    Organisation (CSIRO) Australia
00006  * Copyright (C) 2004 the VideoLAN team
00007  *
00008  * $Id: xarray.c 11664 2005-07-09 06:17:09Z courmisch $
00009  *
00010  * Authors: Andre Pang <[email protected]>
00011  *
00012  * This program is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU General Public License as published by
00014  * the Free Software Foundation; either version 2 of the License, or
00015  * (at your option) any later version.
00016  * 
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * You should have received a copy of the GNU General Public License
00023  * along with this program; if not, write to the Free Software
00024  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
00025  ************************************************************************/
00026 
00027 #include <stdlib.h>
00028 #include <string.h> /* memmove(1) */
00029 
00030 #include "xarray.h"
00031 
00032 #define XARRAY_ASSERT_NOT_NULL(xarray) \
00033     { \
00034         if (xarray == NULL) return XARRAY_ENULLPOINTER; \
00035     }
00036 
00037 #define XARRAY_BOUNDS_CHECK(xarray, index) \
00038     { \
00039         if (index < 0) \
00040             return XARRAY_ENEGATIVEINDEX; \
00041         else if (xarray->last_valid_element != -1 && \
00042                  (int) index > xarray->last_valid_element) \
00043             return XARRAY_EINDEXTOOLARGE; \
00044     }
00045 
00046 #define XARRAY_GROW_ARRAY(xarray) \
00047     { \
00048         xarray->array = (void *) realloc (xarray->array, xarray->size * 2); \
00049         if (xarray->array == NULL) return XARRAY_ENOMEM; \
00050     }
00051 
00052 XSTATIC XArray * xarray_New (unsigned int initial_size_hint)
00053 {
00054     XArray *new_xarray = NULL;
00055     void *inner_array;
00056     unsigned int initial_size;
00057 
00058     new_xarray = (XArray *) malloc (sizeof(XArray));
00059     if (new_xarray == NULL) return NULL;
00060 
00061     if (initial_size_hint <= 0)
00062         initial_size = XARRAY_DEFAULT_SIZE;
00063     else
00064         initial_size = initial_size_hint;
00065 
00066     inner_array = calloc (initial_size, sizeof(void *));
00067 
00068     new_xarray->last_valid_element = -1;
00069     new_xarray->size = initial_size;
00070     new_xarray->last_error = 0;
00071 
00072     if (inner_array == NULL)
00073     {
00074         free (new_xarray);
00075         return NULL;
00076     }
00077 
00078     new_xarray->array = inner_array;
00079 
00080     /* Make a dummy reference to other functions, so that we don't get
00081      * warnings about unused functions from the compiler.  Ahem :) */
00082     while (0)
00083     {
00084         void *dummy_reference;
00085 
00086         dummy_reference = xarray_AddObject;
00087         dummy_reference = xarray_InsertObject;
00088         dummy_reference = xarray_RemoveLastObject;
00089         dummy_reference = xarray_RemoveObject;
00090         dummy_reference = xarray_RemoveObjects;
00091         dummy_reference = xarray_RemoveObjectsAfter;
00092         dummy_reference = xarray_ReplaceObject;
00093 
00094         dummy_reference = xarray_ObjectAtIndex;
00095         dummy_reference = xarray_Count;
00096     }
00097     
00098     return new_xarray;
00099 }
00100 
00101 XSTATIC int xarray_ObjectAtIndex (XArray *xarray, unsigned int index,
00102         void **out_object)
00103 {
00104     XARRAY_ASSERT_NOT_NULL (xarray);
00105     XARRAY_BOUNDS_CHECK (xarray, index);
00106 
00107     *out_object = xarray->array[index];
00108 
00109     return XARRAY_SUCCESS;
00110 }
00111 
00112 XSTATIC int xarray_AddObject (XArray *xarray, void *object)
00113 {
00114     XARRAY_ASSERT_NOT_NULL (xarray);
00115 
00116     ++xarray->last_valid_element;
00117     if (xarray->last_valid_element >= (int) xarray->size)
00118     {
00119         XARRAY_GROW_ARRAY (xarray);
00120     }
00121 
00122     xarray->array[xarray->last_valid_element] = object;
00123 
00124     return XARRAY_SUCCESS;
00125 }
00126 
00127 XSTATIC int xarray_InsertObject (XArray *xarray, void *object,
00128         unsigned int at_index)
00129 {
00130     XARRAY_ASSERT_NOT_NULL (xarray);
00131     ++xarray->last_valid_element;
00132     XARRAY_BOUNDS_CHECK (xarray, at_index);
00133     if (xarray->last_valid_element >= (int) xarray->size)
00134     {
00135         XARRAY_GROW_ARRAY (xarray);
00136     }
00137 
00138     /* Shift everything from a[i] onward one pointer forward */
00139 
00140     if ((int) at_index < xarray->last_valid_element)
00141     {
00142         (void) memmove (&xarray->array[at_index + 1],
00143                         &xarray->array[at_index],
00144                         (xarray->last_valid_element - at_index) *
00145                             sizeof(void *));
00146     }
00147 
00148     xarray->array[at_index] = object;
00149 
00150     return XARRAY_SUCCESS;
00151 }
00152 
00153 XSTATIC int xarray_RemoveLastObject (XArray *xarray)
00154 {
00155     XARRAY_ASSERT_NOT_NULL (xarray);
00156 
00157     if (xarray->last_valid_element == -1)
00158         return XARRAY_EEMPTYARRAY;
00159 
00160     xarray->array[xarray->last_valid_element] = NULL;
00161     --xarray->last_valid_element;
00162 
00163     return XARRAY_SUCCESS;
00164 }
00165 
00166 XSTATIC int xarray_RemoveObject (XArray *xarray, unsigned int at_index)
00167 {
00168     XARRAY_ASSERT_NOT_NULL (xarray);
00169     XARRAY_BOUNDS_CHECK (xarray, at_index);
00170 
00171     /* Shift everything from a[i] onward one pointer backward */
00172 
00173     if ((int) at_index < xarray->last_valid_element)
00174     {
00175         (void) memmove (&xarray->array[at_index],
00176                         &xarray->array[at_index + 1],
00177                         (xarray->last_valid_element - at_index) *
00178                             sizeof(void *));
00179     }
00180 
00181     xarray->array[xarray->last_valid_element] = NULL;
00182     --xarray->last_valid_element;
00183 
00184     return XARRAY_SUCCESS;    
00185 }
00186 
00187 XSTATIC int xarray_RemoveObjects (XArray *xarray, unsigned int at_index,
00188         int count)
00189 {
00190     int i;
00191 
00192     XARRAY_ASSERT_NOT_NULL (xarray);
00193     XARRAY_BOUNDS_CHECK (xarray, at_index);
00194 
00195     if (count == 0) return XARRAY_SUCCESS;
00196 
00197     if ((int) at_index + (count - 1) > xarray->last_valid_element)
00198         return XARRAY_ECOUNTOUTOFBOUNDS;
00199 
00200     for (i = 0; i < count; i++)
00201     {
00202         int e = xarray_RemoveObject (xarray, at_index);
00203         if (e != XARRAY_SUCCESS) return e;
00204     }
00205 
00206     return XARRAY_SUCCESS;
00207 }
00208 
00209 XSTATIC int xarray_RemoveObjectsAfter (XArray *xarray, unsigned int index)
00210 {
00211     XARRAY_ASSERT_NOT_NULL (xarray);
00212     XARRAY_BOUNDS_CHECK (xarray, index);
00213 
00214     index++;
00215 
00216     while ((int) index <= xarray->last_valid_element)
00217     {
00218         int e = xarray_RemoveObject (xarray, index);
00219         if (e != XARRAY_SUCCESS) return e;
00220     }
00221 
00222     return XARRAY_SUCCESS;
00223 }
00224 
00225 XSTATIC int xarray_ReplaceObject (XArray *xarray, unsigned int index,
00226         void *new_object)
00227 {
00228     XARRAY_ASSERT_NOT_NULL (xarray);
00229     XARRAY_BOUNDS_CHECK (xarray, index);
00230 
00231     xarray->array[index] = new_object;
00232 
00233     return XARRAY_SUCCESS;
00234 }
00235 
00236 XSTATIC int xarray_Count (XArray *xarray, unsigned int *out_count)
00237 {
00238     XARRAY_ASSERT_NOT_NULL (xarray);
00239 
00240     *out_count = xarray->last_valid_element + 1;
00241 
00242     return XARRAY_SUCCESS;
00243 }
00244 
00245 
00246 #undef XARRAY_ASSERT_NOT_NULL
00247 #undef XARRAY_BOUNDS_CHECK
00248 #undef XARRAY_GROW_ARRAY
00249 

Generated on Tue Dec 20 10:14:28 2005 for vlc-0.8.4a by  doxygen 1.4.2