@ -67,36 +67,190 @@ extern "C" {
// A stack, in OpenSSL, is an array of pointers. They are the most commonly
// A stack, in OpenSSL, is an array of pointers. They are the most commonly
// used collection object.
// used collection object.
//
//
// This file defines macros for type safe use of the stack functions. A stack
// This file defines macros for type-safe use of the stack functions. A stack
// of a specific type of object has type |STACK_OF(type)|. This can be defined
// type is named like |STACK_OF(FOO)| and is accessed with functions named
// (once) with |DEFINE_STACK_OF(type)| and declared where needed with
// like |sk_FOO_*|. Note the stack will typically contain /pointers/ to |FOO|.
// |DECLARE_STACK_OF(type)|. For example:
//
//
// typedef struct foo_st {
// The |DECLARE_STACK_OF| macro makes |STACK_OF(FOO)| available, and
// int bar;
// |DEFINE_STACK_OF| makes the corresponding functions available.
// } FOO;
// Defining stacks.
// STACK_OF expands to the stack type for |type|.
# define STACK_OF(type) struct stack_st_##type
// DECLARE_STACK_OF declares the |STACK_OF(type)| type. It does not make the
// corresponding |sk_type_*| functions available. This macro should be used in
// files which only need the type.
# define DECLARE_STACK_OF(type) STACK_OF(type);
// DEFINE_NAMED_STACK_OF defines |STACK_OF(name)| to be a stack whose elements
// are |type| *. This macro makes the |sk_name_*| functions available.
//
// It is not necessary to use |DECLARE_STACK_OF| in files which use this macro.
# define DEFINE_NAMED_STACK_OF(name, type) \
BORINGSSL_DEFINE_STACK_OF_IMPL ( name , type * , const type * ) \
BORINGSSL_DEFINE_STACK_TRAITS ( name , type , false )
// DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are
// |type| *. This macro makes the |sk_type_*| functions available.
//
// It is not necessary to use |DECLARE_STACK_OF| in files which use this macro.
# define DEFINE_STACK_OF(type) DEFINE_NAMED_STACK_OF(type, type)
// DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements
// are const |type| *. This macro makes the |sk_type_*| functions available.
//
//
// DEFINE_STACK_OF(FOO)
// It is not necessary to use |DECLARE_STACK_OF| in files which use this macro.
# define DEFINE_CONST_STACK_OF(type) \
BORINGSSL_DEFINE_STACK_OF_IMPL ( type , const type * , const type * ) \
BORINGSSL_DEFINE_STACK_TRAITS ( type , const type , true )
// Using stacks.
//
//
// Although note that the stack will contain /pointers/ to |FOO|.
// After the |DEFINE_STACK_OF| macro is used, the following functions are
// available.
#if 0 // Sample
// sk_SAMPLE_free_func is a callback to free an element in a stack.
typedef void ( * sk_SAMPLE_free_func ) ( SAMPLE * ) ;
// sk_SAMPLE_copy_func is a callback to copy an element in a stack. It should
// return the copy or NULL on error.
typedef SAMPLE * ( * sk_SAMPLE_copy_func ) ( SAMPLE * ) ;
// sk_SAMPLE_cmp_func is a callback to compare |*a| to |*b|. It should return a
// value < 0, 0, or > 0 if |*a| is less than, equal to, or greater than |*b|,
// respectively. Note the extra indirection - the function is given a pointer
// to a pointer to the element. This is the |qsort|/|bsearch| comparison
// function applied to an array of |SAMPLE*|.
//
//
// A macro will be defined for each of the sk_* functions below. For
// TODO(https://crbug.com/boringssl/498): The parameters should be
// STACK_OF(FOO), the macros would be sk_FOO_new, sk_FOO_pop etc.
// |const SAMPLE *const *|.
typedef int ( * sk_SAMPLE_cmp_func ) ( const SAMPLE * * a , const SAMPLE * * b ) ;
// sk_SAMPLE_new creates a new, empty stack with the given comparison function,
// which may be NULL. It returns the new stack or NULL on allocation failure.
STACK_OF ( SAMPLE ) * sk_SAMPLE_new ( sk_SAMPLE_cmp_func comp ) ;
// sk_SAMPLE_new_null creates a new, empty stack. It returns the new stack or
// NULL on allocation failure.
STACK_OF ( SAMPLE ) * sk_SAMPLE_new_null ( void ) ;
// sk_SAMPLE_num returns the number of elements in |sk|.
size_t sk_SAMPLE_num ( const STACK_OF ( SAMPLE ) * sk ) ;
// sk_SAMPLE_zero resets |sk| to the empty state but does nothing to free the
// individual elements themselves.
void sk_SAMPLE_zero ( STACK_OF ( SAMPLE ) * sk ) ;
// sk_SAMPLE_value returns the |i|th pointer in |sk|, or NULL if |i| is out of
// range.
SAMPLE * sk_SAMPLE_value ( const STACK_OF ( SAMPLE ) * sk , size_t i ) ;
// sk_SAMPLE_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i|
// is out of range, it returns NULL.
SAMPLE * sk_SAMPLE_set ( STACK_OF ( SAMPLE ) * sk , size_t i , SAMPLE * p ) ;
// sk_SAMPLE_free frees |sk|, but does nothing to free the individual elements.
// Use |sk_SAMPLE_pop_free| to also free the elements.
void sk_SAMPLE_free ( STACK_OF ( SAMPLE ) * sk ) ;
// sk_SAMPLE_pop_free calls |free_func| on each element in |sk| and then
// frees the stack itself.
void sk_SAMPLE_pop_free ( STACK_OF ( SAMPLE ) * sk , sk_SAMPLE_free_func free_func ) ;
// sk_SAMPLE_insert inserts |p| into the stack at index |where|, moving existing
// elements if needed. It returns the length of the new stack, or zero on
// error.
size_t sk_SAMPLE_insert ( STACK_OF ( SAMPLE ) * sk , SAMPLE * p , size_t where ) ;
// sk_SAMPLE_delete removes the pointer at index |where|, moving other elements
// down if needed. It returns the removed pointer, or NULL if |where| is out of
// range.
SAMPLE * sk_SAMPLE_delete ( STACK_OF ( SAMPLE ) * sk , size_t where ) ;
// sk_SAMPLE_delete_ptr removes, at most, one instance of |p| from |sk| based on
// pointer equality. If an instance of |p| is found then |p| is returned,
// otherwise it returns NULL.
SAMPLE * sk_SAMPLE_delete_ptr ( STACK_OF ( SAMPLE ) * sk , const SAMPLE * p ) ;
// sk_SAMPLE_find find the first value in |sk| equal to |p|. |sk|'s comparison
// function determines equality, or pointer equality if |sk| has no comparison
// function.
//
// If the stack is sorted (see |sk_SAMPLE_sort|), this function uses a binary
// search. Otherwise it performs a linear search. If it finds a matching
// element, it writes the index to |*out_index| (if |out_index| is not NULL) and
// returns one. Otherwise, it returns zero.
//
// Note this differs from OpenSSL. The type signature is slightly different, and
// OpenSSL's version will implicitly sort |sk| if it has a comparison function
// defined.
int sk_SAMPLE_find ( const STACK_OF ( SAMPLE ) * sk , size_t * out_index ,
const SAMPLE * p ) ;
// sk_SAMPLE_shift removes and returns the first element in |sk|, or NULL if
// |sk| is empty.
SAMPLE * sk_SAMPLE_shift ( STACK_OF ( SAMPLE ) * sk ) ;
// sk_SAMPLE_push appends |p| to |sk| and returns the length of the new stack,
// or 0 on allocation failure.
size_t sk_SAMPLE_push ( STACK_OF ( SAMPLE ) * sk , SAMPLE * p ) ;
// sk_SAMPLE_pop removes and returns the last element of |sk|, or NULL if |sk|
// is empty.
SAMPLE * sk_SAMPLE_pop ( STACK_OF ( SAMPLE ) * sk ) ;
// sk_SAMPLE_dup performs a shallow copy of a stack and returns the new stack,
// or NULL on error. Use |sk_SAMPLE_deep_copy| to also copy the elements.
STACK_OF ( SAMPLE ) * sk_SAMPLE_dup ( const STACK_OF ( SAMPLE ) * sk ) ;
// sk_SAMPLE_sort sorts the elements of |sk| into ascending order based on the
// comparison function. The stack maintains a "sorted" flag and sorting an
// already sorted stack is a no-op.
void sk_SAMPLE_sort ( STACK_OF ( SAMPLE ) * sk ) ;
// sk_SAMPLE_is_sorted returns one if |sk| is known to be sorted and zero
// otherwise.
int sk_SAMPLE_is_sorted ( const STACK_OF ( SAMPLE ) * sk ) ;
// sk_SAMPLE_set_cmp_func sets the comparison function to be used by |sk| and
// returns the previous one.
sk_SAMPLE_cmp_func sk_SAMPLE_set_cmp_func ( STACK_OF ( SAMPLE ) * sk ,
sk_SAMPLE_cmp_func comp ) ;
// sk_SAMPLE_deep_copy performs a copy of |sk| and of each of the non-NULL
// elements in |sk| by using |copy_func|. If an error occurs, it calls
// |free_func| to free any copies already made and returns NULL.
STACK_OF ( SAMPLE ) * sk_SAMPLE_deep_copy ( const STACK_OF ( SAMPLE ) * sk ,
sk_SAMPLE_copy_func copy_func ,
sk_SAMPLE_free_func free_func ) ;
// stack_free_func is a function that frees an element in a stack. Note its
# endif // Sample
// Private functions.
//
// TODO(https://crbug.com/boringssl/499): Rename to |OPENSSL_sk_foo|, after
// external code that calls them is fixed.
// OPENSSL_sk_free_func is a function that frees an element in a stack. Note its
// actual type is void (*)(T *) for some T. Low-level |sk_*| functions will be
// actual type is void (*)(T *) for some T. Low-level |sk_*| functions will be
// passed a type-specific wrapper to call it correctly.
// passed a type-specific wrapper to call it correctly.
typedef void ( * stack_free_func ) ( void * ptr ) ;
typedef void ( * OPENSSL_ sk_free_func) ( void * ptr ) ;
// stack_copy_func is a function that copies an element in a stack. Note its
// OPENSSL_ sk_copy_func is a function that copies an element in a stack. Note
// actual type is T *(*)(T *) for some T. Low-level |sk_*| functions will be
// its actual type is T *(*)(T *) for some T. Low-level |sk_*| functions will be
// passed a type-specific wrapper to call it correctly.
// passed a type-specific wrapper to call it correctly.
typedef void * ( * stack_copy_func ) ( void * ptr ) ;
typedef void * ( * OPENSSL_ sk_copy_func) ( void * ptr ) ;
// stack_cmp_func is a comparison function that returns a value < 0, 0 or > 0
// OPENSSL_ sk_cmp_func is a comparison function that returns a value < 0, 0 or >
// if |*a| is less than, equal to or greater than |*b|, respectively. Note the
// 0 if |*a| is less than, equal to or greater than |*b|, respectively. Note
// extra indirection - the function is given a pointer to a pointer to the
// the extra indirection - the function is given a pointer to a pointer to the
// element. This differs from the usual qsort/bsearch comparison function.
// element. This differs from the usual qsort/bsearch comparison function.
//
//
// Note its actual type is |int (*)(const T **a, const T **b)|. Low-level |sk_*|
// Note its actual type is |int (*)(const T **a, const T **b)|. Low-level |sk_*|
@ -104,14 +258,15 @@ typedef void *(*stack_copy_func)(void *ptr);
//
//
// TODO(davidben): This type should be |const T *const *|. It is already fixed
// TODO(davidben): This type should be |const T *const *|. It is already fixed
// in OpenSSL 1.1.1, so hopefully we can fix this compatibly.
// in OpenSSL 1.1.1, so hopefully we can fix this compatibly.
typedef int ( * stac k_cmp_func ) ( const void * * a , const void * * b ) ;
typedef int ( * OPENSSL_ sk_cmp_func) ( const void * * a , const void * * b ) ;
// The following function types call the above type-erased signatures with the
// The following function types call the above type-erased signatures with the
// true types.
// true types.
typedef void ( * stack_call_free_func ) ( stack_free_func , void * ) ;
typedef void ( * OPENSSL_sk_call_free_func ) ( OPENSSL_sk_free_func , void * ) ;
typedef void * ( * stack_call_copy_func ) ( stack_copy_func , void * ) ;
typedef void * ( * OPENSSL_sk_call_copy_func ) ( OPENSSL_sk_copy_func , void * ) ;
typedef int ( * stack_call_cmp_func ) ( stack_cmp_func , const void * const * ,
typedef int ( * OPENSSL_sk_call_cmp_func ) ( OPENSSL_sk_cmp_func ,
const void * const * ) ;
const void * const * ,
const void * const * ) ;
// stack_st contains an array of pointers. It is not designed to be used
// stack_st contains an array of pointers. It is not designed to be used
// directly, rather the wrapper macros should be used.
// directly, rather the wrapper macros should be used.
@ -126,134 +281,47 @@ typedef struct stack_st {
// to by |data|, which may be larger than |num|.
// to by |data|, which may be larger than |num|.
size_t num_alloc ;
size_t num_alloc ;
// comp is an optional comparison function.
// comp is an optional comparison function.
stac k_cmp_func comp ;
OPENSSL_ sk_cmp_func comp ;
} _STACK ;
} _STACK ;
// The following are raw stack functions. They implement the corresponding typed
# define STACK_OF(type) struct stack_st_##type
// |sk_SAMPLE_*| functions generated by |DEFINE_STACK_OF|. Callers shouldn't be
// using them. Rather, callers should use the typed functions.
# define DECLARE_STACK_OF(type) STACK_OF(type);
OPENSSL_EXPORT _STACK * sk_new ( OPENSSL_sk_cmp_func comp ) ;
// These are the raw stack functions, you shouldn't be using them. Rather you
// should be using the type stack macros implemented above.
// sk_new creates a new, empty stack with the given comparison function, which
// may be zero. It returns the new stack or NULL on allocation failure.
OPENSSL_EXPORT _STACK * sk_new ( stack_cmp_func comp ) ;
// sk_new_null creates a new, empty stack. It returns the new stack or NULL on
// allocation failure.
OPENSSL_EXPORT _STACK * sk_new_null ( void ) ;
OPENSSL_EXPORT _STACK * sk_new_null ( void ) ;
// sk_num returns the number of elements in |s|.
OPENSSL_EXPORT size_t sk_num ( const _STACK * sk ) ;
OPENSSL_EXPORT size_t sk_num ( const _STACK * sk ) ;
// sk_zero resets |sk| to the empty state but does nothing to free the
// individual elements themselves.
OPENSSL_EXPORT void sk_zero ( _STACK * sk ) ;
OPENSSL_EXPORT void sk_zero ( _STACK * sk ) ;
// sk_value returns the |i|th pointer in |sk|, or NULL if |i| is out of
// range.
OPENSSL_EXPORT void * sk_value ( const _STACK * sk , size_t i ) ;
OPENSSL_EXPORT void * sk_value ( const _STACK * sk , size_t i ) ;
// sk_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| is out
// of range, it returns NULL.
OPENSSL_EXPORT void * sk_set ( _STACK * sk , size_t i , void * p ) ;
OPENSSL_EXPORT void * sk_set ( _STACK * sk , size_t i , void * p ) ;
// sk_free frees the given stack and array of pointers, but does nothing to
// free the individual elements. Also see |sk_pop_free_ex|.
OPENSSL_EXPORT void sk_free ( _STACK * sk ) ;
OPENSSL_EXPORT void sk_free ( _STACK * sk ) ;
// sk_pop_free_ex calls |free_func| on each element in the stack and then frees
// the stack itself. Note this corresponds to |sk_FOO_pop_free|. It is named
// |sk_pop_free_ex| as a workaround for existing code calling an older version
// of |sk_pop_free|.
OPENSSL_EXPORT void sk_pop_free_ex ( _STACK * sk ,
OPENSSL_EXPORT void sk_pop_free_ex ( _STACK * sk ,
stack_call_free_func call_free_func ,
OPENSSL_sk_call_free_func call_free_func ,
stack_free_func free_func ) ;
OPENSSL_sk_free_func free_func ) ;
// sk_insert inserts |p| into the stack at index |where|, moving existing
// elements if needed. It returns the length of the new stack, or zero on
// error.
OPENSSL_EXPORT size_t sk_insert ( _STACK * sk , void * p , size_t where ) ;
OPENSSL_EXPORT size_t sk_insert ( _STACK * sk , void * p , size_t where ) ;
// sk_delete removes the pointer at index |where|, moving other elements down
// if needed. It returns the removed pointer, or NULL if |where| is out of
// range.
OPENSSL_EXPORT void * sk_delete ( _STACK * sk , size_t where ) ;
OPENSSL_EXPORT void * sk_delete ( _STACK * sk , size_t where ) ;
// sk_delete_ptr removes, at most, one instance of |p| from the stack based on
// pointer equality. If an instance of |p| is found then |p| is returned,
// otherwise it returns NULL.
OPENSSL_EXPORT void * sk_delete_ptr ( _STACK * sk , const void * p ) ;
OPENSSL_EXPORT void * sk_delete_ptr ( _STACK * sk , const void * p ) ;
// sk_find returns the first value in the stack equal to |p|. If a comparison
// function has been set on the stack, equality is defined by it, otherwise
// pointer equality is used. If the stack is sorted, then a binary search is
// used, otherwise a linear search is performed. If a matching element is found,
// its index is written to
// |*out_index| (if |out_index| is not NULL) and one is returned. Otherwise zero
// is returned.
//
// Note this differs from OpenSSL. The type signature is slightly different, and
// OpenSSL's sk_find will implicitly sort |sk| if it has a comparison function
// defined.
OPENSSL_EXPORT int sk_find ( const _STACK * sk , size_t * out_index , const void * p ,
OPENSSL_EXPORT int sk_find ( const _STACK * sk , size_t * out_index , const void * p ,
stack_call_cmp_func call_cmp_func ) ;
OPENSSL_sk_call_cmp_func call_cmp_func ) ;
// sk_shift removes and returns the first element in the stack, or returns NULL
// if the stack is empty.
OPENSSL_EXPORT void * sk_shift ( _STACK * sk ) ;
OPENSSL_EXPORT void * sk_shift ( _STACK * sk ) ;
// sk_push appends |p| to the stack and returns the length of the new stack, or
// 0 on allocation failure.
OPENSSL_EXPORT size_t sk_push ( _STACK * sk , void * p ) ;
OPENSSL_EXPORT size_t sk_push ( _STACK * sk , void * p ) ;
// sk_pop returns and removes the last element on the stack, or NULL if the
// stack is empty.
OPENSSL_EXPORT void * sk_pop ( _STACK * sk ) ;
OPENSSL_EXPORT void * sk_pop ( _STACK * sk ) ;
// sk_dup performs a shallow copy of a stack and returns the new stack, or NULL
// on error.
OPENSSL_EXPORT _STACK * sk_dup ( const _STACK * sk ) ;
OPENSSL_EXPORT _STACK * sk_dup ( const _STACK * sk ) ;
OPENSSL_EXPORT void sk_sort ( _STACK * sk , OPENSSL_sk_call_cmp_func call_cmp_func ) ;
// sk_sort sorts the elements of |sk| into ascending order based on the
// comparison function. The stack maintains a |sorted| flag and sorting an
// already sorted stack is a no-op.
OPENSSL_EXPORT void sk_sort ( _STACK * sk , stack_call_cmp_func call_cmp_func ) ;
// sk_is_sorted returns one if |sk| is known to be sorted and zero
// otherwise.
OPENSSL_EXPORT int sk_is_sorted ( const _STACK * sk ) ;
OPENSSL_EXPORT int sk_is_sorted ( const _STACK * sk ) ;
OPENSSL_EXPORT OPENSSL_sk_cmp_func sk_set_cmp_func ( _STACK * sk ,
// sk_set_cmp_func sets the comparison function to be used by |sk| and returns
OPENSSL_sk_cmp_func comp ) ;
// the previous one.
OPENSSL_EXPORT stack_cmp_func sk_set_cmp_func ( _STACK * sk , stack_cmp_func comp ) ;
// sk_deep_copy performs a copy of |sk| and of each of the non-NULL elements in
// |sk| by using |copy_func|. If an error occurs, |free_func| is used to free
// any copies already made and NULL is returned.
OPENSSL_EXPORT _STACK * sk_deep_copy ( const _STACK * sk ,
OPENSSL_EXPORT _STACK * sk_deep_copy ( const _STACK * sk ,
stack_call_copy_func call_copy_func ,
OPENSSL_sk_call_copy_func call_copy_func ,
stack_copy_func copy_func ,
OPENSSL_sk_copy_func copy_func ,
stack_call_free_func call_free_func ,
OPENSSL_sk_call_free_func call_free_func ,
stack_free_func free_func ) ;
OPENSSL_sk_free_func free_func ) ;
// Deprecated functions.
// sk_pop_free behaves like |sk_pop_free_ex| but performs an invalid function
// sk_pop_free behaves like |sk_pop_free_ex| but performs an invalid function
// pointer cast. It exists because some existing callers called |sk_pop_free|
// pointer cast. It exists because some existing callers called |sk_pop_free|
// directly.
// directly.
//
//
// TODO(davidben): Migrate callers to bssl::UniquePtr and remove this.
// TODO(davidben): Migrate callers to bssl::UniquePtr and remove this.
OPENSSL_EXPORT void sk_pop_free ( _STACK * sk , stack_free_func free_func ) ;
OPENSSL_EXPORT void sk_pop_free ( _STACK * sk , OPENSSL_sk_free_func free_func ) ;
// Defining stack types.
//
// This set of macros is used to emit the typed functions that act on a
// |STACK_OF(T)|.
# if !defined(BORINGSSL_NO_CXX)
# if !defined(BORINGSSL_NO_CXX)
extern " C++ " {
extern " C++ " {
@ -283,157 +351,144 @@ BSSL_NAMESPACE_END
# define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const)
# define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const)
# endif
# endif
# define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \
# define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \
/* We disable MSVC C4191 in this macro, which warns when pointers are cast \
/* We disable MSVC C4191 in this macro, which warns when pointers are cast \
* to the wrong type . While the cast itself is valid , it is often a bug \
* to the wrong type . While the cast itself is valid , it is often a bug \
* because calling it through the cast is UB . However , we never actually \
* because calling it through the cast is UB . However , we never actually \
* call functions as | stac k_cmp_func | . The type is just a type - erased \
* call functions as | OPENSSL_ sk_cmp_func| . The type is just a type - erased \
* function pointer . ( C does not guarantee function pointers fit in \
* function pointer . ( C does not guarantee function pointers fit in \
* | void * | , and GCC will warn on this . ) Thus we just disable the false \
* | void * | , and GCC will warn on this . ) Thus we just disable the false \
* positive warning . */ \
* positive warning . */ \
OPENSSL_MSVC_PRAGMA ( warning ( push ) ) \
OPENSSL_MSVC_PRAGMA ( warning ( push ) ) \
OPENSSL_MSVC_PRAGMA ( warning ( disable : 4191 ) ) \
OPENSSL_MSVC_PRAGMA ( warning ( disable : 4191 ) ) \
\
\
DECLARE_STACK_OF ( name ) \
DECLARE_STACK_OF ( name ) \
\
\
typedef void ( * stac k_ # # name # # _free_func ) ( ptrtype ) ; \
typedef void ( * sk_ # # name # # _free_func ) ( ptrtype ) ; \
typedef ptrtype ( * stac k_ # # name # # _copy_func ) ( ptrtype ) ; \
typedef ptrtype ( * sk_ # # name # # _copy_func ) ( ptrtype ) ; \
typedef int ( * stac k_ # # name # # _cmp_func ) ( constptrtype * a , constptrtype * b ) ; \
typedef int ( * sk_ # # name # # _cmp_func ) ( constptrtype * a , constptrtype * b ) ; \
\
\
OPENSSL_INLINE void sk_ # # name # # _call_free_func ( stack_free_func free_func , \
OPENSSL_INLINE void sk_ # # name # # _call_free_func ( \
void * ptr ) { \
OPENSSL_sk_free_func free_func , void * ptr ) { \
( ( stac k_ # # name # # _free_func ) free_func ) ( ( ptrtype ) ptr ) ; \
( ( sk_ # # name # # _free_func ) free_func ) ( ( ptrtype ) ptr ) ; \
} \
} \
\
\
OPENSSL_INLINE void * sk_ # # name # # _call_copy_func ( stack_copy_func copy_func , \
OPENSSL_INLINE void * sk_ # # name # # _call_copy_func ( \
void * ptr ) { \
OPENSSL_sk_copy_func copy_func , void * ptr ) { \
return ( void * ) ( ( stac k_ # # name # # _copy_func ) copy_func ) ( ( ptrtype ) ptr ) ; \
return ( void * ) ( ( sk_ # # name # # _copy_func ) copy_func ) ( ( ptrtype ) ptr ) ; \
} \
} \
\
\
OPENSSL_INLINE int sk_ # # name # # _call_cmp_func ( \
OPENSSL_INLINE int sk_ # # name # # _call_cmp_func ( OPENSSL_sk_cmp_func cmp_func , \
stack_cmp_func cmp_func , const void * const * a , const void * const * b ) { \
const void * const * a , \
/* The data is actually stored as |void*| pointers, so read the pointer \
const void * const * b ) { \
* as | void * | and then pass the corrected type into the caller - supplied \
/* The data is actually stored as |void*| pointers, so read the pointer \
* function , which expects | constptrtype * | . */ \
* as | void * | and then pass the corrected type into the caller - supplied \
constptrtype a_ptr = ( constptrtype ) * a ; \
* function , which expects | constptrtype * | . */ \
constptrtype b _ptr = ( constptrtype ) * b ; \
constptrtype a _ptr = ( constptrtype ) * a ; \
return ( ( stack_ # # name # # _cmp_func ) cmp_func ) ( & a_ptr , & b_ptr ) ; \
constptrtype b_ptr = ( constptrtype ) * b ; \
} \
return ( ( sk_ # # name # # _cmp_func ) cmp_func ) ( & a_ptr , & b_ptr ) ; \
\
} \
OPENSSL_INLINE STACK_OF ( name ) * sk_ # # name # # _new ( \
\
stac k_ # # name # # _cmp_func comp ) { \
OPENSSL_INLINE STACK_OF ( name ) * sk_ # # name # # _new ( s k_# # name # # _cmp_func comp ) { \
return ( STACK_OF ( name ) * ) sk_new ( ( stac k_cmp_func ) comp ) ; \
return ( STACK_OF ( name ) * ) sk_new ( ( OPENSSL_ sk_cmp_func) comp ) ; \
} \
} \
\
\
OPENSSL_INLINE STACK_OF ( name ) * sk_ # # name # # _new_null ( void ) { \
OPENSSL_INLINE STACK_OF ( name ) * sk_ # # name # # _new_null ( void ) { \
return ( STACK_OF ( name ) * ) sk_new_null ( ) ; \
return ( STACK_OF ( name ) * ) sk_new_null ( ) ; \
} \
} \
\
\
OPENSSL_INLINE size_t sk_ # # name # # _num ( const STACK_OF ( name ) * sk ) { \
OPENSSL_INLINE size_t sk_ # # name # # _num ( const STACK_OF ( name ) * sk ) { \
return sk_num ( ( const _STACK * ) sk ) ; \
return sk_num ( ( const _STACK * ) sk ) ; \
} \
} \
\
\
OPENSSL_INLINE void sk_ # # name # # _zero ( STACK_OF ( name ) * sk ) { \
OPENSSL_INLINE void sk_ # # name # # _zero ( STACK_OF ( name ) * sk ) { \
sk_zero ( ( _STACK * ) sk ) ; \
sk_zero ( ( _STACK * ) sk ) ; \
} \
} \
\
\
OPENSSL_INLINE ptrtype sk_ # # name # # _value ( const STACK_OF ( name ) * sk , \
OPENSSL_INLINE ptrtype sk_ # # name # # _value ( const STACK_OF ( name ) * sk , \
size_t i ) { \
size_t i ) { \
return ( ptrtype ) sk_value ( ( const _STACK * ) sk , i ) ; \
return ( ptrtype ) sk_value ( ( const _STACK * ) sk , i ) ; \
} \
} \
\
\
OPENSSL_INLINE ptrtype sk_ # # name # # _set ( STACK_OF ( name ) * sk , size_t i , \
OPENSSL_INLINE ptrtype sk_ # # name # # _set ( STACK_OF ( name ) * sk , size_t i , \
ptrtype p ) { \
ptrtype p ) { \
return ( ptrtype ) sk_set ( ( _STACK * ) sk , i , ( void * ) p ) ; \
return ( ptrtype ) sk_set ( ( _STACK * ) sk , i , ( void * ) p ) ; \
} \
} \
\
\
OPENSSL_INLINE void sk_ # # name # # _free ( STACK_OF ( name ) * sk ) { \
OPENSSL_INLINE void sk_ # # name # # _free ( STACK_OF ( name ) * sk ) { \
sk_free ( ( _STACK * ) sk ) ; \
sk_free ( ( _STACK * ) sk ) ; \
} \
} \
\
\
OPENSSL_INLINE void sk_ # # name # # _pop_free ( \
OPENSSL_INLINE void sk_ # # name # # _pop_free ( STACK_OF ( name ) * sk , \
STACK_OF ( name ) * sk , stac k_# # name # # _free_func free_func ) { \
s k_ # # name # # _free_func free_func ) { \
sk_pop_free_ex ( ( _STACK * ) sk , sk_ # # name # # _call_free_func , \
sk_pop_free_ex ( ( _STACK * ) sk , sk_ # # name # # _call_free_func , \
( stac k_free_func ) free_func ) ; \
( OPENSSL_ sk_free_func) free_func ) ; \
} \
} \
\
\
OPENSSL_INLINE size_t sk_ # # name # # _insert ( STACK_OF ( name ) * sk , ptrtype p , \
OPENSSL_INLINE size_t sk_ # # name # # _insert ( STACK_OF ( name ) * sk , ptrtype p , \
size_t where ) { \
size_t where ) { \
return sk_insert ( ( _STACK * ) sk , ( void * ) p , where ) ; \
return sk_insert ( ( _STACK * ) sk , ( void * ) p , where ) ; \
} \
} \
\
\
OPENSSL_INLINE ptrtype sk_ # # name # # _delete ( STACK_OF ( name ) * sk , \
OPENSSL_INLINE ptrtype sk_ # # name # # _delete ( STACK_OF ( name ) * sk , \
size_t where ) { \
size_t where ) { \
return ( ptrtype ) sk_delete ( ( _STACK * ) sk , where ) ; \
return ( ptrtype ) sk_delete ( ( _STACK * ) sk , where ) ; \
} \
} \
\
\
OPENSSL_INLINE ptrtype sk_ # # name # # _delete_ptr ( STACK_OF ( name ) * sk , \
OPENSSL_INLINE ptrtype sk_ # # name # # _delete_ptr ( STACK_OF ( name ) * sk , \
constptrtype p ) { \
constptrtype p ) { \
return ( ptrtype ) sk_delete_ptr ( ( _STACK * ) sk , ( const void * ) p ) ; \
return ( ptrtype ) sk_delete_ptr ( ( _STACK * ) sk , ( const void * ) p ) ; \
} \
} \
\
\
OPENSSL_INLINE int sk_ # # name # # _find ( const STACK_OF ( name ) * sk , \
OPENSSL_INLINE int sk_ # # name # # _find ( const STACK_OF ( name ) * sk , \
size_t * out_index , constptrtype p ) { \
size_t * out_index , constptrtype p ) { \
return sk_find ( ( const _STACK * ) sk , out_index , ( const void * ) p , \
return sk_find ( ( const _STACK * ) sk , out_index , ( const void * ) p , \
sk_ # # name # # _call_cmp_func ) ; \
sk_ # # name # # _call_cmp_func ) ; \
} \
} \
\
\
OPENSSL_INLINE ptrtype sk_ # # name # # _shift ( STACK_OF ( name ) * sk ) { \
OPENSSL_INLINE ptrtype sk_ # # name # # _shift ( STACK_OF ( name ) * sk ) { \
return ( ptrtype ) sk_shift ( ( _STACK * ) sk ) ; \
return ( ptrtype ) sk_shift ( ( _STACK * ) sk ) ; \
} \
} \
\
\
OPENSSL_INLINE size_t sk_ # # name # # _push ( STACK_OF ( name ) * sk , ptrtype p ) { \
OPENSSL_INLINE size_t sk_ # # name # # _push ( STACK_OF ( name ) * sk , ptrtype p ) { \
return sk_push ( ( _STACK * ) sk , ( void * ) p ) ; \
return sk_push ( ( _STACK * ) sk , ( void * ) p ) ; \
} \
} \
\
\
OPENSSL_INLINE ptrtype sk_ # # name # # _pop ( STACK_OF ( name ) * sk ) { \
OPENSSL_INLINE ptrtype sk_ # # name # # _pop ( STACK_OF ( name ) * sk ) { \
return ( ptrtype ) sk_pop ( ( _STACK * ) sk ) ; \
return ( ptrtype ) sk_pop ( ( _STACK * ) sk ) ; \
} \
} \
\
\
OPENSSL_INLINE STACK_OF ( name ) * sk_ # # name # # _dup ( const STACK_OF ( name ) * sk ) { \
OPENSSL_INLINE STACK_OF ( name ) * sk_ # # name # # _dup ( const STACK_OF ( name ) * sk ) { \
return ( STACK_OF ( name ) * ) sk_dup ( ( const _STACK * ) sk ) ; \
return ( STACK_OF ( name ) * ) sk_dup ( ( const _STACK * ) sk ) ; \
} \
} \
\
\
OPENSSL_INLINE void sk_ # # name # # _sort ( STACK_OF ( name ) * sk ) { \
OPENSSL_INLINE void sk_ # # name # # _sort ( STACK_OF ( name ) * sk ) { \
sk_sort ( ( _STACK * ) sk , sk_ # # name # # _call_cmp_func ) ; \
sk_sort ( ( _STACK * ) sk , sk_ # # name # # _call_cmp_func ) ; \
} \
} \
\
\
OPENSSL_INLINE int sk_ # # name # # _is_sorted ( const STACK_OF ( name ) * sk ) { \
OPENSSL_INLINE int sk_ # # name # # _is_sorted ( const STACK_OF ( name ) * sk ) { \
return sk_is_sorted ( ( const _STACK * ) sk ) ; \
return sk_is_sorted ( ( const _STACK * ) sk ) ; \
} \
} \
\
\
OPENSSL_INLINE stac k_ # # name # # _cmp_func sk_ # # name # # _set_cmp_func ( \
OPENSSL_INLINE sk_ # # name # # _cmp_func sk_ # # name # # _set_cmp_func ( \
STACK_OF ( name ) * sk , stac k_ # # name # # _cmp_func comp ) { \
STACK_OF ( name ) * sk , sk_ # # name # # _cmp_func comp ) { \
return ( stac k_ # # name # # _cmp_func ) sk_set_cmp_func ( ( _STACK * ) sk , \
return ( sk_ # # name # # _cmp_func ) sk_set_cmp_func ( ( _STACK * ) sk , \
( stac k_cmp_func ) comp ) ; \
( OPENSSL_ sk_cmp_func) comp ) ; \
} \
} \
\
\
OPENSSL_INLINE STACK_OF ( name ) * sk_ # # name # # _deep_copy ( \
OPENSSL_INLINE STACK_OF ( name ) * sk_ # # name # # _deep_copy ( \
const STACK_OF ( name ) * sk , ptrtype ( * copy_func ) ( ptrtype ) , \
const STACK_OF ( name ) * sk , sk_ # # name # # _copy_func copy_func , \
void ( * free_func ) ( ptrtype ) ) { \
sk_ # # name # # _free_func free_func ) { \
return ( STACK_OF ( name ) * ) sk_deep_copy ( \
return ( STACK_OF ( name ) * ) sk_deep_copy ( \
( const _STACK * ) sk , sk_ # # name # # _call_copy_func , \
( const _STACK * ) sk , sk_ # # name # # _call_copy_func , \
( stac k_copy_func ) copy_func , sk_ # # name # # _call_free_func , \
( OPENSSL_ sk_copy_func) copy_func , sk_ # # name # # _call_free_func , \
( stac k_free_func ) free_func ) ; \
( OPENSSL_ sk_free_func) free_func ) ; \
} \
} \
\
\
OPENSSL_MSVC_PRAGMA ( warning ( pop ) )
OPENSSL_MSVC_PRAGMA ( warning ( pop ) )
// DEFINE_NAMED_STACK_OF defines |STACK_OF(name)| to be a stack whose elements
// are |type| *.
# define DEFINE_NAMED_STACK_OF(name, type) \
BORINGSSL_DEFINE_STACK_OF_IMPL ( name , type * , const type * ) \
BORINGSSL_DEFINE_STACK_TRAITS ( name , type , false )
// DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are
// |type| *.
# define DEFINE_STACK_OF(type) DEFINE_NAMED_STACK_OF(type, type)
// DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements
// Built-in stacks.
// are const |type| *.
# define DEFINE_CONST_STACK_OF(type) \
BORINGSSL_DEFINE_STACK_OF_IMPL ( type , const type * , const type * ) \
BORINGSSL_DEFINE_STACK_TRAITS ( type , const type , true )
typedef char * OPENSSL_STRING ;
typedef char * OPENSSL_STRING ;
@ -469,7 +524,7 @@ struct DeleterImpl<Stack, std::enable_if_t<!StackTraits<Stack>::kIsConst>> {
// access it from C++ here.
// access it from C++ here.
using Type = typename StackTraits < Stack > : : Type ;
using Type = typename StackTraits < Stack > : : Type ;
sk_pop_free_ex ( reinterpret_cast < _STACK * > ( sk ) ,
sk_pop_free_ex ( reinterpret_cast < _STACK * > ( sk ) ,
[ ] ( stac k_free_func /* unused */ , void * ptr ) {
[ ] ( OPENSSL_ sk_free_func /* unused */ , void * ptr ) {
DeleterImpl < Type > : : Free ( reinterpret_cast < Type * > ( ptr ) ) ;
DeleterImpl < Type > : : Free ( reinterpret_cast < Type * > ( ptr ) ) ;
} ,
} ,
nullptr ) ;
nullptr ) ;