/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 * All rights reserved.
 *
 * This package is an SSL implementation written
 * by Eric Young (eay@cryptsoft.com).
 * The implementation was written so as to conform with Netscapes SSL.
 *
 * This library is free for commercial and non-commercial use as long as
 * the following conditions are aheared to.  The following conditions
 * apply to all code found in this distribution, be it the RC4, RSA,
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
 * included with this distribution is covered by the same copyright terms
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
 *
 * Copyright remains Eric Young's, and as such any Copyright notices in
 * the code are not to be removed.
 * If this package is used in a product, Eric Young should be given attribution
 * as the author of the parts of the library used.
 * This can be in the form of a textual message at program startup or
 * in documentation (online or textual) provided with the package.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes cryptographic software written by
 *     Eric Young (eay@cryptsoft.com)"
 *    The word 'cryptographic' can be left out if the rouines from the library
 *    being used are not cryptographic related :-).
 * 4. If you include any Windows specific code (or a derivative thereof) from
 *    the apps directory (application code) you must include an acknowledgement:
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
 *
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * The licence and distribution terms for any publically available version or
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
 * copied and put under another distribution licence
 * [including the GNU Public Licence.] */

#ifndef OPENSSL_HEADER_LHASH_H
#define OPENSSL_HEADER_LHASH_H

#include <openssl/base.h>
#include <openssl/type_check.h>

#if defined(__cplusplus)
extern "C" {
#endif


// lhash is a traditional, chaining hash table that automatically expands and
// contracts as needed. One should not use the lh_* functions directly, rather
// use the type-safe macro wrappers:
//
// A hash table of a specific type of object has type |LHASH_OF(type)|. This
// can be defined (once) with |DEFINE_LHASH_OF(type)| and declared where needed
// with |DECLARE_LHASH_OF(type)|. For example:
//
//   struct foo {
//     int bar;
//   };
//
//   DEFINE_LHASH_OF(struct foo)
//
// Although note that the hash table will contain /pointers/ to |foo|.
//
// A macro will be defined for each of the lh_* functions below. For
// LHASH_OF(foo), the macros would be lh_foo_new, lh_foo_num_items etc.


#define LHASH_OF(type) struct lhash_st_##type

#define DECLARE_LHASH_OF(type) LHASH_OF(type);


// lhash_item_st is an element of a hash chain. It points to the opaque data
// for this element and to the next item in the chain. The linked-list is NULL
// terminated.
typedef struct lhash_item_st {
  void *data;
  struct lhash_item_st *next;
  // hash contains the cached, hash value of |data|.
  uint32_t hash;
} LHASH_ITEM;

// lhash_cmp_func is a comparison function that returns a value equal, or not
// equal, to zero depending on whether |*a| is equal, or not equal to |*b|,
// respectively. Note the difference between this and |stack_cmp_func| in that
// this takes pointers to the objects directly.
//
// This function's actual type signature is int (*)(const T*, const T*). The
// low-level |lh_*| functions will be passed a type-specific wrapper to call it
// correctly.
typedef int (*lhash_cmp_func)(const void *a, const void *b);
typedef int (*lhash_cmp_func_helper)(lhash_cmp_func func, const void *a,
                                     const void *b);

// lhash_hash_func is a function that maps an object to a uniformly distributed
// uint32_t.
//
// This function's actual type signature is uint32_t (*)(const T*). The
// low-level |lh_*| functions will be passed a type-specific wrapper to call it
// correctly.
typedef uint32_t (*lhash_hash_func)(const void *a);
typedef uint32_t (*lhash_hash_func_helper)(lhash_hash_func func, const void *a);

typedef struct lhash_st _LHASH;

// lh_new returns a new, empty hash table or NULL on error.
OPENSSL_EXPORT _LHASH *lh_new(lhash_hash_func hash, lhash_cmp_func comp);

// lh_free frees the hash table itself but none of the elements. See
// |lh_doall|.
OPENSSL_EXPORT void lh_free(_LHASH *lh);

// lh_num_items returns the number of items in |lh|.
OPENSSL_EXPORT size_t lh_num_items(const _LHASH *lh);

// lh_retrieve finds an element equal to |data| in the hash table and returns
// it. If no such element exists, it returns NULL.
OPENSSL_EXPORT void *lh_retrieve(const _LHASH *lh, const void *data,
                                 lhash_hash_func_helper call_hash_func,
                                 lhash_cmp_func_helper call_cmp_func);

// lh_retrieve_key finds an element matching |key|, given the specified hash and
// comparison function. This differs from |lh_retrieve| in that the key may be a
// different type than the values stored in |lh|. |key_hash| and |cmp_key| must
// be compatible with the functions passed into |lh_new|.
OPENSSL_EXPORT void *lh_retrieve_key(const _LHASH *lh, const void *key,
                                     uint32_t key_hash,
                                     int (*cmp_key)(const void *key,
                                                    const void *value));

// lh_insert inserts |data| into the hash table. If an existing element is
// equal to |data| (with respect to the comparison function) then |*old_data|
// will be set to that value and it will be replaced. Otherwise, or in the
// event of an error, |*old_data| will be set to NULL. It returns one on
// success or zero in the case of an allocation error.
OPENSSL_EXPORT int lh_insert(_LHASH *lh, void **old_data, void *data,
                             lhash_hash_func_helper call_hash_func,
                             lhash_cmp_func_helper call_cmp_func);

// lh_delete removes an element equal to |data| from the hash table and returns
// it. If no such element is found, it returns NULL.
OPENSSL_EXPORT void *lh_delete(_LHASH *lh, const void *data,
                               lhash_hash_func_helper call_hash_func,
                               lhash_cmp_func_helper call_cmp_func);

// lh_doall_arg calls |func| on each element of the hash table and also passes
// |arg| as the second argument.
// TODO(fork): rename this
OPENSSL_EXPORT void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *),
                                 void *arg);

