OLD | NEW |
1 /* crypto/stack/stack.c */ | 1 /* crypto/stack/stack.c */ |
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
8 * | 8 * |
9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 #include <openssl/stack.h> | 70 #include <openssl/stack.h> |
71 #include <openssl/objects.h> | 71 #include <openssl/objects.h> |
72 | 72 |
73 #undef MIN_NODES | 73 #undef MIN_NODES |
74 #define MIN_NODES 4 | 74 #define MIN_NODES 4 |
75 | 75 |
76 const char STACK_version[]="Stack" OPENSSL_VERSION_PTEXT; | 76 const char STACK_version[]="Stack" OPENSSL_VERSION_PTEXT; |
77 | 77 |
78 #include <errno.h> | 78 #include <errno.h> |
79 | 79 |
80 int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,const char * cons
t *))) | 80 int (*sk_set_cmp_func(_STACK *sk, int (*c)(const void *, const void *))) |
81 » » (const char * const *, const char * const *) | 81 » » (const void *, const void *) |
82 { | 82 { |
83 » int (*old)(const char * const *,const char * const *)=sk->comp; | 83 » int (*old)(const void *,const void *)=sk->comp; |
84 | 84 |
85 if (sk->comp != c) | 85 if (sk->comp != c) |
86 sk->sorted=0; | 86 sk->sorted=0; |
87 sk->comp=c; | 87 sk->comp=c; |
88 | 88 |
89 return old; | 89 return old; |
90 } | 90 } |
91 | 91 |
92 STACK *sk_dup(STACK *sk) | 92 _STACK *sk_dup(_STACK *sk) |
93 { | 93 { |
94 » STACK *ret; | 94 » _STACK *ret; |
95 char **s; | 95 char **s; |
96 | 96 |
97 if ((ret=sk_new(sk->comp)) == NULL) goto err; | 97 if ((ret=sk_new(sk->comp)) == NULL) goto err; |
98 s=(char **)OPENSSL_realloc((char *)ret->data, | 98 s=(char **)OPENSSL_realloc((char *)ret->data, |
99 (unsigned int)sizeof(char *)*sk->num_alloc); | 99 (unsigned int)sizeof(char *)*sk->num_alloc); |
100 if (s == NULL) goto err; | 100 if (s == NULL) goto err; |
101 ret->data=s; | 101 ret->data=s; |
102 | 102 |
103 ret->num=sk->num; | 103 ret->num=sk->num; |
104 memcpy(ret->data,sk->data,sizeof(char *)*sk->num); | 104 memcpy(ret->data,sk->data,sizeof(char *)*sk->num); |
105 ret->sorted=sk->sorted; | 105 ret->sorted=sk->sorted; |
106 ret->num_alloc=sk->num_alloc; | 106 ret->num_alloc=sk->num_alloc; |
107 ret->comp=sk->comp; | 107 ret->comp=sk->comp; |
108 return(ret); | 108 return(ret); |
109 err: | 109 err: |
110 if(ret) | 110 if(ret) |
111 sk_free(ret); | 111 sk_free(ret); |
112 return(NULL); | 112 return(NULL); |
113 } | 113 } |
114 | 114 |
115 STACK *sk_new_null(void) | 115 _STACK *sk_new_null(void) |
116 { | 116 { |
117 » return sk_new((int (*)(const char * const *, const char * const *))0); | 117 » return sk_new((int (*)(const void *, const void *))0); |
118 } | 118 } |
119 | 119 |
120 STACK *sk_new(int (*c)(const char * const *, const char * const *)) | 120 _STACK *sk_new(int (*c)(const void *, const void *)) |
121 { | 121 { |
122 » STACK *ret; | 122 » _STACK *ret; |
123 int i; | 123 int i; |
124 | 124 |
125 » if ((ret=(STACK *)OPENSSL_malloc(sizeof(STACK))) == NULL) | 125 » if ((ret=OPENSSL_malloc(sizeof(_STACK))) == NULL) |
126 goto err; | 126 goto err; |
127 » if ((ret->data=(char **)OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NUL
L) | 127 » if ((ret->data=OPENSSL_malloc(sizeof(char *)*MIN_NODES)) == NULL) |
128 goto err; | 128 goto err; |
129 for (i=0; i<MIN_NODES; i++) | 129 for (i=0; i<MIN_NODES; i++) |
130 ret->data[i]=NULL; | 130 ret->data[i]=NULL; |
131 ret->comp=c; | 131 ret->comp=c; |
132 ret->num_alloc=MIN_NODES; | 132 ret->num_alloc=MIN_NODES; |
133 ret->num=0; | 133 ret->num=0; |
134 ret->sorted=0; | 134 ret->sorted=0; |
135 return(ret); | 135 return(ret); |
136 err: | 136 err: |
137 if(ret) | 137 if(ret) |
138 OPENSSL_free(ret); | 138 OPENSSL_free(ret); |
139 return(NULL); | 139 return(NULL); |
140 } | 140 } |
141 | 141 |
142 int sk_insert(STACK *st, char *data, int loc) | 142 int sk_insert(_STACK *st, void *data, int loc) |
143 { | 143 { |
144 char **s; | 144 char **s; |
145 | 145 |
146 if(st == NULL) return 0; | 146 if(st == NULL) return 0; |
147 if (st->num_alloc <= st->num+1) | 147 if (st->num_alloc <= st->num+1) |
148 { | 148 { |
149 » » s=(char **)OPENSSL_realloc((char *)st->data, | 149 » » s=OPENSSL_realloc((char *)st->data, |
150 (unsigned int)sizeof(char *)*st->num_alloc*2); | 150 (unsigned int)sizeof(char *)*st->num_alloc*2); |
151 if (s == NULL) | 151 if (s == NULL) |
152 return(0); | 152 return(0); |
153 st->data=s; | 153 st->data=s; |
154 st->num_alloc*=2; | 154 st->num_alloc*=2; |
155 } | 155 } |
156 if ((loc >= (int)st->num) || (loc < 0)) | 156 if ((loc >= (int)st->num) || (loc < 0)) |
157 st->data[st->num]=data; | 157 st->data[st->num]=data; |
158 else | 158 else |
159 { | 159 { |
160 int i; | 160 int i; |
161 char **f,**t; | 161 char **f,**t; |
162 | 162 |
163 » » f=(char **)st->data; | 163 » » f=st->data; |
164 » » t=(char **)&(st->data[1]); | 164 » » t=&(st->data[1]); |
165 for (i=st->num; i>=loc; i--) | 165 for (i=st->num; i>=loc; i--) |
166 t[i]=f[i]; | 166 t[i]=f[i]; |
167 | 167 |
168 #ifdef undef /* no memmove on sunos :-( */ | 168 #ifdef undef /* no memmove on sunos :-( */ |
169 » » memmove( (char *)&(st->data[loc+1]), | 169 » » memmove(&(st->data[loc+1]), |
170 » » » (char *)&(st->data[loc]), | 170 » » » &(st->data[loc]), |
171 sizeof(char *)*(st->num-loc)); | 171 sizeof(char *)*(st->num-loc)); |
172 #endif | 172 #endif |
173 st->data[loc]=data; | 173 st->data[loc]=data; |
174 } | 174 } |
175 st->num++; | 175 st->num++; |
176 st->sorted=0; | 176 st->sorted=0; |
177 return(st->num); | 177 return(st->num); |
178 } | 178 } |
179 | 179 |
180 char *sk_delete_ptr(STACK *st, char *p) | 180 void *sk_delete_ptr(_STACK *st, void *p) |
181 { | 181 { |
182 int i; | 182 int i; |
183 | 183 |
184 for (i=0; i<st->num; i++) | 184 for (i=0; i<st->num; i++) |
185 if (st->data[i] == p) | 185 if (st->data[i] == p) |
186 return(sk_delete(st,i)); | 186 return(sk_delete(st,i)); |
187 return(NULL); | 187 return(NULL); |
188 } | 188 } |
189 | 189 |
190 char *sk_delete(STACK *st, int loc) | 190 void *sk_delete(_STACK *st, int loc) |
191 { | 191 { |
192 char *ret; | 192 char *ret; |
193 int i,j; | 193 int i,j; |
194 | 194 |
195 if(!st || (loc < 0) || (loc >= st->num)) return NULL; | 195 if(!st || (loc < 0) || (loc >= st->num)) return NULL; |
196 | 196 |
197 ret=st->data[loc]; | 197 ret=st->data[loc]; |
198 if (loc != st->num-1) | 198 if (loc != st->num-1) |
199 { | 199 { |
200 j=st->num-1; | 200 j=st->num-1; |
201 for (i=loc; i<j; i++) | 201 for (i=loc; i<j; i++) |
202 st->data[i]=st->data[i+1]; | 202 st->data[i]=st->data[i+1]; |
203 /* In theory memcpy is not safe for this | 203 /* In theory memcpy is not safe for this |
204 * memcpy( &(st->data[loc]), | 204 * memcpy( &(st->data[loc]), |
205 * &(st->data[loc+1]), | 205 * &(st->data[loc+1]), |
206 * sizeof(char *)*(st->num-loc-1)); | 206 * sizeof(char *)*(st->num-loc-1)); |
207 */ | 207 */ |
208 } | 208 } |
209 st->num--; | 209 st->num--; |
210 return(ret); | 210 return(ret); |
211 } | 211 } |
212 | 212 |
213 static int internal_find(STACK *st, char *data, int ret_val_options) | 213 static int internal_find(_STACK *st, void *data, int ret_val_options) |
214 { | 214 { |
215 » char **r; | 215 » const void * const *r; |
216 int i; | 216 int i; |
217 » int (*comp_func)(const void *,const void *); | 217 |
218 if(st == NULL) return -1; | 218 if(st == NULL) return -1; |
219 | 219 |
220 if (st->comp == NULL) | 220 if (st->comp == NULL) |
221 { | 221 { |
222 for (i=0; i<st->num; i++) | 222 for (i=0; i<st->num; i++) |
223 if (st->data[i] == data) | 223 if (st->data[i] == data) |
224 return(i); | 224 return(i); |
225 return(-1); | 225 return(-1); |
226 } | 226 } |
227 sk_sort(st); | 227 sk_sort(st); |
228 if (data == NULL) return(-1); | 228 if (data == NULL) return(-1); |
229 » /* This (and the "qsort" below) are the two places in OpenSSL | 229 » r=OBJ_bsearch_ex_(&data,st->data,st->num,sizeof(void *),st->comp, |
230 » * where we need to convert from our standard (type **,type **) | 230 » » » ret_val_options); |
231 » * compare callback type to the (void *,void *) type required by | |
232 » * bsearch. However, the "data" it is being called(back) with are | |
233 » * not (type *) pointers, but the *pointers* to (type *) pointers, | |
234 » * so we get our extra level of pointer dereferencing that way. */ | |
235 » comp_func=(int (*)(const void *,const void *))(st->comp); | |
236 » r=(char **)OBJ_bsearch_ex((char *)&data,(char *)st->data, | |
237 » » st->num,sizeof(char *),comp_func,ret_val_options); | |
238 if (r == NULL) return(-1); | 231 if (r == NULL) return(-1); |
239 » return((int)(r-st->data)); | 232 » return (int)((char **)r-st->data); |
240 } | 233 } |
241 | 234 |
242 int sk_find(STACK *st, char *data) | 235 int sk_find(_STACK *st, void *data) |
243 { | 236 { |
244 return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); | 237 return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); |
245 } | 238 } |
246 int sk_find_ex(STACK *st, char *data) | 239 int sk_find_ex(_STACK *st, void *data) |
247 { | 240 { |
248 return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); | 241 return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); |
249 } | 242 } |
250 | 243 |
251 int sk_push(STACK *st, char *data) | 244 int sk_push(_STACK *st, void *data) |
252 { | 245 { |
253 return(sk_insert(st,data,st->num)); | 246 return(sk_insert(st,data,st->num)); |
254 } | 247 } |
255 | 248 |
256 int sk_unshift(STACK *st, char *data) | 249 int sk_unshift(_STACK *st, void *data) |
257 { | 250 { |
258 return(sk_insert(st,data,0)); | 251 return(sk_insert(st,data,0)); |
259 } | 252 } |
260 | 253 |
261 char *sk_shift(STACK *st) | 254 void *sk_shift(_STACK *st) |
262 { | 255 { |
263 if (st == NULL) return(NULL); | 256 if (st == NULL) return(NULL); |
264 if (st->num <= 0) return(NULL); | 257 if (st->num <= 0) return(NULL); |
265 return(sk_delete(st,0)); | 258 return(sk_delete(st,0)); |
266 } | 259 } |
267 | 260 |
268 char *sk_pop(STACK *st) | 261 void *sk_pop(_STACK *st) |
269 { | 262 { |
270 if (st == NULL) return(NULL); | 263 if (st == NULL) return(NULL); |
271 if (st->num <= 0) return(NULL); | 264 if (st->num <= 0) return(NULL); |
272 return(sk_delete(st,st->num-1)); | 265 return(sk_delete(st,st->num-1)); |
273 } | 266 } |
274 | 267 |
275 void sk_zero(STACK *st) | 268 void sk_zero(_STACK *st) |
276 { | 269 { |
277 if (st == NULL) return; | 270 if (st == NULL) return; |
278 if (st->num <= 0) return; | 271 if (st->num <= 0) return; |
279 memset((char *)st->data,0,sizeof(st->data)*st->num); | 272 memset((char *)st->data,0,sizeof(st->data)*st->num); |
280 st->num=0; | 273 st->num=0; |
281 } | 274 } |
282 | 275 |
283 void sk_pop_free(STACK *st, void (*func)(void *)) | 276 void sk_pop_free(_STACK *st, void (*func)(void *)) |
284 { | 277 { |
285 int i; | 278 int i; |
286 | 279 |
287 if (st == NULL) return; | 280 if (st == NULL) return; |
288 for (i=0; i<st->num; i++) | 281 for (i=0; i<st->num; i++) |
289 if (st->data[i] != NULL) | 282 if (st->data[i] != NULL) |
290 func(st->data[i]); | 283 func(st->data[i]); |
291 sk_free(st); | 284 sk_free(st); |
292 } | 285 } |
293 | 286 |
294 void sk_free(STACK *st) | 287 void sk_free(_STACK *st) |
295 { | 288 { |
296 if (st == NULL) return; | 289 if (st == NULL) return; |
297 if (st->data != NULL) OPENSSL_free(st->data); | 290 if (st->data != NULL) OPENSSL_free(st->data); |
298 OPENSSL_free(st); | 291 OPENSSL_free(st); |
299 } | 292 } |
300 | 293 |
301 int sk_num(const STACK *st) | 294 int sk_num(const _STACK *st) |
302 { | 295 { |
303 if(st == NULL) return -1; | 296 if(st == NULL) return -1; |
304 return st->num; | 297 return st->num; |
305 } | 298 } |
306 | 299 |
307 char *sk_value(const STACK *st, int i) | 300 void *sk_value(const _STACK *st, int i) |
308 { | 301 { |
309 if(!st || (i < 0) || (i >= st->num)) return NULL; | 302 if(!st || (i < 0) || (i >= st->num)) return NULL; |
310 return st->data[i]; | 303 return st->data[i]; |
311 } | 304 } |
312 | 305 |
313 char *sk_set(STACK *st, int i, char *value) | 306 void *sk_set(_STACK *st, int i, void *value) |
314 { | 307 { |
315 if(!st || (i < 0) || (i >= st->num)) return NULL; | 308 if(!st || (i < 0) || (i >= st->num)) return NULL; |
316 return (st->data[i] = value); | 309 return (st->data[i] = value); |
317 } | 310 } |
318 | 311 |
319 void sk_sort(STACK *st) | 312 void sk_sort(_STACK *st) |
320 { | 313 { |
321 if (st && !st->sorted) | 314 if (st && !st->sorted) |
322 { | 315 { |
323 int (*comp_func)(const void *,const void *); | 316 int (*comp_func)(const void *,const void *); |
324 | 317 |
325 /* same comment as in sk_find ... previously st->comp was declar
ed | 318 /* same comment as in sk_find ... previously st->comp was declar
ed |
326 * as a (void*,void*) callback type, but this made the populatio
n | 319 * as a (void*,void*) callback type, but this made the populatio
n |
327 * of the callback pointer illogical - our callbacks compare | 320 * of the callback pointer illogical - our callbacks compare |
328 * type** with type**, so we leave the casting until absolutely | 321 * type** with type**, so we leave the casting until absolutely |
329 * necessary (ie. "now"). */ | 322 * necessary (ie. "now"). */ |
330 comp_func=(int (*)(const void *,const void *))(st->comp); | 323 comp_func=(int (*)(const void *,const void *))(st->comp); |
331 qsort(st->data,st->num,sizeof(char *), comp_func); | 324 qsort(st->data,st->num,sizeof(char *), comp_func); |
332 st->sorted=1; | 325 st->sorted=1; |
333 } | 326 } |
334 } | 327 } |
335 | 328 |
336 int sk_is_sorted(const STACK *st) | 329 int sk_is_sorted(const _STACK *st) |
337 { | 330 { |
338 if (!st) | 331 if (!st) |
339 return 1; | 332 return 1; |
340 return st->sorted; | 333 return st->sorted; |
341 } | 334 } |
OLD | NEW |