jpayne@69: /* jpayne@69: * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. jpayne@69: * jpayne@69: * Licensed under the OpenSSL license (the "License"). You may not use jpayne@69: * this file except in compliance with the License. You can obtain a copy jpayne@69: * in the file LICENSE in the source distribution or at jpayne@69: * https://www.openssl.org/source/license.html jpayne@69: */ jpayne@69: jpayne@69: /* jpayne@69: * Header for dynamic hash table routines Author - Eric Young jpayne@69: */ jpayne@69: jpayne@69: #ifndef HEADER_LHASH_H jpayne@69: # define HEADER_LHASH_H jpayne@69: jpayne@69: # include jpayne@69: # include jpayne@69: jpayne@69: #ifdef __cplusplus jpayne@69: extern "C" { jpayne@69: #endif jpayne@69: jpayne@69: typedef struct lhash_node_st OPENSSL_LH_NODE; jpayne@69: typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *); jpayne@69: typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *); jpayne@69: typedef void (*OPENSSL_LH_DOALL_FUNC) (void *); jpayne@69: typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *); jpayne@69: typedef struct lhash_st OPENSSL_LHASH; jpayne@69: jpayne@69: /* jpayne@69: * Macros for declaring and implementing type-safe wrappers for LHASH jpayne@69: * callbacks. This way, callbacks can be provided to LHASH structures without jpayne@69: * function pointer casting and the macro-defined callbacks provide jpayne@69: * per-variable casting before deferring to the underlying type-specific jpayne@69: * callbacks. NB: It is possible to place a "static" in front of both the jpayne@69: * DECLARE and IMPLEMENT macros if the functions are strictly internal. jpayne@69: */ jpayne@69: jpayne@69: /* First: "hash" functions */ jpayne@69: # define DECLARE_LHASH_HASH_FN(name, o_type) \ jpayne@69: unsigned long name##_LHASH_HASH(const void *); jpayne@69: # define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ jpayne@69: unsigned long name##_LHASH_HASH(const void *arg) { \ jpayne@69: const o_type *a = arg; \ jpayne@69: return name##_hash(a); } jpayne@69: # define LHASH_HASH_FN(name) name##_LHASH_HASH jpayne@69: jpayne@69: /* Second: "compare" functions */ jpayne@69: # define DECLARE_LHASH_COMP_FN(name, o_type) \ jpayne@69: int name##_LHASH_COMP(const void *, const void *); jpayne@69: # define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ jpayne@69: int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ jpayne@69: const o_type *a = arg1; \ jpayne@69: const o_type *b = arg2; \ jpayne@69: return name##_cmp(a,b); } jpayne@69: # define LHASH_COMP_FN(name) name##_LHASH_COMP jpayne@69: jpayne@69: /* Fourth: "doall_arg" functions */ jpayne@69: # define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ jpayne@69: void name##_LHASH_DOALL_ARG(void *, void *); jpayne@69: # define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ jpayne@69: void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ jpayne@69: o_type *a = arg1; \ jpayne@69: a_type *b = arg2; \ jpayne@69: name##_doall_arg(a, b); } jpayne@69: # define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG jpayne@69: jpayne@69: jpayne@69: # define LH_LOAD_MULT 256 jpayne@69: jpayne@69: int OPENSSL_LH_error(OPENSSL_LHASH *lh); jpayne@69: OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c); jpayne@69: void OPENSSL_LH_free(OPENSSL_LHASH *lh); jpayne@69: void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data); jpayne@69: void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data); jpayne@69: void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data); jpayne@69: void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func); jpayne@69: void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg); jpayne@69: unsigned long OPENSSL_LH_strhash(const char *c); jpayne@69: unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh); jpayne@69: unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh); jpayne@69: void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load); jpayne@69: jpayne@69: # ifndef OPENSSL_NO_STDIO jpayne@69: void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp); jpayne@69: void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp); jpayne@69: void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp); jpayne@69: # endif jpayne@69: void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out); jpayne@69: void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out); jpayne@69: void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out); jpayne@69: jpayne@69: # if OPENSSL_API_COMPAT < 0x10100000L jpayne@69: # define _LHASH OPENSSL_LHASH jpayne@69: # define LHASH_NODE OPENSSL_LH_NODE jpayne@69: # define lh_error OPENSSL_LH_error jpayne@69: # define lh_new OPENSSL_LH_new jpayne@69: # define lh_free OPENSSL_LH_free jpayne@69: # define lh_insert OPENSSL_LH_insert jpayne@69: # define lh_delete OPENSSL_LH_delete jpayne@69: # define lh_retrieve OPENSSL_LH_retrieve jpayne@69: # define lh_doall OPENSSL_LH_doall jpayne@69: # define lh_doall_arg OPENSSL_LH_doall_arg jpayne@69: # define lh_strhash OPENSSL_LH_strhash jpayne@69: # define lh_num_items OPENSSL_LH_num_items jpayne@69: # ifndef OPENSSL_NO_STDIO jpayne@69: # define lh_stats OPENSSL_LH_stats jpayne@69: # define lh_node_stats OPENSSL_LH_node_stats jpayne@69: # define lh_node_usage_stats OPENSSL_LH_node_usage_stats jpayne@69: # endif jpayne@69: # define lh_stats_bio OPENSSL_LH_stats_bio jpayne@69: # define lh_node_stats_bio OPENSSL_LH_node_stats_bio jpayne@69: # define lh_node_usage_stats_bio OPENSSL_LH_node_usage_stats_bio jpayne@69: # endif jpayne@69: jpayne@69: /* Type checking... */ jpayne@69: jpayne@69: # define LHASH_OF(type) struct lhash_st_##type jpayne@69: jpayne@69: # define DEFINE_LHASH_OF(type) \ jpayne@69: LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ jpayne@69: static ossl_unused ossl_inline LHASH_OF(type) *lh_##type##_new(unsigned long (*hfn)(const type *), \ jpayne@69: int (*cfn)(const type *, const type *)) \ jpayne@69: { \ jpayne@69: return (LHASH_OF(type) *) \ jpayne@69: OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ jpayne@69: { \ jpayne@69: OPENSSL_LH_free((OPENSSL_LHASH *)lh); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ jpayne@69: { \ jpayne@69: return (type *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ jpayne@69: { \ jpayne@69: return (type *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ jpayne@69: { \ jpayne@69: return (type *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ jpayne@69: { \ jpayne@69: return OPENSSL_LH_error((OPENSSL_LHASH *)lh); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ jpayne@69: { \ jpayne@69: return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ jpayne@69: { \ jpayne@69: OPENSSL_LH_node_stats_bio((const OPENSSL_LHASH *)lh, out); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ jpayne@69: { \ jpayne@69: OPENSSL_LH_node_usage_stats_bio((const OPENSSL_LHASH *)lh, out); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ jpayne@69: { \ jpayne@69: OPENSSL_LH_stats_bio((const OPENSSL_LHASH *)lh, out); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ jpayne@69: { \ jpayne@69: return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ jpayne@69: { \ jpayne@69: OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \ jpayne@69: } \ jpayne@69: static ossl_unused ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ jpayne@69: void (*doall)(type *)) \ jpayne@69: { \ jpayne@69: OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \ jpayne@69: } \ jpayne@69: LHASH_OF(type) jpayne@69: jpayne@69: #define IMPLEMENT_LHASH_DOALL_ARG_CONST(type, argtype) \ jpayne@69: int_implement_lhash_doall(type, argtype, const type) jpayne@69: jpayne@69: #define IMPLEMENT_LHASH_DOALL_ARG(type, argtype) \ jpayne@69: int_implement_lhash_doall(type, argtype, type) jpayne@69: jpayne@69: #define int_implement_lhash_doall(type, argtype, cbargtype) \ jpayne@69: static ossl_unused ossl_inline void \ jpayne@69: lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \ jpayne@69: void (*fn)(cbargtype *, argtype *), \ jpayne@69: argtype *arg) \ jpayne@69: { \ jpayne@69: OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \ jpayne@69: } \ jpayne@69: LHASH_OF(type) jpayne@69: jpayne@69: DEFINE_LHASH_OF(OPENSSL_STRING); jpayne@69: # ifdef _MSC_VER jpayne@69: /* jpayne@69: * push and pop this warning: jpayne@69: * warning C4090: 'function': different 'const' qualifiers jpayne@69: */ jpayne@69: # pragma warning (push) jpayne@69: # pragma warning (disable: 4090) jpayne@69: # endif jpayne@69: jpayne@69: DEFINE_LHASH_OF(OPENSSL_CSTRING); jpayne@69: jpayne@69: # ifdef _MSC_VER jpayne@69: # pragma warning (pop) jpayne@69: # endif jpayne@69: jpayne@69: /* jpayne@69: * If called without higher optimization (min. -xO3) the Oracle Developer jpayne@69: * Studio compiler generates code for the defined (static inline) functions jpayne@69: * above. jpayne@69: * This would later lead to the linker complaining about missing symbols when jpayne@69: * this header file is included but the resulting object is not linked against jpayne@69: * the Crypto library (openssl#6912). jpayne@69: */ jpayne@69: # ifdef __SUNPRO_C jpayne@69: # pragma weak OPENSSL_LH_new jpayne@69: # pragma weak OPENSSL_LH_free jpayne@69: # pragma weak OPENSSL_LH_insert jpayne@69: # pragma weak OPENSSL_LH_delete jpayne@69: # pragma weak OPENSSL_LH_retrieve jpayne@69: # pragma weak OPENSSL_LH_error jpayne@69: # pragma weak OPENSSL_LH_num_items jpayne@69: # pragma weak OPENSSL_LH_node_stats_bio jpayne@69: # pragma weak OPENSSL_LH_node_usage_stats_bio jpayne@69: # pragma weak OPENSSL_LH_stats_bio jpayne@69: # pragma weak OPENSSL_LH_get_down_load jpayne@69: # pragma weak OPENSSL_LH_set_down_load jpayne@69: # pragma weak OPENSSL_LH_doall jpayne@69: # pragma weak OPENSSL_LH_doall_arg jpayne@69: # endif /* __SUNPRO_C */ jpayne@69: jpayne@69: #ifdef __cplusplus jpayne@69: } jpayne@69: #endif jpayne@69: jpayne@69: #endif