// lh_strhash is the default hash function which processes NUL-terminated
// strings.
OPENSSL_EXPORT uint32_t lh_strhash(const char *c);

#define DEFINE_LHASH_OF(type)                                                  \
  DECLARE_LHASH_OF(type)                                                       \
                                                                               \
  typedef int (*lhash_##type##_cmp_func)(const type *, const type *);          \
  typedef uint32_t (*lhash_##type##_hash_func)(const type *);                  \
                                                                               \
  OPENSSL_INLINE int lh_##type##_call_cmp_func(lhash_cmp_func func,            \
                                               const void *a, const void *b) { \
    return ((lhash_##type##_cmp_func)func)((const type *)a, (const type *)b);  \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE uint32_t lh_##type##_call_hash_func(lhash_hash_func func,     \
                                                     const void *a) {          \
    return ((lhash_##type##_hash_func)func)((const type *)a);                  \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE LHASH_OF(type) *                                              \
      lh_##type##_new(lhash_##type##_hash_func hash,                           \
                      lhash_##type##_cmp_func comp) {                          \
    return (LHASH_OF(type) *)lh_new((lhash_hash_func)hash,                     \
                                    (lhash_cmp_func)comp);                     \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE void lh_##type##_free(LHASH_OF(type) *lh) {                   \
    lh_free((_LHASH *)lh);                                                     \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE size_t lh_##type##_num_items(const LHASH_OF(type) *lh) {      \
    return lh_num_items((const _LHASH *)lh);                                   \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE type *lh_##type##_retrieve(const LHASH_OF(type) *lh,          \
                                            const type *data) {                \
    return (type *)lh_retrieve((const _LHASH *)lh, data,                       \
                               lh_##type##_call_hash_func,                     \
                               lh_##type##_call_cmp_func);                     \
  }                                                                            \
                                                                               \
  typedef struct {                                                             \
    int (*cmp_key)(const void *key, const type *value);                        \
    const void *key;                                                           \
  } LHASH_CMP_KEY_##type;                                                      \
                                                                               \
  OPENSSL_INLINE int lh_##type##_call_cmp_key(const void *key,                 \
                                              const void *value) {             \
    const LHASH_CMP_KEY_##type *cb = (const LHASH_CMP_KEY_##type *)key;        \
    return cb->cmp_key(cb->key, (const type *)value);                          \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE type *lh_##type##_retrieve_key(                               \
      const LHASH_OF(type) *lh, const void *key, uint32_t key_hash,            \
      int (*cmp_key)(const void *key, const type *value)) {                    \
    LHASH_CMP_KEY_##type cb = {cmp_key, key};                                  \
    return (type *)lh_retrieve_key((const _LHASH *)lh, &cb, key_hash,          \
                                   lh_##type##_call_cmp_key);                  \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE int lh_##type##_insert(LHASH_OF(type) *lh, type **old_data,   \
                                        type *data) {                          \
    void *old_data_void = NULL;                                                \
    int ret =                                                                  \
        lh_insert((_LHASH *)lh, &old_data_void, data,                          \
                  lh_##type##_call_hash_func, lh_##type##_call_cmp_func);      \
    *old_data = (type *)old_data_void;                                         \
    return ret;                                                                \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE type *lh_##type##_delete(LHASH_OF(type) *lh,                  \
                                          const type *data) {                  \
    return (type *)lh_delete((_LHASH *)lh, data, lh_##type##_call_hash_func,   \
                             lh_##type##_call_cmp_func);                       \
  }                                                                            \
                                                                               \
  typedef struct {                                                             \
    void (*doall)(type *);                                                     \
    void (*doall_arg)(type *, void *);                                         \
    void *arg;                                                                 \
  } LHASH_DOALL_##type;                                                        \
                                                                               \
  OPENSSL_INLINE void lh_##type##_call_doall(void *value, void *arg) {         \
    const LHASH_DOALL_##type *cb = (const LHASH_DOALL_##type *)arg;            \
    cb->doall((type *)value);                                                  \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE void lh_##type##_call_doall_arg(void *value, void *arg) {     \
    const LHASH_DOALL_##type *cb = (const LHASH_DOALL_##type *)arg;            \
    cb->doall_arg((type *)value, cb->arg);                                     \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE void lh_##type##_doall(LHASH_OF(type) *lh,                    \
                                        void (*func)(type *)) {                \
    LHASH_DOALL_##type cb = {func, NULL, NULL};                                \
    lh_doall_arg((_LHASH *)lh, lh_##type##_call_doall, &cb);                   \
  }                                                                            \
                                                                               \
  OPENSSL_INLINE void lh_##type##_doall_arg(                                   \
      LHASH_OF(type) *lh, void (*func)(type *, void *), void *arg) {           \
    LHASH_DOALL_##type cb = {NULL, func, arg};                                 \
    lh_doall_arg((_LHASH *)lh, lh_##type##_call_doall_arg, &cb);               \
  }


#if defined(__cplusplus)
}  // extern C
#endif

#endif  // OPENSSL_HEADER_LHASH_H
