wshash.c
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:3k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  *
  3.  * wshash.c
  4.  *
  5.  * Author: Markku Rossi <mtr@iki.fi>
  6.  *
  7.  * Copyright (c) 1999-2000 WAPIT OY LTD.
  8.  *  All rights reserved.
  9.  *
  10.  * A mapping from null-terminated strings to `void *' pointers.
  11.  *
  12.  */
  13. #include "wsint.h"
  14. #include "wshash.h"
  15. /********************* Types and definitions ****************************/
  16. /* The size of the hash table. */
  17. #define WS_HASH_TABLE_SIZE 256
  18. /* A hash item. */
  19. struct WsHashItemRec
  20. {
  21.     struct WsHashItemRec *next;
  22.     char *name;
  23.     void *data;
  24. };
  25. typedef struct WsHashItemRec WsHashItem;
  26. /* The hash object. */
  27. struct WsHashRec
  28. {
  29.     WsHashItem *items[WS_HASH_TABLE_SIZE];
  30.     WsHashItemDestructor destructor;
  31.     void *destructor_context;
  32. };
  33. /********************* Prototypes for static functions ******************/
  34. /* Hash function to count the hash value of string `string'.  */
  35. static size_t count_hash(const char *string);
  36. /********************* Global functions *********************************/
  37. WsHashPtr ws_hash_create(WsHashItemDestructor destructor, void *context)
  38. {
  39.     WsHashPtr hash = ws_calloc(1, sizeof(*hash));
  40.     if (hash) {
  41.         hash->destructor = destructor;
  42.         hash->destructor_context = context;
  43.     }
  44.     return hash;
  45. }
  46. void ws_hash_destroy(WsHashPtr hash)
  47. {
  48.     if (hash == NULL)
  49.         return;
  50.     ws_hash_clear(hash);
  51.     ws_free(hash);
  52. }
  53. WsBool ws_hash_put(WsHashPtr hash, const char *name, void *data)
  54. {
  55.     WsHashItem *i;
  56.     size_t h = count_hash(name);
  57.     for (i = hash->items[h]; i; i = i->next) {
  58.         if (strcmp(i->name, name) == 0) {
  59.             /* Found it. */
  60.             /* Destroy the old item */
  61.             if (hash->destructor)
  62.                 (*hash->destructor)(i->data, hash->destructor_context);
  63.             i->data = data;
  64.             return WS_FALSE;
  65.         }
  66.     }
  67.     /* Must create a new mapping. */
  68.     i = ws_calloc(1, sizeof(*i));
  69.     if (i == NULL)
  70.         return WS_FALSE;
  71.     i->name = ws_strdup(name);
  72.     if (i->name == NULL) {
  73.         ws_free(i);
  74.         return WS_FALSE;
  75.     }
  76.     i->data = data;
  77.     /* Link it to our hash. */
  78.     i->next = hash->items[h];
  79.     hash->items[h] = i;
  80.     return WS_TRUE;
  81. }
  82. void *ws_hash_get(WsHashPtr hash, const char *name)
  83. {
  84.     WsHashItem *i;
  85.     size_t h = count_hash(name);
  86.     for (i = hash->items[h]; i; i = i->next)
  87.         if (strcmp(i->name, name) == 0)
  88.             return i->data;
  89.     return NULL;
  90. }
  91. void ws_hash_clear(WsHashPtr hash)
  92. {
  93.     WsHashItem *i, *n;
  94.     size_t j;
  95.     for (j = 0; j < WS_HASH_TABLE_SIZE; j++) {
  96.         for (i = hash->items[j]; i; i = n) {
  97.             n = i->next;
  98.             if (hash->destructor)
  99.                 (*hash->destructor)(i->data, hash->destructor_context);
  100.             ws_free(i->name);
  101.             ws_free(i);
  102.         }
  103.         hash->items[j] = NULL;
  104.     }
  105. }
  106. /********************* Static functions *********************************/
  107. static size_t count_hash(const char *string)
  108. {
  109.     size_t val = 0;
  110.     int i;
  111.     for (i = 0; string[i]; i++) {
  112.         val <<= 3;
  113.         val ^= string[i];
  114.         val ^= (val & 0xff00) >> 5;
  115.         val ^= (val & 0xff0000) >> 16;
  116.     }
  117.     return val % WS_HASH_TABLE_SIZE;
  118. }