stack.h (31966B)
1 // Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef OPENSSL_HEADER_STACK_H 16 #define OPENSSL_HEADER_STACK_H 17 18 #include <openssl/base.h> // IWYU pragma: export 19 20 #if defined(__cplusplus) 21 extern "C" { 22 #endif 23 24 25 // A stack, in OpenSSL, is an array of pointers. They are the most commonly 26 // used collection object. 27 // 28 // This file defines macros for type-safe use of the stack functions. A stack 29 // type is named like |STACK_OF(FOO)| and is accessed with functions named 30 // like |sk_FOO_*|. Note the stack will typically contain /pointers/ to |FOO|. 31 // 32 // The |DECLARE_STACK_OF| macro makes |STACK_OF(FOO)| available, and 33 // |DEFINE_STACK_OF| makes the corresponding functions available. 34 35 36 // Defining stacks. 37 38 // STACK_OF expands to the stack type for |type|. 39 #define STACK_OF(type) struct stack_st_##type 40 41 // DECLARE_STACK_OF declares the |STACK_OF(type)| type. It does not make the 42 // corresponding |sk_type_*| functions available. This macro should be used in 43 // files which only need the type. 44 #define DECLARE_STACK_OF(type) STACK_OF(type); 45 46 // DEFINE_NAMED_STACK_OF defines |STACK_OF(name)| to be a stack whose elements 47 // are |type| *. This macro makes the |sk_name_*| functions available. 48 // 49 // It is not necessary to use |DECLARE_STACK_OF| in files which use this macro. 50 #define DEFINE_NAMED_STACK_OF(name, type) \ 51 BORINGSSL_DEFINE_STACK_OF_IMPL(name, type *, const type *) \ 52 BORINGSSL_DEFINE_STACK_TRAITS(name, type, false) 53 54 // DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are 55 // |type| *. This macro makes the |sk_type_*| functions available. 56 // 57 // It is not necessary to use |DECLARE_STACK_OF| in files which use this macro. 58 #define DEFINE_STACK_OF(type) DEFINE_NAMED_STACK_OF(type, type) 59 60 // DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements 61 // are const |type| *. This macro makes the |sk_type_*| functions available. 62 // 63 // It is not necessary to use |DECLARE_STACK_OF| in files which use this macro. 64 #define DEFINE_CONST_STACK_OF(type) \ 65 BORINGSSL_DEFINE_STACK_OF_IMPL(type, const type *, const type *) \ 66 BORINGSSL_DEFINE_STACK_TRAITS(type, const type, true) 67 68 69 // Using stacks. 70 // 71 // After the |DEFINE_STACK_OF| macro is used, the following functions are 72 // available. 73 74 #if 0 // Sample 75 76 // sk_SAMPLE_free_func is a callback to free an element in a stack. 77 typedef void (*sk_SAMPLE_free_func)(SAMPLE *); 78 79 // sk_SAMPLE_copy_func is a callback to copy an element in a stack. It should 80 // return the copy or NULL on error. 81 typedef SAMPLE *(*sk_SAMPLE_copy_func)(const SAMPLE *); 82 83 // sk_SAMPLE_cmp_func is a callback to compare |*a| to |*b|. It should return a 84 // value < 0, 0, or > 0 if |*a| is less than, equal to, or greater than |*b|, 85 // respectively. Note the extra indirection - the function is given a pointer 86 // to a pointer to the element. This is the |qsort|/|bsearch| comparison 87 // function applied to an array of |SAMPLE*|. 88 typedef int (*sk_SAMPLE_cmp_func)(const SAMPLE *const *a, 89 const SAMPLE *const *b); 90 91 // sk_SAMPLE_new creates a new, empty stack with the given comparison function, 92 // which may be NULL. It returns the new stack or NULL on allocation failure. 93 STACK_OF(SAMPLE) *sk_SAMPLE_new(sk_SAMPLE_cmp_func comp); 94 95 // sk_SAMPLE_new_null creates a new, empty stack. It returns the new stack or 96 // NULL on allocation failure. 97 STACK_OF(SAMPLE) *sk_SAMPLE_new_null(void); 98 99 // sk_SAMPLE_num returns the number of elements in |sk|. It is safe to cast this 100 // value to |int|. |sk| is guaranteed to have at most |INT_MAX| elements. If 101 // |sk| is NULL, it is treated as the empty list and this function returns zero. 102 size_t sk_SAMPLE_num(const STACK_OF(SAMPLE) *sk); 103 104 // sk_SAMPLE_zero resets |sk| to the empty state but does nothing to free the 105 // individual elements themselves. 106 void sk_SAMPLE_zero(STACK_OF(SAMPLE) *sk); 107 108 // sk_SAMPLE_value returns the |i|th pointer in |sk|, or NULL if |i| is out of 109 // range. If |sk| is NULL, it is treated as an empty list and the function 110 // returns NULL. 111 SAMPLE *sk_SAMPLE_value(const STACK_OF(SAMPLE) *sk, size_t i); 112 113 // sk_SAMPLE_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| 114 // is out of range, it returns NULL. 115 SAMPLE *sk_SAMPLE_set(STACK_OF(SAMPLE) *sk, size_t i, SAMPLE *p); 116 117 // sk_SAMPLE_free frees |sk|, but does nothing to free the individual elements. 118 // Use |sk_SAMPLE_pop_free| to also free the elements. 119 void sk_SAMPLE_free(STACK_OF(SAMPLE) *sk); 120 121 // sk_SAMPLE_pop_free calls |free_func| on each element in |sk| and then 122 // frees the stack itself. 123 void sk_SAMPLE_pop_free(STACK_OF(SAMPLE) *sk, sk_SAMPLE_free_func free_func); 124 125 // sk_SAMPLE_insert inserts |p| into the stack at index |where|, moving existing 126 // elements if needed. It returns the length of the new stack, or zero on 127 // error. 128 size_t sk_SAMPLE_insert(STACK_OF(SAMPLE) *sk, SAMPLE *p, size_t where); 129 130 // sk_SAMPLE_delete removes the pointer at index |where|, moving other elements 131 // down if needed. It returns the removed pointer, or NULL if |where| is out of 132 // range. 133 SAMPLE *sk_SAMPLE_delete(STACK_OF(SAMPLE) *sk, size_t where); 134 135 // sk_SAMPLE_delete_ptr removes, at most, one instance of |p| from |sk| based on 136 // pointer equality. If an instance of |p| is found then |p| is returned, 137 // otherwise it returns NULL. 138 SAMPLE *sk_SAMPLE_delete_ptr(STACK_OF(SAMPLE) *sk, const SAMPLE *p); 139 140 // sk_SAMPLE_delete_if_func is the callback function for |sk_SAMPLE_delete_if|. 141 // It should return one to remove |p| and zero to keep it. 142 typedef int (*sk_SAMPLE_delete_if_func)(SAMPLE *p, void *data); 143 144 // sk_SAMPLE_delete_if calls |func| with each element of |sk| and removes the 145 // entries where |func| returned one. This function does not free or return 146 // removed pointers so, if |sk| owns its contents, |func| should release the 147 // pointers prior to returning one. 148 void sk_SAMPLE_delete_if(STACK_OF(SAMPLE) *sk, sk_SAMPLE_delete_if_func func, 149 void *data); 150 151 // sk_SAMPLE_find find the first value in |sk| equal to |p|. |sk|'s comparison 152 // function determines equality, or pointer equality if |sk| has no comparison 153 // function. 154 // 155 // If the stack is sorted (see |sk_SAMPLE_sort|), this function uses a binary 156 // search. Otherwise it performs a linear search. If it finds a matching 157 // element, it writes the index to |*out_index| (if |out_index| is not NULL) and 158 // returns one. Otherwise, it returns zero. If |sk| is NULL, it is treated as 159 // the empty list and the function returns zero. 160 // 161 // Note this differs from OpenSSL. The type signature is slightly different, and 162 // OpenSSL's version will implicitly sort |sk| if it has a comparison function 163 // defined. 164 int sk_SAMPLE_find(const STACK_OF(SAMPLE) *sk, size_t *out_index, 165 const SAMPLE *p); 166 167 // sk_SAMPLE_shift removes and returns the first element in |sk|, or NULL if 168 // |sk| is empty. 169 SAMPLE *sk_SAMPLE_shift(STACK_OF(SAMPLE) *sk); 170 171 // sk_SAMPLE_push appends |p| to |sk| and returns the length of the new stack, 172 // or 0 on allocation failure. 173 size_t sk_SAMPLE_push(STACK_OF(SAMPLE) *sk, SAMPLE *p); 174 175 // sk_SAMPLE_pop removes and returns the last element of |sk|, or NULL if |sk| 176 // is empty. 177 SAMPLE *sk_SAMPLE_pop(STACK_OF(SAMPLE) *sk); 178 179 // sk_SAMPLE_dup performs a shallow copy of a stack and returns the new stack, 180 // or NULL on error. Use |sk_SAMPLE_deep_copy| to also copy the elements. 181 STACK_OF(SAMPLE) *sk_SAMPLE_dup(const STACK_OF(SAMPLE) *sk); 182 183 // sk_SAMPLE_sort sorts the elements of |sk| into ascending order based on the 184 // comparison function. The stack maintains a "sorted" flag and sorting an 185 // already sorted stack is a no-op. 186 void sk_SAMPLE_sort(STACK_OF(SAMPLE) *sk); 187 188 // sk_SAMPLE_is_sorted returns one if |sk| is known to be sorted and zero 189 // otherwise. 190 int sk_SAMPLE_is_sorted(const STACK_OF(SAMPLE) *sk); 191 192 // sk_SAMPLE_set_cmp_func sets the comparison function to be used by |sk| and 193 // returns the previous one. 194 sk_SAMPLE_cmp_func sk_SAMPLE_set_cmp_func(STACK_OF(SAMPLE) *sk, 195 sk_SAMPLE_cmp_func comp); 196 197 // sk_SAMPLE_deep_copy performs a copy of |sk| and of each of the non-NULL 198 // elements in |sk| by using |copy_func|. If an error occurs, it calls 199 // |free_func| to free any copies already made and returns NULL. 200 STACK_OF(SAMPLE) *sk_SAMPLE_deep_copy(const STACK_OF(SAMPLE) *sk, 201 sk_SAMPLE_copy_func copy_func, 202 sk_SAMPLE_free_func free_func); 203 204 #endif // Sample 205 206 207 // Private functions. 208 // 209 // The |sk_*| functions generated above are implemented internally using the 210 // type-erased functions below. Callers should use the typed wrappers instead. 211 // When using the type-erased functions, callers are responsible for ensuring 212 // the underlying types are correct. Casting pointers to the wrong types will 213 // result in memory errors. 214 215 // OPENSSL_sk_free_func is a function that frees an element in a stack. Note its 216 // actual type is void (*)(T *) for some T. Low-level |sk_*| functions will be 217 // passed a type-specific wrapper to call it correctly. 218 typedef void (*OPENSSL_sk_free_func)(void *ptr); 219 220 // OPENSSL_sk_copy_func is a function that copies an element in a stack. Note 221 // its actual type is T *(*)(const T *) for some T. Low-level |sk_*| functions 222 // will be passed a type-specific wrapper to call it correctly. 223 typedef void *(*OPENSSL_sk_copy_func)(const void *ptr); 224 225 // OPENSSL_sk_cmp_func is a comparison function that returns a value < 0, 0 or > 226 // 0 if |*a| is less than, equal to or greater than |*b|, respectively. Note 227 // the extra indirection - the function is given a pointer to a pointer to the 228 // element. This differs from the usual qsort/bsearch comparison function. 229 // 230 // Note its actual type is |int (*)(const T *const *a, const T *const *b)|. 231 // Low-level |sk_*| functions will be passed a type-specific wrapper to call it 232 // correctly. 233 typedef int (*OPENSSL_sk_cmp_func)(const void *const *a, const void *const *b); 234 235 // OPENSSL_sk_delete_if_func is the generic version of 236 // |sk_SAMPLE_delete_if_func|. 237 typedef int (*OPENSSL_sk_delete_if_func)(void *obj, void *data); 238 239 // The following function types call the above type-erased signatures with the 240 // true types. 241 typedef void (*OPENSSL_sk_call_free_func)(OPENSSL_sk_free_func, void *); 242 typedef void *(*OPENSSL_sk_call_copy_func)(OPENSSL_sk_copy_func, const void *); 243 typedef int (*OPENSSL_sk_call_cmp_func)(OPENSSL_sk_cmp_func, const void *, 244 const void *); 245 typedef int (*OPENSSL_sk_call_delete_if_func)(OPENSSL_sk_delete_if_func, void *, 246 void *); 247 248 // An OPENSSL_STACK contains an array of pointers. It is not designed to be used 249 // directly, rather the wrapper macros should be used. 250 typedef struct stack_st OPENSSL_STACK; 251 252 // The following are raw stack functions. They implement the corresponding typed 253 // |sk_SAMPLE_*| functions generated by |DEFINE_STACK_OF|. Callers shouldn't be 254 // using them. Rather, callers should use the typed functions. 255 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_cmp_func comp); 256 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_new_null(void); 257 OPENSSL_EXPORT size_t OPENSSL_sk_num(const OPENSSL_STACK *sk); 258 OPENSSL_EXPORT void OPENSSL_sk_zero(OPENSSL_STACK *sk); 259 OPENSSL_EXPORT void *OPENSSL_sk_value(const OPENSSL_STACK *sk, size_t i); 260 OPENSSL_EXPORT void *OPENSSL_sk_set(OPENSSL_STACK *sk, size_t i, void *p); 261 OPENSSL_EXPORT void OPENSSL_sk_free(OPENSSL_STACK *sk); 262 OPENSSL_EXPORT void OPENSSL_sk_pop_free_ex( 263 OPENSSL_STACK *sk, OPENSSL_sk_call_free_func call_free_func, 264 OPENSSL_sk_free_func free_func); 265 OPENSSL_EXPORT size_t OPENSSL_sk_insert(OPENSSL_STACK *sk, void *p, 266 size_t where); 267 OPENSSL_EXPORT void *OPENSSL_sk_delete(OPENSSL_STACK *sk, size_t where); 268 OPENSSL_EXPORT void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *sk, const void *p); 269 OPENSSL_EXPORT void OPENSSL_sk_delete_if( 270 OPENSSL_STACK *sk, OPENSSL_sk_call_delete_if_func call_func, 271 OPENSSL_sk_delete_if_func func, void *data); 272 OPENSSL_EXPORT int OPENSSL_sk_find(const OPENSSL_STACK *sk, size_t *out_index, 273 const void *p, 274 OPENSSL_sk_call_cmp_func call_cmp_func); 275 OPENSSL_EXPORT void *OPENSSL_sk_shift(OPENSSL_STACK *sk); 276 OPENSSL_EXPORT size_t OPENSSL_sk_push(OPENSSL_STACK *sk, void *p); 277 OPENSSL_EXPORT void *OPENSSL_sk_pop(OPENSSL_STACK *sk); 278 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk); 279 OPENSSL_EXPORT void OPENSSL_sk_sort(OPENSSL_STACK *sk, 280 OPENSSL_sk_call_cmp_func call_cmp_func); 281 OPENSSL_EXPORT int OPENSSL_sk_is_sorted(const OPENSSL_STACK *sk); 282 OPENSSL_EXPORT OPENSSL_sk_cmp_func 283 OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_cmp_func comp); 284 OPENSSL_EXPORT OPENSSL_STACK *OPENSSL_sk_deep_copy( 285 const OPENSSL_STACK *sk, OPENSSL_sk_call_copy_func call_copy_func, 286 OPENSSL_sk_copy_func copy_func, OPENSSL_sk_call_free_func call_free_func, 287 OPENSSL_sk_free_func free_func); 288 289 290 // Deprecated private functions (hidden). 291 // 292 // TODO(crbug.com/boringssl/499): Migrate callers to the typed wrappers, or at 293 // least the new names and remove the old ones. 294 // 295 // TODO(b/290792019, b/290785937): Ideally these would at least be inline 296 // functions, so we do not squat the symbols. 297 298 typedef OPENSSL_STACK _STACK; 299 300 // The following functions call the corresponding |OPENSSL_sk_*| function. 301 OPENSSL_EXPORT OPENSSL_DEPRECATED OPENSSL_STACK *sk_new_null(void); 302 OPENSSL_EXPORT OPENSSL_DEPRECATED size_t sk_num(const OPENSSL_STACK *sk); 303 OPENSSL_EXPORT OPENSSL_DEPRECATED void *sk_value(const OPENSSL_STACK *sk, 304 size_t i); 305 OPENSSL_EXPORT OPENSSL_DEPRECATED void sk_free(OPENSSL_STACK *sk); 306 OPENSSL_EXPORT OPENSSL_DEPRECATED size_t sk_push(OPENSSL_STACK *sk, void *p); 307 OPENSSL_EXPORT OPENSSL_DEPRECATED void *sk_pop(OPENSSL_STACK *sk); 308 309 // sk_pop_free_ex calls |OPENSSL_sk_pop_free_ex|. 310 // 311 // TODO(b/291994116): Remove this. 312 OPENSSL_EXPORT OPENSSL_DEPRECATED void sk_pop_free_ex( 313 OPENSSL_STACK *sk, OPENSSL_sk_call_free_func call_free_func, 314 OPENSSL_sk_free_func free_func); 315 316 // sk_pop_free behaves like |OPENSSL_sk_pop_free_ex| but performs an invalid 317 // function pointer cast. It exists because some existing callers called 318 // |sk_pop_free| directly. 319 // 320 // TODO(davidben): Migrate callers to bssl::UniquePtr and remove this. 321 OPENSSL_EXPORT OPENSSL_DEPRECATED void sk_pop_free( 322 OPENSSL_STACK *sk, OPENSSL_sk_free_func free_func); 323 324 325 #if !defined(BORINGSSL_NO_CXX) 326 extern "C++" { 327 BSSL_NAMESPACE_BEGIN 328 namespace internal { 329 template <typename T> 330 struct StackTraits {}; 331 } 332 BSSL_NAMESPACE_END 333 } 334 335 #define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) \ 336 extern "C++" { \ 337 BSSL_NAMESPACE_BEGIN \ 338 namespace internal { \ 339 template <> \ 340 struct StackTraits<STACK_OF(name)> { \ 341 static constexpr bool kIsStack = true; \ 342 using Type = type; \ 343 static constexpr bool kIsConst = is_const; \ 344 }; \ 345 } \ 346 BSSL_NAMESPACE_END \ 347 } 348 349 #else 350 #define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) 351 #endif 352 353 #define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \ 354 /* We disable MSVC C4191 in this macro, which warns when pointers are cast \ 355 * to the wrong type. While the cast itself is valid, it is often a bug \ 356 * because calling it through the cast is UB. However, we never actually \ 357 * call functions as |OPENSSL_sk_cmp_func|. The type is just a type-erased \ 358 * function pointer. (C does not guarantee function pointers fit in \ 359 * |void*|, and GCC will warn on this.) Thus we just disable the false \ 360 * positive warning. */ \ 361 OPENSSL_MSVC_PRAGMA(warning(push)) \ 362 OPENSSL_MSVC_PRAGMA(warning(disable : 4191)) \ 363 OPENSSL_GNUC_CLANG_PRAGMA("GCC diagnostic push") \ 364 OPENSSL_CLANG_PRAGMA( \ 365 "clang diagnostic ignored \"-Wunknown-warning-option\"") \ 366 OPENSSL_CLANG_PRAGMA( \ 367 "clang diagnostic ignored \"-Wcast-function-type-strict\"") \ 368 /* We also disable -Wcast-qual. As part of this C-based type erasure setup, \ 369 * the wrapper macros need to cast away const in places. In C++, const_cast \ 370 * suppresses the warning, but it seemingly cannot be suppressed in C. */ \ 371 OPENSSL_GNUC_CLANG_PRAGMA("GCC diagnostic ignored \"-Wcast-qual\"") \ 372 \ 373 DECLARE_STACK_OF(name) \ 374 \ 375 typedef void (*sk_##name##_free_func)(ptrtype); \ 376 typedef ptrtype (*sk_##name##_copy_func)(constptrtype); \ 377 typedef int (*sk_##name##_cmp_func)(constptrtype const *, \ 378 constptrtype const *); \ 379 typedef int (*sk_##name##_delete_if_func)(ptrtype, void *); \ 380 \ 381 OPENSSL_INLINE void sk_##name##_call_free_func( \ 382 OPENSSL_sk_free_func free_func, void *ptr) { \ 383 ((sk_##name##_free_func)free_func)((ptrtype)ptr); \ 384 } \ 385 \ 386 OPENSSL_INLINE void *sk_##name##_call_copy_func( \ 387 OPENSSL_sk_copy_func copy_func, const void *ptr) { \ 388 return (void *)((sk_##name##_copy_func)copy_func)((constptrtype)ptr); \ 389 } \ 390 \ 391 OPENSSL_INLINE int sk_##name##_call_cmp_func(OPENSSL_sk_cmp_func cmp_func, \ 392 const void *a, const void *b) { \ 393 constptrtype a_ptr = (constptrtype)a; \ 394 constptrtype b_ptr = (constptrtype)b; \ 395 /* |cmp_func| expects an extra layer of pointers to match qsort. */ \ 396 return ((sk_##name##_cmp_func)cmp_func)(&a_ptr, &b_ptr); \ 397 } \ 398 \ 399 OPENSSL_INLINE int sk_##name##_call_delete_if_func( \ 400 OPENSSL_sk_delete_if_func func, void *obj, void *data) { \ 401 return ((sk_##name##_delete_if_func)func)((ptrtype)obj, data); \ 402 } \ 403 \ 404 OPENSSL_INLINE STACK_OF(name) *sk_##name##_new(sk_##name##_cmp_func comp) { \ 405 return (STACK_OF(name) *)OPENSSL_sk_new((OPENSSL_sk_cmp_func)comp); \ 406 } \ 407 \ 408 OPENSSL_INLINE STACK_OF(name) *sk_##name##_new_null(void) { \ 409 return (STACK_OF(name) *)OPENSSL_sk_new_null(); \ 410 } \ 411 \ 412 OPENSSL_INLINE size_t sk_##name##_num(const STACK_OF(name) *sk) { \ 413 return OPENSSL_sk_num((const OPENSSL_STACK *)sk); \ 414 } \ 415 \ 416 OPENSSL_INLINE void sk_##name##_zero(STACK_OF(name) *sk) { \ 417 OPENSSL_sk_zero((OPENSSL_STACK *)sk); \ 418 } \ 419 \ 420 OPENSSL_INLINE ptrtype sk_##name##_value(const STACK_OF(name) *sk, \ 421 size_t i) { \ 422 return (ptrtype)OPENSSL_sk_value((const OPENSSL_STACK *)sk, i); \ 423 } \ 424 \ 425 OPENSSL_INLINE ptrtype sk_##name##_set(STACK_OF(name) *sk, size_t i, \ 426 ptrtype p) { \ 427 return (ptrtype)OPENSSL_sk_set((OPENSSL_STACK *)sk, i, (void *)p); \ 428 } \ 429 \ 430 OPENSSL_INLINE void sk_##name##_free(STACK_OF(name) *sk) { \ 431 OPENSSL_sk_free((OPENSSL_STACK *)sk); \ 432 } \ 433 \ 434 OPENSSL_INLINE void sk_##name##_pop_free(STACK_OF(name) *sk, \ 435 sk_##name##_free_func free_func) { \ 436 OPENSSL_sk_pop_free_ex((OPENSSL_STACK *)sk, sk_##name##_call_free_func, \ 437 (OPENSSL_sk_free_func)free_func); \ 438 } \ 439 \ 440 OPENSSL_INLINE size_t sk_##name##_insert(STACK_OF(name) *sk, ptrtype p, \ 441 size_t where) { \ 442 return OPENSSL_sk_insert((OPENSSL_STACK *)sk, (void *)p, where); \ 443 } \ 444 \ 445 OPENSSL_INLINE ptrtype sk_##name##_delete(STACK_OF(name) *sk, \ 446 size_t where) { \ 447 return (ptrtype)OPENSSL_sk_delete((OPENSSL_STACK *)sk, where); \ 448 } \ 449 \ 450 OPENSSL_INLINE ptrtype sk_##name##_delete_ptr(STACK_OF(name) *sk, \ 451 constptrtype p) { \ 452 return (ptrtype)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, \ 453 (const void *)p); \ 454 } \ 455 \ 456 OPENSSL_INLINE void sk_##name##_delete_if( \ 457 STACK_OF(name) *sk, sk_##name##_delete_if_func func, void *data) { \ 458 OPENSSL_sk_delete_if((OPENSSL_STACK *)sk, sk_##name##_call_delete_if_func, \ 459 (OPENSSL_sk_delete_if_func)func, data); \ 460 } \ 461 \ 462 OPENSSL_INLINE int sk_##name##_find(const STACK_OF(name) *sk, \ 463 size_t *out_index, constptrtype p) { \ 464 return OPENSSL_sk_find((const OPENSSL_STACK *)sk, out_index, \ 465 (const void *)p, sk_##name##_call_cmp_func); \ 466 } \ 467 \ 468 OPENSSL_INLINE ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \ 469 return (ptrtype)OPENSSL_sk_shift((OPENSSL_STACK *)sk); \ 470 } \ 471 \ 472 OPENSSL_INLINE size_t sk_##name##_push(STACK_OF(name) *sk, ptrtype p) { \ 473 return OPENSSL_sk_push((OPENSSL_STACK *)sk, (void *)p); \ 474 } \ 475 \ 476 OPENSSL_INLINE ptrtype sk_##name##_pop(STACK_OF(name) *sk) { \ 477 return (ptrtype)OPENSSL_sk_pop((OPENSSL_STACK *)sk); \ 478 } \ 479 \ 480 OPENSSL_INLINE STACK_OF(name) *sk_##name##_dup(const STACK_OF(name) *sk) { \ 481 return (STACK_OF(name) *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); \ 482 } \ 483 \ 484 OPENSSL_INLINE void sk_##name##_sort(STACK_OF(name) *sk) { \ 485 OPENSSL_sk_sort((OPENSSL_STACK *)sk, sk_##name##_call_cmp_func); \ 486 } \ 487 \ 488 OPENSSL_INLINE int sk_##name##_is_sorted(const STACK_OF(name) *sk) { \ 489 return OPENSSL_sk_is_sorted((const OPENSSL_STACK *)sk); \ 490 } \ 491 \ 492 OPENSSL_INLINE sk_##name##_cmp_func sk_##name##_set_cmp_func( \ 493 STACK_OF(name) *sk, sk_##name##_cmp_func comp) { \ 494 return (sk_##name##_cmp_func)OPENSSL_sk_set_cmp_func( \ 495 (OPENSSL_STACK *)sk, (OPENSSL_sk_cmp_func)comp); \ 496 } \ 497 \ 498 OPENSSL_INLINE STACK_OF(name) *sk_##name##_deep_copy( \ 499 const STACK_OF(name) *sk, sk_##name##_copy_func copy_func, \ 500 sk_##name##_free_func free_func) { \ 501 return (STACK_OF(name) *)OPENSSL_sk_deep_copy( \ 502 (const OPENSSL_STACK *)sk, sk_##name##_call_copy_func, \ 503 (OPENSSL_sk_copy_func)copy_func, sk_##name##_call_free_func, \ 504 (OPENSSL_sk_free_func)free_func); \ 505 } \ 506 \ 507 OPENSSL_GNUC_CLANG_PRAGMA("GCC diagnostic pop") \ 508 OPENSSL_MSVC_PRAGMA(warning(pop)) 509 510 511 // Built-in stacks. 512 513 typedef char *OPENSSL_STRING; 514 515 DEFINE_STACK_OF(void) 516 DEFINE_NAMED_STACK_OF(OPENSSL_STRING, char) 517 518 519 #if defined(__cplusplus) 520 } // extern C 521 #endif 522 523 #if !defined(BORINGSSL_NO_CXX) 524 extern "C++" { 525 526 #include <type_traits> 527 528 BSSL_NAMESPACE_BEGIN 529 530 namespace internal { 531 532 // Stacks defined with |DEFINE_CONST_STACK_OF| are freed with |sk_free|. 533 template <typename Stack> 534 struct DeleterImpl<Stack, std::enable_if_t<StackTraits<Stack>::kIsConst>> { 535 static void Free(Stack *sk) { 536 OPENSSL_sk_free(reinterpret_cast<OPENSSL_STACK *>(sk)); 537 } 538 }; 539 540 // Stacks defined with |DEFINE_STACK_OF| are freed with |sk_pop_free| and the 541 // corresponding type's deleter. 542 template <typename Stack> 543 struct DeleterImpl<Stack, std::enable_if_t<!StackTraits<Stack>::kIsConst>> { 544 static void Free(Stack *sk) { 545 // sk_FOO_pop_free is defined by macros and bound by name, so we cannot 546 // access it from C++ here. 547 using Type = typename StackTraits<Stack>::Type; 548 OPENSSL_sk_pop_free_ex( 549 reinterpret_cast<OPENSSL_STACK *>(sk), 550 [](OPENSSL_sk_free_func /* unused */, void *ptr) { 551 DeleterImpl<Type>::Free(reinterpret_cast<Type *>(ptr)); 552 }, 553 nullptr); 554 } 555 }; 556 557 template <typename Stack> 558 class StackIteratorImpl { 559 public: 560 using Type = typename StackTraits<Stack>::Type; 561 // Iterators must be default-constructable. 562 StackIteratorImpl() : sk_(nullptr), idx_(0) {} 563 StackIteratorImpl(const Stack *sk, size_t idx) : sk_(sk), idx_(idx) {} 564 565 bool operator==(StackIteratorImpl other) const { 566 return sk_ == other.sk_ && idx_ == other.idx_; 567 } 568 bool operator!=(StackIteratorImpl other) const { 569 return !(*this == other); 570 } 571 572 Type *operator*() const { 573 return reinterpret_cast<Type *>( 574 OPENSSL_sk_value(reinterpret_cast<const OPENSSL_STACK *>(sk_), idx_)); 575 } 576 577 StackIteratorImpl &operator++(/* prefix */) { 578 idx_++; 579 return *this; 580 } 581 582 StackIteratorImpl operator++(int /* postfix */) { 583 StackIteratorImpl copy(*this); 584 ++(*this); 585 return copy; 586 } 587 588 private: 589 const Stack *sk_; 590 size_t idx_; 591 }; 592 593 template <typename Stack> 594 using StackIterator = 595 std::enable_if_t<StackTraits<Stack>::kIsStack, StackIteratorImpl<Stack>>; 596 597 } // namespace internal 598 599 // PushToStack pushes |elem| to |sk|. It returns true on success and false on 600 // allocation failure. 601 template <typename Stack> 602 inline std::enable_if_t<!internal::StackTraits<Stack>::kIsConst, bool> 603 PushToStack(Stack *sk, 604 UniquePtr<typename internal::StackTraits<Stack>::Type> elem) { 605 if (!OPENSSL_sk_push(reinterpret_cast<OPENSSL_STACK *>(sk), elem.get())) { 606 return false; 607 } 608 // OPENSSL_sk_push takes ownership on success. 609 elem.release(); 610 return true; 611 } 612 613 BSSL_NAMESPACE_END 614 615 // Define begin() and end() for stack types so C++ range for loops work. 616 template <typename Stack> 617 inline bssl::internal::StackIterator<Stack> begin(const Stack *sk) { 618 return bssl::internal::StackIterator<Stack>(sk, 0); 619 } 620 621 template <typename Stack> 622 inline bssl::internal::StackIterator<Stack> end(const Stack *sk) { 623 return bssl::internal::StackIterator<Stack>( 624 sk, OPENSSL_sk_num(reinterpret_cast<const OPENSSL_STACK *>(sk))); 625 } 626 627 } // extern C++ 628 #endif 629 630 #endif // OPENSSL_HEADER_STACK_H