1/* 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10{- 11use OpenSSL::stackhash qw(generate_lhash_macros); 12-} 13 14/* 15 * Header for dynamic hash table routines Author - Eric Young 16 */ 17 18#ifndef OPENSSL_LHASH_H 19# define OPENSSL_LHASH_H 20# pragma once 21 22# include <openssl/macros.h> 23# ifndef OPENSSL_NO_DEPRECATED_3_0 24# define HEADER_LHASH_H 25# endif 26 27# include <openssl/e_os2.h> 28# include <openssl/bio.h> 29 30#ifdef __cplusplus 31extern "C" { 32#endif 33 34typedef struct lhash_node_st OPENSSL_LH_NODE; 35typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *); 36typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *); 37typedef void (*OPENSSL_LH_DOALL_FUNC) (void *); 38typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *); 39typedef struct lhash_st OPENSSL_LHASH; 40 41/* 42 * Macros for declaring and implementing type-safe wrappers for LHASH 43 * callbacks. This way, callbacks can be provided to LHASH structures without 44 * function pointer casting and the macro-defined callbacks provide 45 * per-variable casting before deferring to the underlying type-specific 46 * callbacks. NB: It is possible to place a "static" in front of both the 47 * DECLARE and IMPLEMENT macros if the functions are strictly internal. 48 */ 49 50/* First: "hash" functions */ 51# define DECLARE_LHASH_HASH_FN(name, o_type) \ 52 unsigned long name##_LHASH_HASH(const void *); 53# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ 54 unsigned long name##_LHASH_HASH(const void *arg) { \ 55 const o_type *a = arg; \ 56 return name##_hash(a); } 57# define LHASH_HASH_FN(name) name##_LHASH_HASH 58 59/* Second: "compare" functions */ 60# define DECLARE_LHASH_COMP_FN(name, o_type) \ 61 int name##_LHASH_COMP(const void *, const void *); 62# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ 63 int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ 64 const o_type *a = arg1; \ 65 const o_type *b = arg2; \ 66 return name##_cmp(a,b); } 67# define LHASH_COMP_FN(name) name##_LHASH_COMP 68 69/* Fourth: "doall_arg" functions */ 70# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ 71 void name##_LHASH_DOALL_ARG(void *, void *); 72# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ 73 void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ 74 o_type *a = arg1; \ 75 a_type *b = arg2; \ 76 name##_doall_arg(a, b); } 77# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG 78 79 80# define LH_LOAD_MULT 256 81 82int OPENSSL_LH_error(OPENSSL_LHASH *lh); 83OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c); 84void OPENSSL_LH_free(OPENSSL_LHASH *lh); 85void OPENSSL_LH_flush(OPENSSL_LHASH *lh); 86void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data); 87void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data); 88void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data); 89void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func); 90void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg); 91unsigned long OPENSSL_LH_strhash(const char *c); 92unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh); 93unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh); 94void OPENSSL_LH_set_down_load(OPENSSL_LHASH *lh, unsigned long down_load); 95 96# ifndef OPENSSL_NO_STDIO 97void OPENSSL_LH_stats(const OPENSSL_LHASH *lh, FILE *fp); 98void OPENSSL_LH_node_stats(const OPENSSL_LHASH *lh, FILE *fp); 99void OPENSSL_LH_node_usage_stats(const OPENSSL_LHASH *lh, FILE *fp); 100# endif 101void OPENSSL_LH_stats_bio(const OPENSSL_LHASH *lh, BIO *out); 102void OPENSSL_LH_node_stats_bio(const OPENSSL_LHASH *lh, BIO *out); 103void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out); 104 105# ifndef OPENSSL_NO_DEPRECATED_1_1_0 106# define _LHASH OPENSSL_LHASH 107# define LHASH_NODE OPENSSL_LH_NODE 108# define lh_error OPENSSL_LH_error 109# define lh_new OPENSSL_LH_new 110# define lh_free OPENSSL_LH_free 111# define lh_insert OPENSSL_LH_insert 112# define lh_delete OPENSSL_LH_delete 113# define lh_retrieve OPENSSL_LH_retrieve 114# define lh_doall OPENSSL_LH_doall 115# define lh_doall_arg OPENSSL_LH_doall_arg 116# define lh_strhash OPENSSL_LH_strhash 117# define lh_num_items OPENSSL_LH_num_items 118# ifndef OPENSSL_NO_STDIO 119# define lh_stats OPENSSL_LH_stats 120# define lh_node_stats OPENSSL_LH_node_stats 121# define lh_node_usage_stats OPENSSL_LH_node_usage_stats 122# endif 123# define lh_stats_bio OPENSSL_LH_stats_bio 124# define lh_node_stats_bio OPENSSL_LH_node_stats_bio 125# define lh_node_usage_stats_bio OPENSSL_LH_node_usage_stats_bio 126# endif 127 128/* Type checking... */ 129 130# define LHASH_OF(type) struct lhash_st_##type 131 132/* Helper macro for internal use */ 133# define DEFINE_LHASH_OF_INTERNAL(type) \ 134 LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ 135 typedef int (*lh_##type##_compfunc)(const type *a, const type *b); \ 136 typedef unsigned long (*lh_##type##_hashfunc)(const type *a); \ 137 typedef void (*lh_##type##_doallfunc)(type *a); \ 138 static ossl_unused ossl_inline type *ossl_check_##type##_lh_plain_type(type *ptr) \ 139 { \ 140 return ptr; \ 141 } \ 142 static ossl_unused ossl_inline const type *ossl_check_const_##type##_lh_plain_type(const type *ptr) \ 143 { \ 144 return ptr; \ 145 } \ 146 static ossl_unused ossl_inline const OPENSSL_LHASH *ossl_check_const_##type##_lh_type(const LHASH_OF(type) *lh) \ 147 { \ 148 return (const OPENSSL_LHASH *)lh; \ 149 } \ 150 static ossl_unused ossl_inline OPENSSL_LHASH *ossl_check_##type##_lh_type(LHASH_OF(type) *lh) \ 151 { \ 152 return (OPENSSL_LHASH *)lh; \ 153 } \ 154 static ossl_unused ossl_inline OPENSSL_LH_COMPFUNC ossl_check_##type##_lh_compfunc_type(lh_##type##_compfunc cmp) \ 155 { \ 156 return (OPENSSL_LH_COMPFUNC)cmp; \ 157 } \ 158 static ossl_unused ossl_inline OPENSSL_LH_HASHFUNC ossl_check_##type##_lh_hashfunc_type(lh_##type##_hashfunc hfn) \ 159 { \ 160 return (OPENSSL_LH_HASHFUNC)hfn; \ 161 } \ 162 static ossl_unused ossl_inline OPENSSL_LH_DOALL_FUNC ossl_check_##type##_lh_doallfunc_type(lh_##type##_doallfunc dfn) \ 163 { \ 164 return (OPENSSL_LH_DOALL_FUNC)dfn; \ 165 } \ 166 LHASH_OF(type) 167 168# define DEFINE_LHASH_OF(type) \ 169 LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ 170 static ossl_unused ossl_inline LHASH_OF(type) *lh_##type##_new(unsigned long (*hfn)(const type *), \ 171 int (*cfn)(const type *, const type *)) \ 172 { \ 173 return (LHASH_OF(type) *) \ 174 OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \ 175 } \ 176 static ossl_unused ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ 177 { \ 178 OPENSSL_LH_free((OPENSSL_LHASH *)lh); \ 179 } \ 180 static ossl_unused ossl_inline void lh_##type##_flush(LHASH_OF(type) *lh) \ 181 { \ 182 OPENSSL_LH_flush((OPENSSL_LHASH *)lh); \ 183 } \ 184 static ossl_unused ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ 185 { \ 186 return (type *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d); \ 187 } \ 188 static ossl_unused ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ 189 { \ 190 return (type *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d); \ 191 } \ 192 static ossl_unused ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ 193 { \ 194 return (type *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d); \ 195 } \ 196 static ossl_unused ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ 197 { \ 198 return OPENSSL_LH_error((OPENSSL_LHASH *)lh); \ 199 } \ 200 static ossl_unused ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ 201 { \ 202 return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh); \ 203 } \ 204 static ossl_unused ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ 205 { \ 206 OPENSSL_LH_node_stats_bio((const OPENSSL_LHASH *)lh, out); \ 207 } \ 208 static ossl_unused ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ 209 { \ 210 OPENSSL_LH_node_usage_stats_bio((const OPENSSL_LHASH *)lh, out); \ 211 } \ 212 static ossl_unused ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ 213 { \ 214 OPENSSL_LH_stats_bio((const OPENSSL_LHASH *)lh, out); \ 215 } \ 216 static ossl_unused ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ 217 { \ 218 return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh); \ 219 } \ 220 static ossl_unused ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ 221 { \ 222 OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \ 223 } \ 224 static ossl_unused ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ 225 void (*doall)(type *)) \ 226 { \ 227 OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \ 228 } \ 229 static ossl_unused ossl_inline void lh_##type##_doall_arg(LHASH_OF(type) *lh, \ 230 void (*doallarg)(type *, void *), \ 231 void *arg) \ 232 { \ 233 OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, \ 234 (OPENSSL_LH_DOALL_FUNCARG)doallarg, arg); \ 235 } \ 236 LHASH_OF(type) 237 238#define IMPLEMENT_LHASH_DOALL_ARG_CONST(type, argtype) \ 239 int_implement_lhash_doall(type, argtype, const type) 240 241#define IMPLEMENT_LHASH_DOALL_ARG(type, argtype) \ 242 int_implement_lhash_doall(type, argtype, type) 243 244#define int_implement_lhash_doall(type, argtype, cbargtype) \ 245 static ossl_unused ossl_inline void \ 246 lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \ 247 void (*fn)(cbargtype *, argtype *), \ 248 argtype *arg) \ 249 { \ 250 OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \ 251 } \ 252 LHASH_OF(type) 253 254{- 255 generate_lhash_macros("OPENSSL_STRING") 256 .generate_lhash_macros("OPENSSL_CSTRING"); 257-} 258 259#ifdef __cplusplus 260} 261#endif 262 263#endif 264