00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <string.h>
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
00081
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
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
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