ESAPI-C 1.0
The OWASP Enterprise Security API for C

utarray.h

Go to the documentation of this file.
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 */
 All Data Structures Files Functions Variables Typedefs Defines