2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 #include "internal/cryptlib.h"
12 #include <openssl/stack.h>
13 #include <openssl/objects.h>
20 OPENSSL_sk_compfunc comp
;
28 OPENSSL_sk_compfunc
OPENSSL_sk_set_cmp_func(OPENSSL_STACK
*sk
, OPENSSL_sk_compfunc c
)
30 OPENSSL_sk_compfunc old
= sk
->comp
;
39 OPENSSL_STACK
*OPENSSL_sk_dup(OPENSSL_STACK
*sk
)
44 if ((ret
= OPENSSL_sk_new(sk
->comp
)) == NULL
)
46 s
= OPENSSL_realloc((char *)ret
->data
,
47 (unsigned int)sizeof(char *) * sk
->num_alloc
);
53 memcpy(ret
->data
, sk
->data
, sizeof(char *) * sk
->num
);
54 ret
->sorted
= sk
->sorted
;
55 ret
->num_alloc
= sk
->num_alloc
;
63 OPENSSL_STACK
*OPENSSL_sk_deep_copy(OPENSSL_STACK
*sk
, OPENSSL_sk_copyfunc copy_func
,
64 OPENSSL_sk_freefunc free_func
)
69 if ((ret
= OPENSSL_malloc(sizeof(*ret
))) == NULL
)
72 ret
->sorted
= sk
->sorted
;
74 ret
->num_alloc
= sk
->num
> MIN_NODES
? sk
->num
: MIN_NODES
;
75 ret
->data
= OPENSSL_malloc(sizeof(*ret
->data
) * ret
->num_alloc
);
76 if (ret
->data
== NULL
) {
80 for (i
= 0; i
< ret
->num_alloc
; i
++)
83 for (i
= 0; i
< ret
->num
; ++i
) {
84 if (sk
->data
[i
] == NULL
)
86 if ((ret
->data
[i
] = copy_func(sk
->data
[i
])) == NULL
) {
88 if (ret
->data
[i
] != NULL
)
89 free_func(ret
->data
[i
]);
97 OPENSSL_STACK
*OPENSSL_sk_new_null(void)
99 return OPENSSL_sk_new((OPENSSL_sk_compfunc
)NULL
);
102 OPENSSL_STACK
*OPENSSL_sk_new(OPENSSL_sk_compfunc c
)
106 if ((ret
= OPENSSL_zalloc(sizeof(*ret
))) == NULL
)
108 if ((ret
->data
= OPENSSL_zalloc(sizeof(*ret
->data
) * MIN_NODES
)) == NULL
)
111 ret
->num_alloc
= MIN_NODES
;
119 int OPENSSL_sk_insert(OPENSSL_STACK
*st
, void *data
, int loc
)
125 if (st
->num_alloc
<= st
->num
+ 1) {
126 s
= OPENSSL_realloc((char *)st
->data
,
127 (unsigned int)sizeof(char *) * st
->num_alloc
* 2);
133 if ((loc
>= (int)st
->num
) || (loc
< 0))
134 st
->data
[st
->num
] = data
;
136 memmove(&(st
->data
[loc
+ 1]),
137 &(st
->data
[loc
]), sizeof(char *) * (st
->num
- loc
));
138 st
->data
[loc
] = data
;
145 void *OPENSSL_sk_delete_ptr(OPENSSL_STACK
*st
, const void *p
)
149 for (i
= 0; i
< st
->num
; i
++)
150 if (st
->data
[i
] == p
)
151 return OPENSSL_sk_delete(st
, i
);
155 void *OPENSSL_sk_delete(OPENSSL_STACK
*st
, int loc
)
160 if (st
== NULL
|| loc
< 0 || loc
>= st
->num
)
164 if (loc
!= st
->num
- 1) {
166 for (i
= loc
; i
< j
; i
++)
167 st
->data
[i
] = st
->data
[i
+ 1];
169 * In theory memcpy is not safe for this memcpy( &(st->data[loc]),
170 * &(st->data[loc+1]), sizeof(char *)*(st->num-loc-1));
177 static int internal_find(OPENSSL_STACK
*st
, const void *data
,
180 const void *const *r
;
186 if (st
->comp
== NULL
) {
187 for (i
= 0; i
< st
->num
; i
++)
188 if (st
->data
[i
] == data
)
195 r
= OBJ_bsearch_ex_(&data
, st
->data
, st
->num
, sizeof(void *), st
->comp
,
199 return (int)((char **)r
- st
->data
);
202 int OPENSSL_sk_find(OPENSSL_STACK
*st
, const void *data
)
204 return internal_find(st
, data
, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH
);
207 int OPENSSL_sk_find_ex(OPENSSL_STACK
*st
, const void *data
)
209 return internal_find(st
, data
, OBJ_BSEARCH_VALUE_ON_NOMATCH
);
212 int OPENSSL_sk_push(OPENSSL_STACK
*st
, void *data
)
214 return (OPENSSL_sk_insert(st
, data
, st
->num
));
217 int OPENSSL_sk_unshift(OPENSSL_STACK
*st
, void *data
)
219 return (OPENSSL_sk_insert(st
, data
, 0));
222 void *OPENSSL_sk_shift(OPENSSL_STACK
*st
)
228 return (OPENSSL_sk_delete(st
, 0));
231 void *OPENSSL_sk_pop(OPENSSL_STACK
*st
)
237 return (OPENSSL_sk_delete(st
, st
->num
- 1));
240 void OPENSSL_sk_zero(OPENSSL_STACK
*st
)
246 memset(st
->data
, 0, sizeof(*st
->data
) * st
->num
);
250 void OPENSSL_sk_pop_free(OPENSSL_STACK
*st
, OPENSSL_sk_freefunc func
)
256 for (i
= 0; i
< st
->num
; i
++)
257 if (st
->data
[i
] != NULL
)
262 void OPENSSL_sk_free(OPENSSL_STACK
*st
)
266 OPENSSL_free(st
->data
);
270 int OPENSSL_sk_num(const OPENSSL_STACK
*st
)
277 void *OPENSSL_sk_value(const OPENSSL_STACK
*st
, int i
)
279 if (st
== NULL
|| i
< 0 || i
>= st
->num
)
284 void *OPENSSL_sk_set(OPENSSL_STACK
*st
, int i
, void *value
)
286 if (st
== NULL
|| i
< 0 || i
>= st
->num
)
288 return (st
->data
[i
] = value
);
291 void OPENSSL_sk_sort(OPENSSL_STACK
*st
)
293 if (st
&& !st
->sorted
&& st
->comp
!= NULL
) {
294 qsort(st
->data
, st
->num
, sizeof(char *), st
->comp
);
299 int OPENSSL_sk_is_sorted(const OPENSSL_STACK
*st
)