1 /* 2 3 ratproxy - naive dynamic list implementation 4 -------------------------------------------- 5 6 Multiple macros for handling several types of dynamic lists and 7 strings. 8 9 Author: Michal Zalewski <lcamtuf@google.com> 10 11 Copyright 2007, 2008 by Google Inc. All Rights Reserved. 12 13 Licensed under the Apache License, Version 2.0 (the "License"); 14 you may not use this file except in compliance with the License. 15 You may obtain a copy of the License at 16 17 http://www.apache.org/licenses/LICENSE-2.0 18 19 Unless required by applicable law or agreed to in writing, software 20 distributed under the License is distributed on an "AS IS" BASIS, 21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 22 See the License for the specific language governing permissions and 23 limitations under the License. 24 25 */ 26 27 #ifndef _HAVE_NLIST_H 28 #define _HAVE_NLIST_H 29 30 #include "types.h" 31 32 #define ALLOC_CHUNK 32 33 34 struct naive_list { _u8** v; _u32 c; }; 35 36 #define ADD(list,val) do { \ 37 struct naive_list* __list = &(list); \ 38 if (!(__list->c % ALLOC_CHUNK)) { \ 39 __list->v = realloc(__list->v,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u8*)); \ 40 if (!__list->v) fatal("out of memory"); \ 41 } \ 42 __list->v[__list->c++] = (val); \ 43 __list->v[__list->c] = 0; \ 44 } while (0) 45 46 #define DYN_ADD(list,val) do { \ 47 _u8* _s = strdup(val); \ 48 if (!_s) fatal("out of memory"); \ 49 ADD((list),_s); \ 50 } while (0) 51 52 #define FREE(list) do { \ 53 struct naive_list* __list = &(list); \ 54 if (__list->v) free(__list->v); \ 55 __list->v = 0; \ 56 __list->c = 0; \ 57 } while (0); 58 59 #define DYN_FREE(list) do { \ 60 _u32 _i; \ 61 struct naive_list* __list = &(list); \ 62 for (_i=0;_i<__list->c;_i++) \ 63 if (__list->v[_i]) free(__list->v[_i]); \ 64 if (__list->v) free(__list->v); \ 65 __list->v = 0; \ 66 __list->c = 0; \ 67 } while (0); 68 69 struct naive_list2 { _u8 **v1, **v2; _u32 c; }; 70 71 #define ADD2(list, val1, val2) do { \ 72 struct naive_list2* __list = &(list); \ 73 if (!(__list->c % ALLOC_CHUNK)) { \ 74 __list->v1 = realloc(__list->v1,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u8*)); \ 75 __list->v2 = realloc(__list->v2,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u8*)); \ 76 if (!__list->v1 || !__list->v2) fatal("out of memory"); \ 77 } \ 78 __list->v1[__list->c] = (val1); \ 79 __list->v2[__list->c++] = (val2); \ 80 } while (0) 81 82 #define DYN_ADD2(list,val1,val2) do { \ 83 _u8 *_s1 = strdup(val1), *_s2 = strdup(val2); \ 84 if (!_s1 || !_s2) fatal("out of memory"); \ 85 ADD2((list),_s1,_s2); \ 86 } while (0) 87 88 #define FREE2(list) do { \ 89 struct naive_list2* __list = &(list); \ 90 if (__list->v1) free(__list->v1); \ 91 if (__list->v2) free(__list->v2); \ 92 __list->v1 = 0; \ 93 __list->v2 = 0; \ 94 __list->c = 0; \ 95 } while (0); 96 97 #define DYN_FREE2(list) do { \ 98 _u32 _i; \ 99 struct naive_list2* __list = &(list); \ 100 for (_i=0;_i<__list->c;_i++) { \ 101 if (__list->v1[_i]) free(__list->v1[_i]); \ 102 if (__list->v2[_i]) free(__list->v2[_i]); \ 103 } \ 104 if (__list->v1) free(__list->v1); \ 105 if (__list->v2) free(__list->v2); \ 106 __list->v1 = 0; \ 107 __list->v2 = 0; \ 108 __list->c = 0; \ 109 } while (0); 110 111 112 /* A specialized structure for parameter handling. */ 113 struct naive_list_p { 114 _u8 **v1; /* Field name */ 115 _u8 **v2; /* Field value */ 116 _u8 **fn; /* Filename ("" if none) */ 117 _u32 *l2; /* Field value length (0 - ASCIZ ) */ 118 _u32 c; /* Field count */ 119 }; 120 121 #define ADDP(list, val1, val2, fnval) do { \ 122 struct naive_list_p* __list = &(list); \ 123 if (!(__list->c % ALLOC_CHUNK)) { \ 124 __list->v1 = realloc(__list->v1,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u8*)); \ 125 __list->v2 = realloc(__list->v2,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u8*)); \ 126 __list->fn = realloc(__list->fn,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u8*)); \ 127 __list->l2 = realloc(__list->l2,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u32)); \ 128 if (!__list->v1 || !__list->v2 || !__list->fn || !__list->l2) fatal("out of memory"); \ 129 } \ 130 __list->v1[__list->c] = (val1); \ 131 __list->v2[__list->c] = (val2); \ 132 __list->fn[__list->c] = (fnval); \ 133 __list->l2[__list->c++] = 0; \ 134 } while (0) 135 136 #define ADDP_RAWMEM(list, val1, val2, v2len, fnval) do { \ 137 struct naive_list_p* __list = &(list); \ 138 if (!(__list->c % ALLOC_CHUNK)) { \ 139 __list->v1 = realloc(__list->v1,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u8*)); \ 140 __list->v2 = realloc(__list->v2,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u8*)); \ 141 __list->fn = realloc(__list->fn,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u8*)); \ 142 __list->l2 = realloc(__list->l2,(2 + ALLOC_CHUNK + __list->c) * sizeof(_u32)); \ 143 if (!__list->v1 || !__list->v2 || !__list->fn || !__list->l2) fatal("out of memory"); \ 144 } \ 145 __list->v1[__list->c] = (val1); \ 146 __list->v2[__list->c] = (val2); \ 147 __list->fn[__list->c] = (fnval); \ 148 __list->l2[__list->c++] = (v2len); \ 149 } while (0) 150 151 #define DYN_ADDP(list,val1,val2,fn) do { \ 152 _u8 *_s1 = strdup(val1), *_s2 = strdup(val2), *_fn = strdup(fn); \ 153 if (!_s1 || !_s2 || !_fn) fatal("out of memory"); \ 154 ADDP((list),_s1,_s2,_fn); \ 155 } while (0) 156 157 #define DYN_ADDP_RAWMEM(list,val1,val2,v2len,fn) do { \ 158 _u32 _l2 = (v2len); \ 159 _u8 *_s1 = strdup(val1), *_s2 = malloc(_l2), *_fn = strdup(fn); \ 160 if (!_s1 || !_s2 || !_fn) fatal("out of memory"); \ 161 memcpy(_s2,(val2),_l2); \ 162 _s2[_l2] = 0; \ 163 ADDP_RAWMEM((list),_s1,_s2,_l2,_fn); \ 164 } while (0) 165 166 struct dyn_str { _u8* v; _u32 l; }; 167 168 #define STR_FREE(buf) do { \ 169 struct dyn_str* _str = &(buf); \ 170 if (_str->v) free(_str->v); \ 171 _str->v = 0; \ 172 _str->l = 0; \ 173 } while (0) 174 175 #define STR_APPEND(buf,value) do { \ 176 _u8* _data = (value); \ 177 _u32 _len = strlen(_data); \ 178 struct dyn_str* _str = &(buf); \ 179 _str->v = realloc(_str->v,_str->l + _len + 1); \ 180 if (!_str->v) fatal("out of memory"); \ 181 memcpy(_str->v + _str->l, _data, _len); \ 182 _str->l += _len; \ 183 _str->v[_str->l] = 0; \ 184 } while (0) 185 186 #define STR_APPEND_RAWMEM(buf,value,vlen) do { \ 187 _u8* _data = (value); \ 188 _u32 _len = (vlen); \ 189 struct dyn_str* _str = &(buf); \ 190 _str->v = realloc(_str->v,_str->l + _len + 1); \ 191 if (!_str->v) fatal("out of memory"); \ 192 memcpy(_str->v + _str->l, _data, _len); \ 193 _str->l += _len; \ 194 _str->v[_str->l] = 0; \ 195 } while (0) 196 197 #define STR_APPEND_CHAR(buf,value) do { \ 198 _u8 _data = (value); \ 199 struct dyn_str* _str = &(buf); \ 200 _str->v = realloc(_str->v,_str->l + 2); \ 201 if (!_str->v) fatal("out of memory"); \ 202 _str->v[_str->l++] = _data; \ 203 _str->v[_str->l] = 0; \ 204 } while (0) 205 206 #endif /* ! _HAVE_NLIST_H */ 207