-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathhash.c
146 lines (118 loc) · 4.25 KB
/
hash.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <openssl/err.h>
#include <openssl/lhash.h>
#include <openssl/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <assert.h>
void print_error() {
char buf[256];
int err = ERR_get_error();
ERR_error_string_n(err, buf, sizeof(buf));
printf("errno: %d, %s\n", err, buf);
}
struct something_st {
char* name;
};
typedef struct something_st SOMETHING;
struct lhash_st_SOMETHING {
union lh_SOMETHING_dummy { void* d1; unsigned long d2; int d3; } dummy;
};
long unsigned int something_hash(const SOMETHING* s) {
return OPENSSL_LH_strhash(s->name);
}
int something_compare(const SOMETHING* s1, const SOMETHING* s2) {
return strcmp(s1->name, s2->name);
}
#ifndef __unused
#define __unused __attribute__((unused))
#endif
//DEFINE_LHASH_OF(SOMETHING);
//The above will generate the following:
// lh_SOMETHING_new is used to create a hash table. It takes a hash function
// and a compare function which are defined above.
static __unused
inline struct lhash_st_SOMETHING* lh_SOMETHING_new(
unsigned long (*hfn)(const SOMETHING*),
int (*cfn)(const SOMETHING*, const SOMETHING*)) {
return (struct lhash_st_SOMETHING*)
OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn);
}
// Notice that the return type if struct lhash_st_SOMETHING* which can then
// be used to call the other functions below:
// So to insert we pass our hash table that we created above and a pointer
// to struct somthing_st (SOMETHING) to insert.
//
static __unused
inline SOMETHING *lh_SOMETHING_insert(struct lhash_st_SOMETHING *lh, SOMETHING *d) {
return (SOMETHING *)OPENSSL_LH_insert((OPENSSL_LHASH *)lh, d);
}
// Get/retrieve a value from the hash table:
static __unused
inline SOMETHING *lh_SOMETHING_retrieve(struct lhash_st_SOMETHING *lh, const SOMETHING *d) {
return (SOMETHING *)OPENSSL_LH_retrieve((OPENSSL_LHASH *)lh, d);
}
// Get the number of entries in the hash table
static __unused
inline unsigned long lh_SOMETHING_num_items(struct lhash_st_SOMETHING *lh) {
return OPENSSL_LH_num_items((OPENSSL_LHASH *)lh);
}
static __unused
inline void lh_SOMETHING_free(struct lhash_st_SOMETHING* lh) {
OPENSSL_LH_free((OPENSSL_LHASH *)lh);
}
static __unused
inline void lh_SOMETHING_flush(struct lhash_st_SOMETHING *lh) {
OPENSSL_LH_flush((OPENSSL_LHASH *)lh);
}
static __unused
inline SOMETHING *lh_SOMETHING_delete(struct lhash_st_SOMETHING *lh, const SOMETHING *d) {
return (SOMETHING *)OPENSSL_LH_delete((OPENSSL_LHASH *)lh, d);
}
static __unused
inline int lh_SOMETHING_error(struct lhash_st_SOMETHING *lh) {
return OPENSSL_LH_error((OPENSSL_LHASH *)lh);
}
static __unused
inline void lh_SOMETHING_node_stats_bio(const struct lhash_st_SOMETHING *lh, BIO *out) {
OPENSSL_LH_node_stats_bio((const OPENSSL_LHASH *)lh, out);
}
static __unused
inline void lh_SOMETHING_node_usage_stats_bio(const struct lhash_st_SOMETHING *lh, BIO *out) {
OPENSSL_LH_node_usage_stats_bio((const OPENSSL_LHASH *)lh, out);
}
static __unused
inline void lh_SOMETHING_stats_bio(const struct lhash_st_SOMETHING *lh, BIO *out) {
OPENSSL_LH_stats_bio((const OPENSSL_LHASH *)lh, out);
}
static __unused
inline unsigned long lh_SOMETHING_get_down_load(struct lhash_st_SOMETHING *lh) {
return OPENSSL_LH_get_down_load((OPENSSL_LHASH *)lh);
}
static __unused
inline void lh_SOMETHING_set_down_load(struct lhash_st_SOMETHING *lh, unsigned long dl) {
OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl);
}
static __unused
inline void lh_SOMETHING_doall(struct lhash_st_SOMETHING *lh, void (*doall)(SOMETHING *)) {
OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall);
} struct lhash_st_SOMETHING;
void do_all(SOMETHING* s) {
printf("s->name: %s\n", s->name);
}
int main(int argc, char** argv) {
printf("OpenSSL lhash example\n");
struct lhash_st_SOMETHING* lh = lh_SOMETHING_new(something_hash, something_compare);
struct something_st first = {"first"};
SOMETHING* nothing = lh_SOMETHING_insert(lh, &first);
assert(nothing == NULL);
printf("Inserted: %s\n", first.name);
printf("Number of items: %lu\n", lh_SOMETHING_num_items(lh));
SOMETHING* inserted = lh_SOMETHING_retrieve(lh, &first);
printf("Retrieved: %s\n", inserted->name);
printf("Do all:\n");
lh_SOMETHING_doall(lh, do_all);
print_error();
exit(EXIT_SUCCESS);
}