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
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include <stdio.h>
00048 #if ! defined(BUILD_OS_DARWIN)
00049 #include <malloc.h>
00050 #endif
00051 #include <string.h>
00052 #include <stdlib.h>
00053 #include "array_alloc.h"
00054
00055 #define AA_NOSTART 1
00056 #define AA_INITIAL 2
00057 #define AA_EL_SIZE 3
00058 #define AA_NUMERATOR 4
00059 #define AA_DENOMINATOR 5
00060 #define AA_DISCARD 6
00061 #define AA_ALLOC1 7
00062 #define AA_ALLOC2 8
00063 #define AA_ALLOC3 9
00064 #define AA_ELT_ALLOC 10
00065 #define AA_ELT_ALLOC2 11
00066 #define AA_ELT_ALLOC3 12
00067 #define AA_ALLOC_NULL 13
00068
00069 static char *aa_error[] = {
00070 "array_alloc no error.",
00071 "array_alloc Cannot malloc a struct fore aa_handle to point to",
00072 "array_alloc Initial allocation amount is not usable (<= 1)",
00073 "array_alloc Initial element size is not usable ( < 1 )",
00074 "array_alloc Initial numerator is not usable ( < 2)",
00075 "array_alloc Initial denominator is not usable (< 1 )",
00076 "array_alloc consistency checks fail in freeing memory",
00077 "array_alloc initial word of aa structure destroyed",
00078 "array_alloc middle word of aa structure destroyed",
00079 "array_alloc final word of aa structure destroyed",
00080 "array_alloc elements-to-alloc given <= 0",
00081 "array_alloc malloc failure",
00082 "array_alloc realloc failure",
00083 "array_alloc: null pointer passed to aa_alloc",
00084 };
00085
00086 static void error(aa_handle,int);
00087 #define ERROR(l,i) error(l,i)
00088
00089
00090 struct aa_data_st {
00091 struct aa_data_st * aa_handle_consistency1;
00092 char ** aa_base;
00093 long * aa_next_to_use;
00094 long * aa_max;
00095 long aa_initial_alloc;
00096 long aa_element_size;
00097 struct aa_data_st * aa_handle_consistency2;
00098 long aa_realloc_numerator;
00099 long aa_realloc_denominator;
00100 void (*aa_error_func) ( int, char *, int , char *);
00101 int aa_user_num;
00102 char * aa_user_string;
00103 struct aa_data_st * aa_handle_consistency3;
00104 };
00105
00106
00107
00108
00109
00110
00111 aa_handle aa_initialize( char **base,
00112 long * next_to_use,
00113 long *max_allocated,
00114 int initial_allocation,
00115 int element_size,
00116 int change_numerator,
00117 int change_denominator,
00118 void (*err_func)( int, char *, int, char *),
00119 int user_num,
00120 char *user_string)
00121 {
00122
00123 aa_handle l;
00124
00125 l = (aa_handle) malloc( sizeof(struct aa_data_st));
00126 if(l == 0)
00127 ERROR(l,AA_NOSTART);
00128 l->aa_handle_consistency1 =
00129 l->aa_handle_consistency2 =
00130 l->aa_handle_consistency3 = l;
00131 l->aa_base = base;
00132 *next_to_use = 0;
00133 l->aa_next_to_use = next_to_use;
00134 *max_allocated = 0;
00135 l->aa_max = max_allocated;
00136 l->aa_initial_alloc = initial_allocation;
00137 if(element_size < 1)
00138 ERROR(l,AA_EL_SIZE);
00139 l->aa_element_size = element_size;
00140 if(element_size < 1)
00141 ERROR(l,AA_INITIAL);
00142 l->aa_realloc_numerator = change_numerator;
00143 l->aa_realloc_denominator = change_denominator;
00144 #ifdef DEBUG
00145 fprintf(stderr,"dadebug init al %d elt size %d num %d den %d\n",initial_allocation,element_size,change_numerator, change_denominator);
00146 #endif
00147 if(change_numerator < 2 )
00148 ERROR(l,AA_NUMERATOR);
00149 if(change_denominator < 1 || change_denominator >= change_numerator)
00150 ERROR(l,AA_DENOMINATOR);
00151 l->aa_error_func = err_func;
00152 l->aa_user_num = user_num;
00153 l->aa_user_string = user_string;
00154
00155 #ifdef DEBUG
00156 fprintf(stderr,"dadebug new handle %#x user %s\n",l,user_string);
00157 #endif
00158 return(l);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 void *
00170 aa_alloc(aa_handle lclaa, long elements_to_alloc)
00171 {
00172 long count;
00173 long max;
00174 char *newbase;
00175 char *oldbase;
00176 long len;
00177 long newmax;
00178 long elsize;
00179
00180 #ifdef DEBUG
00181 fprintf(stderr,"dadebug handle %#x count %d next to use %d\n",lclaa,elements_to_alloc,*(lclaa->aa_next_to_use));
00182 #endif
00183 if(!lclaa)
00184 ERROR(lclaa,AA_ALLOC_NULL);
00185 if(elements_to_alloc <= 0)
00186 ERROR(lclaa,AA_ELT_ALLOC);
00187 #ifdef AA_CONSISTENCY_CHECKS
00188 if(lclaa != lclaa->aa_handle_consistency1)
00189 ERROR(lclaa,AA_ALLOC1);
00190 if(lclaa != lclaa->aa_handle_consistency2)
00191 ERROR(lclaa,AA_ALLOC2);
00192 if(lclaa != lclaa->aa_handle_consistency3)
00193 ERROR(lclaa,AA_ALLOC3);
00194 #endif
00195 count = *lclaa->aa_next_to_use;
00196 max = *lclaa->aa_max;
00197 elsize = lclaa->aa_element_size;
00198
00199 if(( count + elements_to_alloc) < max) {
00200 #ifdef DEBUG
00201 fprintf(stderr," dadebug use next elt: %d elsize %d new next is %d\n",count,elsize,count + elements_to_alloc);
00202 #endif
00203 *lclaa->aa_next_to_use = count + elements_to_alloc;
00204 return((void *)( ((char *) *lclaa->aa_base)
00205 + count * elsize));
00206 }
00207
00208
00209
00210 #ifdef DEBUG
00211 fprintf(stderr," dadebug increase\n");
00212 #endif
00213 oldbase = *lclaa->aa_base;
00214 if(oldbase == (char *)0) {
00215
00216 if(elements_to_alloc > lclaa->aa_initial_alloc)
00217 max = elements_to_alloc + lclaa->aa_initial_alloc;
00218 else
00219 max = lclaa->aa_initial_alloc;
00220
00221 len = max *elsize;
00222
00223 newbase = (char *)malloc(len);
00224 if(newbase == 0)
00225 ERROR(lclaa,AA_ELT_ALLOC2);
00226 *(lclaa->aa_base) = newbase;
00227 *(lclaa->aa_next_to_use) = elements_to_alloc;
00228 *(lclaa->aa_max) = max;
00229 #ifdef DEBUG
00230 fprintf(stderr,"dadebug new basee calced. \n");
00231 #endif
00232 return(newbase);
00233 }
00234
00235
00236
00237 newmax = max * lclaa->aa_realloc_numerator;
00238 newmax = newmax / lclaa->aa_realloc_denominator;
00239 if((count + elements_to_alloc) >= newmax)
00240 newmax += elements_to_alloc;
00241 len = newmax *elsize;
00242 newbase = (char *)realloc(oldbase,len);
00243 if(newbase == 0)
00244 ERROR(lclaa,AA_ELT_ALLOC3);
00245 *(lclaa->aa_base) = newbase;
00246 *(lclaa->aa_next_to_use) = count + elements_to_alloc;
00247 *(lclaa->aa_max) = newmax;
00248 #ifdef DEBUG
00249 fprintf(stderr,"dadebug realloc base returned basee calced. \n");
00250 #endif
00251 return( newbase + count*elsize);
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 void
00264 aa_discard(aa_handle lclaa)
00265 {
00266 if(lclaa && lclaa ==lclaa->aa_handle_consistency1 &&
00267 lclaa ==lclaa->aa_handle_consistency2 &&
00268 lclaa ==lclaa->aa_handle_consistency3 ) {
00269 if(*(lclaa->aa_base))
00270 free(*(lclaa->aa_base));
00271 *(lclaa->aa_base) = 0;
00272 if(lclaa->aa_next_to_use)
00273 *(lclaa->aa_next_to_use) = 0;
00274 if(lclaa->aa_max)
00275 *(lclaa->aa_max) = 0;
00276 (void)memset(lclaa,0,sizeof(*lclaa));
00277 return;
00278 }
00279 ERROR(lclaa,AA_DISCARD);
00280 }
00281 static void error (aa_handle lclaa, int i)
00282 {
00283 if(lclaa == 0) {
00284 (void)fprintf(stderr,"%s. aa_handle %p. error %d\n",
00285 aa_error[i],lclaa,i);
00286 abort();
00287 }
00288 if(lclaa->aa_error_func) {
00289 (*(lclaa->aa_error_func))(lclaa->aa_user_num,
00290 lclaa->aa_user_string,i,aa_error[i]);
00291 } else {
00292 (void)fprintf(stderr,"%s. aa_handle %p. error %d. Handle_info: %d %s\n",
00293 aa_error[i],
00294 lclaa,
00295 i,
00296 lclaa->aa_user_num,
00297 (lclaa->aa_user_string)? lclaa->aa_user_string: "");
00298 }
00299 abort();
00300 }