X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilchashtable.c;h=7c3d7cbfbad5b899de73eec3c1673a251b6c68d3;hb=b4dc1a71c928fdc0ec885ed5745b0d17b094ff7e;hp=027325b0affe559eda69fcdc71b6f06b7ddfae5d;hpb=51558729d89b9f3492b2ca754242ed548a579ca4;p=runtime.git diff --git a/lib/silcutil/silchashtable.c b/lib/silcutil/silchashtable.c index 027325b0..7c3d7cbf 100644 --- a/lib/silcutil/silchashtable.c +++ b/lib/silcutil/silchashtable.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2001 - 2007 Pekka Riikonen + Copyright (C) 2001 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,10 +23,8 @@ However, this is reliable and no data is lost at any point. If you know that you never have duplicate keys then this is as fast as any simple hash table. */ -/* $Id$ */ -#include "silc.h" -#include "silchashtable.h" +#include "silcruntime.h" /* Define to 1 if you want hash table debug enabled */ #define SILC_HASH_TABLE_DEBUG 0 @@ -805,10 +803,8 @@ void silc_hash_table_foreach(SilcHashTable ht, SilcHashForeach foreach, int i; SilcBool auto_rehash; - if (!foreach) { - silc_set_errno(SILC_ERR_INVALID_ARGUMENT); - return FALSE; - } + if (!foreach) + return; auto_rehash = ht->auto_rehash; ht->auto_rehash = FALSE; @@ -990,3 +986,144 @@ SilcBool silc_hash_table_get(SilcHashTableList *htl, void **key, return TRUE; } + +/**************************** Utility functions *****************************/ + +/* Case sensitive hashing */ + +SilcUInt32 silc_hash_string(void *key, void *user_context) +{ + char *s = (char *)key; + SilcUInt32 h = 0; + + while (*s != '\0') { + h += *s++; + h += (h << 10); + h ^= (h >> 6); + } + + h += (h << 3); + h ^= (h >> 11); + h += (h << 15); + + return h; +} + +/* Case-insensitive hashing */ + +SilcUInt32 silc_hash_string_case(void *key, void *user_context) +{ + char *s = (char *)key; + SilcUInt32 h = 0; + + while (*s != '\0') { + h += tolower((int)*s); + h += (h << 10); + h ^= (h >> 6); + s++; + } + + h += (h << 3); + h ^= (h >> 11); + h += (h << 15); + + return h; +} + +/* Hash UTF-8 string */ + +SilcUInt32 silc_hash_utf8_string(void *key, void *user_context) +{ + char *s = (char *)key; + SilcUInt32 h = 0; + + while (*s != '\0') { + h += *s++; + h += (h << 10); + h ^= (h >> 6); + } + + h += (h << 3); + h ^= (h >> 11); + h += (h << 15); + + return h; +} + +/* Basic hash function to hash integers. */ + +SilcUInt32 silc_hash_uint(void *key, void *user_context) +{ + return SILC_PTR_TO_32(key); +} + +/* Basic hash funtion to hash pointers. */ + +SilcUInt32 silc_hash_ptr(void *key, void *user_context) +{ + return SILC_PTR_TO_32(key); +} + +/* Hash binary data. The `user_context' is the data length. */ + +SilcUInt32 silc_hash_data(void *key, void *user_context) +{ + SilcUInt32 len = SILC_PTR_TO_32(user_context), h, i; + unsigned char *data = (char *)key; + + h = (data[0] * data[len - 1] + 1) * len; + + for (i = 0; i < len; i++) { + h += data[i]; + h += (h << 10); + h ^= (h >> 6); + } + + h += (h << 3); + h ^= (h >> 11); + h += (h << 15); + + return h; +} + +/* Compares two strings. */ + +SilcBool silc_hash_string_compare(void *key1, void *key2, void *user_context) +{ + return !strcmp((char *)key1, (char *)key2); +} + +/* Compares two strings, ignores case. */ + +SilcBool silc_hash_string_case_compare(void *key1, void *key2, + void *user_context) +{ + return !strcasecmp((char *)key1, (char *)key2); +} + +/* Compares binary data. */ + +SilcBool silc_hash_data_compare(void *key1, void *key2, void *user_context) +{ + SilcUInt32 len = SILC_PTR_TO_32(user_context); + return !memcmp(key1, key2, len); +} + +/* Compares UTF-8 string. */ + +SilcBool silc_hash_utf8_compare(void *key1, void *key2, void *user_context) +{ + int l1 = strlen((char *)key1); + int l2 = strlen((char *)key2); + if (l1 != l2) + return FALSE; + return !memcmp(key1, key2, l2); +} + +/* Generic destructor */ + +void silc_hash_destructor(void *key, void *context, void *user_context) +{ + silc_free(key); + silc_free(context); +}