]>
Commit | Line | Data |
---|---|---|
21dcbebc RS |
1 | /* |
2 | * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. | |
0f113f3e | 3 | * |
21dcbebc RS |
4 | * Licensed under the OpenSSL license (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 | |
d02b48c6 RE |
8 | */ |
9 | ||
0f113f3e MC |
10 | /* |
11 | * Header for dynamic hash table routines Author - Eric Young | |
d02b48c6 RE |
12 | */ |
13 | ||
14 | #ifndef HEADER_LHASH_H | |
0f113f3e | 15 | # define HEADER_LHASH_H |
d02b48c6 | 16 | |
0f113f3e | 17 | # include <openssl/e_os2.h> |
a00ae6c4 | 18 | # include <openssl/bio.h> |
ef33b970 | 19 | |
82271cee RL |
20 | #ifdef __cplusplus |
21 | extern "C" { | |
22 | #endif | |
23 | ||
0f113f3e MC |
24 | typedef struct lhash_node_st { |
25 | void *data; | |
26 | struct lhash_node_st *next; | |
0f113f3e | 27 | unsigned long hash; |
0f113f3e MC |
28 | } LHASH_NODE; |
29 | ||
30 | typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *); | |
31 | typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *); | |
32 | typedef void (*LHASH_DOALL_FN_TYPE) (void *); | |
33 | typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *); | |
34 | ||
35 | /* | |
36 | * Macros for declaring and implementing type-safe wrappers for LHASH | |
37 | * callbacks. This way, callbacks can be provided to LHASH structures without | |
38 | * function pointer casting and the macro-defined callbacks provide | |
39 | * per-variable casting before deferring to the underlying type-specific | |
40 | * callbacks. NB: It is possible to place a "static" in front of both the | |
41 | * DECLARE and IMPLEMENT macros if the functions are strictly internal. | |
42 | */ | |
dfa46e50 GT |
43 | |
44 | /* First: "hash" functions */ | |
0f113f3e MC |
45 | # define DECLARE_LHASH_HASH_FN(name, o_type) \ |
46 | unsigned long name##_LHASH_HASH(const void *); | |
47 | # define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ | |
48 | unsigned long name##_LHASH_HASH(const void *arg) { \ | |
49 | const o_type *a = arg; \ | |
50 | return name##_hash(a); } | |
51 | # define LHASH_HASH_FN(name) name##_LHASH_HASH | |
dfa46e50 GT |
52 | |
53 | /* Second: "compare" functions */ | |
0f113f3e MC |
54 | # define DECLARE_LHASH_COMP_FN(name, o_type) \ |
55 | int name##_LHASH_COMP(const void *, const void *); | |
56 | # define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ | |
57 | int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ | |
58 | const o_type *a = arg1; \ | |
59 | const o_type *b = arg2; \ | |
60 | return name##_cmp(a,b); } | |
61 | # define LHASH_COMP_FN(name) name##_LHASH_COMP | |
dfa46e50 | 62 | |
18602745 | 63 | /* Fourth: "doall_arg" functions */ |
0f113f3e MC |
64 | # define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ |
65 | void name##_LHASH_DOALL_ARG(void *, void *); | |
66 | # define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ | |
67 | void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ | |
68 | o_type *a = arg1; \ | |
69 | a_type *b = arg2; \ | |
70 | name##_doall_arg(a, b); } | |
71 | # define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG | |
72 | ||
73 | typedef struct lhash_st { | |
74 | LHASH_NODE **b; | |
75 | LHASH_COMP_FN_TYPE comp; | |
76 | LHASH_HASH_FN_TYPE hash; | |
77 | unsigned int num_nodes; | |
78 | unsigned int num_alloc_nodes; | |
79 | unsigned int p; | |
80 | unsigned int pmax; | |
81 | unsigned long up_load; /* load times 256 */ | |
82 | unsigned long down_load; /* load times 256 */ | |
83 | unsigned long num_items; | |
84 | unsigned long num_expands; | |
85 | unsigned long num_expand_reallocs; | |
86 | unsigned long num_contracts; | |
87 | unsigned long num_contract_reallocs; | |
88 | unsigned long num_hash_calls; | |
89 | unsigned long num_comp_calls; | |
90 | unsigned long num_insert; | |
91 | unsigned long num_replace; | |
92 | unsigned long num_delete; | |
93 | unsigned long num_no_delete; | |
94 | unsigned long num_retrieve; | |
95 | unsigned long num_retrieve_miss; | |
96 | unsigned long num_hash_comps; | |
97 | int error; | |
98 | } _LHASH; /* Do not use _LHASH directly, use LHASH_OF | |
99 | * and friends */ | |
100 | ||
101 | # define LH_LOAD_MULT 256 | |
102 | ||
103 | /* | |
104 | * Indicates a malloc() error in the last call, this is only bad in | |
105 | * lh_insert(). | |
106 | */ | |
e6b5c341 | 107 | int lh_error(_LHASH *lh); |
dfeab068 | 108 | |
3c1d6bbc BL |
109 | _LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); |
110 | void lh_free(_LHASH *lh); | |
111 | void *lh_insert(_LHASH *lh, void *data); | |
112 | void *lh_delete(_LHASH *lh, const void *data); | |
113 | void *lh_retrieve(_LHASH *lh, const void *data); | |
114 | void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); | |
115 | void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); | |
e778802f | 116 | unsigned long lh_strhash(const char *c); |
3c1d6bbc | 117 | unsigned long lh_num_items(const _LHASH *lh); |
e6b5c341 DSH |
118 | unsigned long lh_get_down_load(const _LHASH *lh); |
119 | void lh_set_down_load(_LHASH *lh, unsigned long down_load); | |
d02b48c6 | 120 | |
474e469b RS |
121 | # ifndef OPENSSL_NO_STDIO |
122 | void lh_stats(const _LHASH *lh, FILE *fp); | |
123 | void lh_node_stats(const _LHASH *lh, FILE *fp); | |
31b446e2 | 124 | void lh_node_usage_stats(const _LHASH *lh, FILE *fp); |
474e469b | 125 | # endif |
3c1d6bbc BL |
126 | void lh_stats_bio(const _LHASH *lh, BIO *out); |
127 | void lh_node_stats_bio(const _LHASH *lh, BIO *out); | |
128 | void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); | |
3c1d6bbc | 129 | |
220903f9 | 130 | /* Type checking... */ |
3c1d6bbc | 131 | |
0f113f3e | 132 | # define LHASH_OF(type) struct lhash_st_##type |
3c1d6bbc | 133 | |
89d6aa10 | 134 | # define DEFINE_LHASH_OF(type) \ |
703f44e7 | 135 | LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \ |
89d6aa10 | 136 | static ossl_inline LHASH_OF(type) * \ |
62d0577e DSH |
137 | lh_##type##_new(unsigned long (*hfn)(const type *), \ |
138 | int (*cfn)(const type *, const type *)) \ | |
139 | { \ | |
140 | return (LHASH_OF(type) *) \ | |
141 | lh_new((LHASH_HASH_FN_TYPE) hfn, (LHASH_COMP_FN_TYPE)cfn); \ | |
142 | } \ | |
89d6aa10 | 143 | static ossl_inline void lh_##type##_free(LHASH_OF(type) *lh) \ |
e6b5c341 DSH |
144 | { \ |
145 | lh_free((_LHASH *)lh); \ | |
146 | } \ | |
89d6aa10 | 147 | static ossl_inline type *lh_##type##_insert(LHASH_OF(type) *lh, type *d) \ |
e6b5c341 | 148 | { \ |
917c343e | 149 | return (type *)lh_insert((_LHASH *)lh, d); \ |
e6b5c341 | 150 | } \ |
89d6aa10 | 151 | static ossl_inline type *lh_##type##_delete(LHASH_OF(type) *lh, const type *d) \ |
e6b5c341 | 152 | { \ |
917c343e | 153 | return (type *)lh_delete((_LHASH *)lh, d); \ |
e6b5c341 | 154 | } \ |
89d6aa10 | 155 | static ossl_inline type *lh_##type##_retrieve(LHASH_OF(type) *lh, const type *d) \ |
e6b5c341 | 156 | { \ |
917c343e | 157 | return (type *)lh_retrieve((_LHASH *)lh, d); \ |
e6b5c341 | 158 | } \ |
89d6aa10 | 159 | static ossl_inline int lh_##type##_error(LHASH_OF(type) *lh) \ |
e6b5c341 DSH |
160 | { \ |
161 | return lh_error((_LHASH *)lh); \ | |
162 | } \ | |
89d6aa10 | 163 | static ossl_inline unsigned long lh_##type##_num_items(LHASH_OF(type) *lh) \ |
e6b5c341 DSH |
164 | { \ |
165 | return lh_num_items((_LHASH *)lh); \ | |
166 | } \ | |
89d6aa10 | 167 | static ossl_inline void lh_##type##_node_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ |
e6b5c341 DSH |
168 | { \ |
169 | lh_node_stats_bio((_LHASH *)lh, out); \ | |
170 | } \ | |
89d6aa10 | 171 | static ossl_inline void lh_##type##_node_usage_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ |
e6b5c341 DSH |
172 | { \ |
173 | lh_node_usage_stats_bio((_LHASH *)lh, out); \ | |
174 | } \ | |
89d6aa10 | 175 | static ossl_inline void lh_##type##_stats_bio(const LHASH_OF(type) *lh, BIO *out) \ |
e6b5c341 DSH |
176 | { \ |
177 | lh_stats_bio((_LHASH *)lh, out); \ | |
178 | } \ | |
89d6aa10 | 179 | static ossl_inline unsigned long lh_##type##_get_down_load(LHASH_OF(type) *lh) \ |
e6b5c341 DSH |
180 | { \ |
181 | return lh_get_down_load((_LHASH *)lh); \ | |
182 | } \ | |
89d6aa10 | 183 | static ossl_inline void lh_##type##_set_down_load(LHASH_OF(type) *lh, unsigned long dl) \ |
e6b5c341 DSH |
184 | { \ |
185 | lh_set_down_load((_LHASH *)lh, dl); \ | |
186 | } \ | |
89d6aa10 | 187 | static ossl_inline void lh_##type##_doall(LHASH_OF(type) *lh, \ |
63c75cd6 DSH |
188 | void (*doall)(type *)) \ |
189 | { \ | |
190 | lh_doall((_LHASH *)lh, (LHASH_DOALL_FN_TYPE)doall); \ | |
191 | } \ | |
e6b5c341 | 192 | LHASH_OF(type) |
3c1d6bbc | 193 | |
2a056de8 DSH |
194 | #define IMPLEMENT_LHASH_DOALL_ARG_CONST(type, argtype) \ |
195 | int_implement_lhash_doall(type, argtype, const type) | |
196 | ||
197 | #define IMPLEMENT_LHASH_DOALL_ARG(type, argtype) \ | |
198 | int_implement_lhash_doall(type, argtype, type) | |
199 | ||
200 | #define int_implement_lhash_doall(type, argtype, cbargtype) \ | |
89d6aa10 | 201 | static ossl_inline void \ |
2a056de8 DSH |
202 | lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \ |
203 | void (*fn)(cbargtype *, argtype *), \ | |
204 | argtype *arg) \ | |
205 | { \ | |
206 | lh_doall_arg((_LHASH *)lh, (LHASH_DOALL_ARG_FN_TYPE)fn, (void *)arg); \ | |
207 | } \ | |
208 | LHASH_OF(type) | |
209 | ||
0f113f3e | 210 | # define CHECKED_LHASH_OF(type,lh) \ |
3c1d6bbc BL |
211 | ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh)) |
212 | ||
220903f9 | 213 | /* Define wrapper functions. */ |
0f113f3e | 214 | # define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ |
3c1d6bbc | 215 | lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) |
3c1d6bbc | 216 | |
89d6aa10 DSH |
217 | DEFINE_LHASH_OF(OPENSSL_STRING); |
218 | DEFINE_LHASH_OF(OPENSSL_CSTRING); | |
3c1d6bbc | 219 | |
d02b48c6 RE |
220 | #ifdef __cplusplus |
221 | } | |
222 | #endif | |
223 | ||
224 | #endif |