static void contract(OPENSSL_LHASH *lh);
static OPENSSL_LH_NODE **getrn(OPENSSL_LHASH *lh, const void *data, unsigned long *rhash);
+OPENSSL_LHASH *OPENSSL_LH_set_thunks(OPENSSL_LHASH *lh,
+ OPENSSL_LH_HASHFUNCTHUNK hw,
+ OPENSSL_LH_COMPFUNCTHUNK cw,
+ OPENSSL_LH_DOALL_FUNC_THUNK daw,
+ OPENSSL_LH_DOALL_FUNCARG_THUNK daaw)
+{
+
+ if (lh == NULL)
+ return NULL;
+ lh->compw = cw;
+ lh->hashw = hw;
+ lh->daw = daw;
+ lh->daaw = daaw;
+ return lh;
+}
+
OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c)
{
OPENSSL_LHASH *ret;
}
static void doall_util_fn(OPENSSL_LHASH *lh, int use_arg,
+ OPENSSL_LH_DOALL_FUNC_THUNK wfunc,
OPENSSL_LH_DOALL_FUNC func,
- OPENSSL_LH_DOALL_FUNCARG func_arg, void *arg)
+ OPENSSL_LH_DOALL_FUNCARG func_arg,
+ OPENSSL_LH_DOALL_FUNCARG_THUNK wfunc_arg,
+ void *arg)
{
int i;
OPENSSL_LH_NODE *a, *n;
while (a != NULL) {
n = a->next;
if (use_arg)
- func_arg(a->data, arg);
+ wfunc_arg(a->data, arg, func_arg);
else
- func(a->data);
+ wfunc(a->data, func);
a = n;
}
}
void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func)
{
- doall_util_fn(lh, 0, func, (OPENSSL_LH_DOALL_FUNCARG)0, NULL);
+ if (lh == NULL)
+ return;
+
+ doall_util_fn(lh, 0, lh->daw, func, (OPENSSL_LH_DOALL_FUNCARG)NULL,
+ (OPENSSL_LH_DOALL_FUNCARG_THUNK)NULL, NULL);
}
-void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg)
+void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh,
+ OPENSSL_LH_DOALL_FUNCARG func, void *arg)
{
- doall_util_fn(lh, 1, (OPENSSL_LH_DOALL_FUNC)0, func, arg);
+ if (lh == NULL)
+ return;
+
+ doall_util_fn(lh, 1, (OPENSSL_LH_DOALL_FUNC_THUNK)NULL,
+ (OPENSSL_LH_DOALL_FUNC)NULL, func, lh->daaw, arg);
+}
+
+void OPENSSL_LH_doall_arg_thunk(OPENSSL_LHASH *lh,
+ OPENSSL_LH_DOALL_FUNCARG_THUNK daaw,
+ OPENSSL_LH_DOALL_FUNCARG fn, void *arg)
+{
+ doall_util_fn(lh, 1, (OPENSSL_LH_DOALL_FUNC_THUNK)NULL,
+ (OPENSSL_LH_DOALL_FUNC)NULL, fn, daaw, arg);
}
static int expand(OPENSSL_LHASH *lh)
{
OPENSSL_LH_NODE **ret, *n1;
unsigned long hash, nn;
- OPENSSL_LH_COMPFUNC cf;
- hash = (*(lh->hash)) (data);
+ if (lh->hashw != NULL)
+ hash = lh->hashw(data, lh->hash);
+ else
+ hash = lh->hash(data);
+
*rhash = hash;
nn = hash % lh->pmax;
if (nn < lh->p)
nn = hash % lh->num_alloc_nodes;
- cf = lh->comp;
ret = &(lh->b[(int)nn]);
for (n1 = *ret; n1 != NULL; n1 = n1->next) {
if (n1->hash != hash) {
ret = &(n1->next);
continue;
}
- if (cf(n1->data, data) == 0)
- break;
+
+ if (lh->compw != NULL) {
+ if (lh->compw(n1->data, data, lh->comp) == 0)
+ break;
+ } else {
+ if (lh->comp(n1->data, data) == 0)
+ break;
+ }
ret = &(n1->next);
}
return ret;
lh_TYPE_set_down_load, lh_TYPE_error,
OPENSSL_LH_new, OPENSSL_LH_free, OPENSSL_LH_flush,
OPENSSL_LH_insert, OPENSSL_LH_delete, OPENSSL_LH_retrieve,
-OPENSSL_LH_doall, OPENSSL_LH_doall_arg, OPENSSL_LH_num_items,
+OPENSSL_LH_doall, OPENSSL_LH_doall_arg, OPENSSL_LH_doall_arg_thunk,
+OPENSSL_LH_set_thunks, OPENSSL_LH_num_items,
OPENSSL_LH_get_down_load, OPENSSL_LH_set_down_load, OPENSSL_LH_error
- dynamic hash table
LHASH_OF(TYPE) *lh_TYPE_new(OPENSSL_LH_HASHFUNC hash, OPENSSL_LH_COMPFUNC compare);
void lh_TYPE_free(LHASH_OF(TYPE) *table);
void lh_TYPE_flush(LHASH_OF(TYPE) *table);
+ OPENSSL_LHASH *OPENSSL_LH_set_thunks(OPENSSL_LHASH *lh,
+ OPENSSL_LH_HASHFUNCTHUNK hw,
+ OPENSSL_LH_COMPFUNCTHUNK cw,
+ OPENSSL_LH_DOALL_FUNC_THUNK daw,
+ OPENSSL_LH_DOALL_FUNCARG_THUNK daaw)
TYPE *lh_TYPE_insert(LHASH_OF(TYPE) *table, TYPE *data);
TYPE *lh_TYPE_delete(LHASH_OF(TYPE) *table, TYPE *data);
void lh_TYPE_doall(LHASH_OF(TYPE) *table, OPENSSL_LH_DOALL_FUNC func);
void lh_TYPE_doall_arg(LHASH_OF(TYPE) *table, OPENSSL_LH_DOALL_FUNCARG func,
TYPE *arg);
+ void OPENSSL_LH_doall_arg_thunk(OPENSSL_LHASH *lh,
+ OPENSSL_LH_DOALL_FUNCARG_THUNK daaw,
+ OPENSSL_LH_DOALL_FUNCARG fn, void *arg)
unsigned long lh_TYPE_num_items(OPENSSL_LHASH *lh);
unsigned long lh_TYPE_get_down_load(OPENSSL_LHASH *lh);
B<OPENSSL_LH> functions. Most applications should not call the B<OPENSSL_LH>
functions directly.
+OPENSSL_LH_set_thunks() and OPENSSL_LH_doall_arg_thunk(), while public by
+necessity, are actually internal functions and should not be used.
+
=head1 RETURN VALUES
B<lh_I<TYPE>_new>() and OPENSSL_LH_new() return NULL on error, otherwise a
typedef struct lhash_node_st OPENSSL_LH_NODE;
typedef int (*OPENSSL_LH_COMPFUNC) (const void *, const void *);
+typedef int (*OPENSSL_LH_COMPFUNCTHUNK) (const void *, const void *, OPENSSL_LH_COMPFUNC cfn);
typedef unsigned long (*OPENSSL_LH_HASHFUNC) (const void *);
+typedef unsigned long (*OPENSSL_LH_HASHFUNCTHUNK) (const void *, OPENSSL_LH_HASHFUNC hfn);
typedef void (*OPENSSL_LH_DOALL_FUNC) (void *);
+typedef void (*OPENSSL_LH_DOALL_FUNC_THUNK) (void *, OPENSSL_LH_DOALL_FUNC doall);
typedef void (*OPENSSL_LH_DOALL_FUNCARG) (void *, void *);
+typedef void (*OPENSSL_LH_DOALL_FUNCARG_THUNK) (void *, void *, OPENSSL_LH_DOALL_FUNCARG doall);
typedef struct lhash_st OPENSSL_LHASH;
/*
int OPENSSL_LH_error(OPENSSL_LHASH *lh);
OPENSSL_LHASH *OPENSSL_LH_new(OPENSSL_LH_HASHFUNC h, OPENSSL_LH_COMPFUNC c);
+OPENSSL_LHASH *OPENSSL_LH_set_thunks(OPENSSL_LHASH *lh,
+ OPENSSL_LH_HASHFUNCTHUNK hw,
+ OPENSSL_LH_COMPFUNCTHUNK cw,
+ OPENSSL_LH_DOALL_FUNC_THUNK daw,
+ OPENSSL_LH_DOALL_FUNCARG_THUNK daaw);
void OPENSSL_LH_free(OPENSSL_LHASH *lh);
void OPENSSL_LH_flush(OPENSSL_LHASH *lh);
void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data);
void *OPENSSL_LH_delete(OPENSSL_LHASH *lh, const void *data);
void *OPENSSL_LH_retrieve(OPENSSL_LHASH *lh, const void *data);
void OPENSSL_LH_doall(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNC func);
-void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh, OPENSSL_LH_DOALL_FUNCARG func, void *arg);
+void OPENSSL_LH_doall_arg(OPENSSL_LHASH *lh,
+ OPENSSL_LH_DOALL_FUNCARG func, void *arg);
+void OPENSSL_LH_doall_arg_thunk(OPENSSL_LHASH *lh,
+ OPENSSL_LH_DOALL_FUNCARG_THUNK daaw,
+ OPENSSL_LH_DOALL_FUNCARG fn, void *arg);
+
unsigned long OPENSSL_LH_strhash(const char *c);
unsigned long OPENSSL_LH_num_items(const OPENSSL_LHASH *lh);
unsigned long OPENSSL_LH_get_down_load(const OPENSSL_LHASH *lh);
typedef int (*lh_##type##_compfunc)(const type *a, const type *b); \
typedef unsigned long (*lh_##type##_hashfunc)(const type *a); \
typedef void (*lh_##type##_doallfunc)(type *a); \
+ static ossl_inline unsigned long lh_##type##_hash_thunk(const void *data, OPENSSL_LH_HASHFUNC hfn) \
+ { \
+ unsigned long (*hfn_conv)(const type *) = (unsigned long (*)(const type *))hfn; \
+ return hfn_conv((const type *)data); \
+ } \
+ static ossl_inline int lh_##type##_comp_thunk(const void *da, const void *db, OPENSSL_LH_COMPFUNC cfn) \
+ { \
+ int (*cfn_conv)(const type *, const type *) = (int (*)(const type *, const type *))cfn; \
+ return cfn_conv((const type *)da, (const type *)db); \
+ } \
+ static ossl_inline void lh_##type##_doall_thunk(void *node, OPENSSL_LH_DOALL_FUNC doall) \
+ { \
+ void (*doall_conv)(type *) = (void (*)(type *))doall; \
+ doall_conv((type *)node); \
+ } \
+ static ossl_inline void lh_##type##_doall_arg_thunk(void *node, void *arg, OPENSSL_LH_DOALL_FUNCARG doall) \
+ { \
+ void (*doall_conv)(type *, void *) = (void (*)(type *, void *))doall; \
+ doall_conv((type *)node, arg); \
+ } \
static ossl_unused ossl_inline type *\
ossl_check_##type##_lh_plain_type(type *ptr) \
{ \
LHASH_OF(type) { \
union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; \
}; \
- static ossl_unused ossl_inline LHASH_OF(type) * \
- lh_##type##_new(unsigned long (*hfn)(const type *), \
- int (*cfn)(const type *, const type *)) \
+ static unsigned long \
+ lh_##type##_hfn_thunk(const void *data, OPENSSL_LH_HASHFUNC hfn) \
{ \
- return (LHASH_OF(type) *) \
- OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \
+ unsigned long (*hfn_conv)(const type *) = (unsigned long (*)(const type *))hfn; \
+ return hfn_conv((const type *)data); \
+ } \
+ static int lh_##type##_cfn_thunk(const void *da, const void *db, OPENSSL_LH_COMPFUNC cfn) \
+ { \
+ int (*cfn_conv)(const type *, const type *) = (int (*)(const type *, const type *))cfn; \
+ return cfn_conv((const type *)da, (const type *)db); \
} \
static ossl_unused ossl_inline void \
lh_##type##_free(LHASH_OF(type) *lh) \
OPENSSL_LH_set_down_load((OPENSSL_LHASH *)lh, dl); \
} \
static ossl_unused ossl_inline void \
+ lh_##type##_doall_thunk(void *node, OPENSSL_LH_DOALL_FUNC doall) \
+ { \
+ void (*doall_conv)(type *) = (void (*)(type *))doall; \
+ doall_conv((type *)node); \
+ } \
+ static ossl_unused ossl_inline void \
+ lh_##type##_doall_arg_thunk(void *node, void *arg, OPENSSL_LH_DOALL_FUNCARG doall) \
+ { \
+ void (*doall_conv)(type *, void *) = (void (*)(type *, void *))doall; \
+ doall_conv((type *)node, arg); \
+ } \
+ static ossl_unused ossl_inline void \
lh_##type##_doall(LHASH_OF(type) *lh, void (*doall)(type *)) \
{ \
OPENSSL_LH_doall((OPENSSL_LHASH *)lh, (OPENSSL_LH_DOALL_FUNC)doall); \
} \
+ static ossl_unused ossl_inline LHASH_OF(type) * \
+ lh_##type##_new(unsigned long (*hfn)(const type *), \
+ int (*cfn)(const type *, const type *)) \
+ { \
+ return (LHASH_OF(type) *)OPENSSL_LH_set_thunks(OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn), \
+ lh_##type##_hfn_thunk, lh_##type##_cfn_thunk, \
+ lh_##type##_doall_thunk, \
+ lh_##type##_doall_arg_thunk); \
+ } \
static ossl_unused ossl_inline void \
lh_##type##_doall_arg(LHASH_OF(type) *lh, \
void (*doallarg)(type *, void *), void *arg) \
int_implement_lhash_doall(type, argtype, type)
#define int_implement_lhash_doall(type, argtype, cbargtype) \
+ static ossl_unused ossl_inline void \
+ lh_##type##_doall_##argtype##_thunk(void *node, void *arg, OPENSSL_LH_DOALL_FUNCARG fn) \
+ { \
+ void (*fn_conv)(cbargtype *, argtype *) = (void (*)(cbargtype *, argtype *))fn; \
+ fn_conv((cbargtype *)node, (argtype *)arg); \
+ } \
static ossl_unused ossl_inline void \
lh_##type##_doall_##argtype(LHASH_OF(type) *lh, \
void (*fn)(cbargtype *, argtype *), \
argtype *arg) \
{ \
- OPENSSL_LH_doall_arg((OPENSSL_LHASH *)lh, \
- (OPENSSL_LH_DOALL_FUNCARG)fn, (void *)arg); \
+ OPENSSL_LH_doall_arg_thunk((OPENSSL_LHASH *)lh, \
+ lh_##type##_doall_##argtype##_thunk, \
+ (OPENSSL_LH_DOALL_FUNCARG)fn, \
+ (void *)arg); \
} \
LHASH_OF(type)