ESAPI-C 1.0
The OWASP Enterprise Security API for C
|
00001 00032 #ifndef UTARRAY_H 00033 #define UTARRAY_H 00034 00035 #define UTARRAY_VERSION 1.9.1 00036 00037 #ifdef __GNUC__ 00038 #define _UNUSED_ __attribute__ ((__unused__)) 00039 #else 00040 #define _UNUSED_ 00041 #endif 00042 00043 #include <stddef.h> /* size_t */ 00044 #include <string.h> /* memset, etc */ 00045 #include <stdlib.h> /* exit */ 00046 00047 #define oom() exit(-1) 00048 00049 typedef void (ctor_f)(void *dst, const void *src); 00050 typedef void (dtor_f)(void *elt); 00051 typedef void (init_f)(void *elt); 00052 typedef struct { 00053 size_t sz; 00054 init_f *init; 00055 ctor_f *copy; 00056 dtor_f *dtor; 00057 } UT_icd; 00058 00059 typedef struct { 00060 unsigned i,n;/* i: index of next available slot, n: num slots */ 00061 const UT_icd *icd; /* initializer, copy and destructor functions */ 00062 char *d; /* n slots of size icd->sz*/ 00063 } UT_array; 00064 00065 #define utarray_init(a,_icd) do { \ 00066 memset(a,0,sizeof(UT_array)); \ 00067 (a)->icd=_icd; \ 00068 } while(0) 00069 00070 #define utarray_done(a) do { \ 00071 if ((a)->n) { \ 00072 if ((a)->icd->dtor) { \ 00073 size_t _ut_i; \ 00074 for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ 00075 (a)->icd->dtor(utarray_eltptr(a,_ut_i)); \ 00076 } \ 00077 } \ 00078 free((a)->d); \ 00079 } \ 00080 (a)->n=0; \ 00081 } while(0) 00082 00083 #define utarray_new(a,_icd) do { \ 00084 a=(UT_array*)malloc(sizeof(UT_array)); \ 00085 utarray_init(a,_icd); \ 00086 } while(0) 00087 00088 #define utarray_free(a) do { \ 00089 utarray_done(a); \ 00090 free(a); \ 00091 } while(0) 00092 00093 #define utarray_reserve(a,by) do { \ 00094 if (((a)->i+by) > ((a)->n)) { \ 00095 while(((a)->i+by) > ((a)->n)) { (a)->n = ((a)->n ? (2*(a)->n) : 8); } \ 00096 if ( ((a)->d=(char*)realloc((a)->d, (a)->n*(a)->icd->sz)) == NULL) oom(); \ 00097 } \ 00098 } while(0) 00099 00100 #define utarray_push_back(a,p) do { \ 00101 utarray_reserve(a,1); \ 00102 if ((a)->icd->copy) { (a)->icd->copy( _utarray_eltptr(a,(a)->i++), p); } \ 00103 else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd->sz); }; \ 00104 } while(0) 00105 00106 #define utarray_pop_back(a) do { \ 00107 if ((a)->icd->dtor) { (a)->icd->dtor( _utarray_eltptr(a,--((a)->i))); } \ 00108 else { (a)->i--; } \ 00109 } while(0) 00110 00111 #define utarray_extend_back(a) do { \ 00112 utarray_reserve(a,1); \ 00113 if ((a)->icd->init) { (a)->icd->init(_utarray_eltptr(a,(a)->i)); } \ 00114 else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd->sz); } \ 00115 (a)->i++; \ 00116 } while(0) 00117 00118 #define utarray_len(a) ((a)->i) 00119 00120 #define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL) 00121 #define _utarray_eltptr(a,j) ((char*)((a)->d + ((a)->icd->sz*(j) ))) 00122 00123 #define utarray_insert(a,p,j) do { \ 00124 utarray_reserve(a,1); \ 00125 if (j > (a)->i) break; \ 00126 if ((j) < (a)->i) { \ 00127 memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j), \ 00128 ((a)->i - (j))*((a)->icd->sz)); \ 00129 } \ 00130 if ((a)->icd->copy) { (a)->icd->copy( _utarray_eltptr(a,j), p); } \ 00131 else { memcpy(_utarray_eltptr(a,j), p, (a)->icd->sz); }; \ 00132 (a)->i++; \ 00133 } while(0) 00134 00135 #define utarray_inserta(a,w,j) do { \ 00136 if (utarray_len(w) == 0) break; \ 00137 if (j > (a)->i) break; \ 00138 utarray_reserve(a,utarray_len(w)); \ 00139 if ((j) < (a)->i) { \ 00140 memmove(_utarray_eltptr(a,(j)+utarray_len(w)), \ 00141 _utarray_eltptr(a,j), \ 00142 ((a)->i - (j))*((a)->icd->sz)); \ 00143 } \ 00144 if (a->icd->copy) { \ 00145 size_t _ut_i; \ 00146 for(_ut_i=0;_ut_i<(w)->i;_ut_i++) { \ 00147 (a)->icd->copy(_utarray_eltptr(a,j+_ut_i), _utarray_eltptr(w,_ut_i)); \ 00148 } \ 00149 } else { \ 00150 memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0), \ 00151 utarray_len(w)*((a)->icd->sz)); \ 00152 } \ 00153 (a)->i += utarray_len(w); \ 00154 } while(0) 00155 00156 #define utarray_resize(dst,num) do { \ 00157 size_t _ut_i; \ 00158 if (dst->i > (size_t)(num)) { \ 00159 if ((dst)->icd->dtor) { \ 00160 for(_ut_i=num; _ut_i < dst->i; _ut_i++) { \ 00161 (dst)->icd->dtor(utarray_eltptr(dst,_ut_i)); \ 00162 } \ 00163 } \ 00164 } else if (dst->i < (size_t)(num)) { \ 00165 utarray_reserve(dst,num-dst->i); \ 00166 if ((dst)->icd->init) { \ 00167 for(_ut_i=dst->i; _ut_i < num; _ut_i++) { \ 00168 (dst)->icd->init(utarray_eltptr(dst,_ut_i)); \ 00169 } \ 00170 } else { \ 00171 memset(_utarray_eltptr(dst,dst->i),0,(dst)->icd->sz*(num-dst->i)); \ 00172 } \ 00173 } \ 00174 dst->i = num; \ 00175 } while(0) 00176 00177 #define utarray_concat(dst,src) do { \ 00178 utarray_inserta(dst,src,utarray_len(dst)); \ 00179 } while(0) 00180 00181 #define utarray_erase(a,pos,len) do { \ 00182 if ((a)->icd->dtor) { \ 00183 size_t _ut_i; \ 00184 for(_ut_i=0; _ut_i < len; _ut_i++) { \ 00185 (a)->icd->dtor(utarray_eltptr(a,pos+_ut_i)); \ 00186 } \ 00187 } \ 00188 if ((a)->i > (pos+len)) { \ 00189 memmove( _utarray_eltptr(a,pos), _utarray_eltptr(a,pos+len), \ 00190 ((a->i)-(pos+len))*((a)->icd->sz)); \ 00191 } \ 00192 (a)->i -= (len); \ 00193 } while(0) 00194 00195 #define utarray_clear(a) do { \ 00196 if ((a)->i > 0) { \ 00197 if ((a)->icd->dtor) { \ 00198 size_t _ut_i; \ 00199 for(_ut_i=0; _ut_i < (a)->i; _ut_i++) { \ 00200 (a)->icd->dtor(utarray_eltptr(a,_ut_i)); \ 00201 } \ 00202 } \ 00203 (a)->i = 0; \ 00204 } \ 00205 } while(0) 00206 00207 #define utarray_sort(a,cmp) do { \ 00208 qsort((a)->d, (a)->i, (a)->icd->sz, cmp); \ 00209 } while(0) 00210 00211 #define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL) 00212 #define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : ((((a)->i) > (utarray_eltidx(a,e)+1)) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL)) 00213 #define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL) 00214 #define utarray_eltidx(a,e) (((char*)(e) >= (char*)((a)->d)) ? (((char*)(e) - (char*)((a)->d))/(a)->icd->sz) : -1) 00215 00216 /* last we pre-define a few icd for common utarrays of ints and strings */ 00217 static void utarray_str_cpy(void *dst, const void *src) { 00218 char **_src = (char**)src, **_dst = (char**)dst; 00219 *_dst = (*_src == NULL) ? NULL : strdup(*_src); 00220 } 00221 static void utarray_str_dtor(void *elt) { 00222 char **eltc = (char**)elt; 00223 if (*eltc) free(*eltc); 00224 } 00225 static const UT_icd ut_str_icd _UNUSED_ = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor}; 00226 static const UT_icd ut_int_icd _UNUSED_ = {sizeof(int),NULL,NULL,NULL}; 00227 00228 00229 #endif /* UTARRAY_H */