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