Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

wshash.c

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /*
00058  *
00059  * wshash.c
00060  *
00061  * Author: Markku Rossi <mtr@iki.fi>
00062  *
00063  * Copyright (c) 1999-2000 WAPIT OY LTD.
00064  *       All rights reserved.
00065  *
00066  * A mapping from null-terminated strings to `void *' pointers.
00067  *
00068  */
00069 
00070 #include "wsint.h"
00071 #include "wshash.h"
00072 
00073 /********************* Types and definitions ****************************/
00074 
00075 /* The size of the hash table. */
00076 #define WS_HASH_TABLE_SIZE  256
00077 
00078 /* A hash item. */
00079 struct WsHashItemRec
00080 {
00081     struct WsHashItemRec *next;
00082     char *name;
00083     void *data;
00084 };
00085 
00086 typedef struct WsHashItemRec WsHashItem;
00087 
00088 /* The hash object. */
00089 struct WsHashRec
00090 {
00091     WsHashItem *items[WS_HASH_TABLE_SIZE];
00092     WsHashItemDestructor destructor;
00093     void *destructor_context;
00094 };
00095 
00096 /********************* Prototypes for static functions ******************/
00097 
00098 /* Hash function to count the hash value of string `string'.  */
00099 static size_t count_hash(const char *string);
00100 
00101 /********************* Global functions *********************************/
00102 
00103 WsHashPtr ws_hash_create(WsHashItemDestructor destructor, void *context)
00104 {
00105     WsHashPtr hash = ws_calloc(1, sizeof(*hash));
00106 
00107     if (hash) {
00108         hash->destructor = destructor;
00109         hash->destructor_context = context;
00110     }
00111 
00112     return hash;
00113 }
00114 
00115 
00116 void ws_hash_destroy(WsHashPtr hash)
00117 {
00118     if (hash == NULL)
00119         return;
00120 
00121     ws_hash_clear(hash);
00122     ws_free(hash);
00123 }
00124 
00125 
00126 WsBool ws_hash_put(WsHashPtr hash, const char *name, void *data)
00127 {
00128     WsHashItem *i;
00129     size_t h = count_hash(name);
00130 
00131     for (i = hash->items[h]; i; i = i->next) {
00132         if (strcmp(i->name, name) == 0) {
00133             /* Found it. */
00134 
00135             /* Destroy the old item */
00136             if (hash->destructor)
00137                 (*hash->destructor)(i->data, hash->destructor_context);
00138 
00139             i->data = data;
00140 
00141             return WS_FALSE;
00142         }
00143     }
00144 
00145     /* Must create a new mapping. */
00146     i = ws_calloc(1, sizeof(*i));
00147 
00148     if (i == NULL)
00149         return WS_FALSE;
00150 
00151     i->name = ws_strdup(name);
00152     if (i->name == NULL) {
00153         ws_free(i);
00154         return WS_FALSE;
00155     }
00156 
00157     i->data = data;
00158 
00159     /* Link it to our hash. */
00160     i->next = hash->items[h];
00161     hash->items[h] = i;
00162 
00163     return WS_TRUE;
00164 }
00165 
00166 
00167 void *ws_hash_get(WsHashPtr hash, const char *name)
00168 {
00169     WsHashItem *i;
00170     size_t h = count_hash(name);
00171 
00172     for (i = hash->items[h]; i; i = i->next)
00173         if (strcmp(i->name, name) == 0)
00174             return i->data;
00175 
00176     return NULL;
00177 }
00178 
00179 
00180 void ws_hash_clear(WsHashPtr hash)
00181 {
00182     WsHashItem *i, *n;
00183     size_t j;
00184 
00185     for (j = 0; j < WS_HASH_TABLE_SIZE; j++) {
00186         for (i = hash->items[j]; i; i = n) {
00187             n = i->next;
00188             if (hash->destructor)
00189                 (*hash->destructor)(i->data, hash->destructor_context);
00190 
00191             ws_free(i->name);
00192             ws_free(i);
00193         }
00194         hash->items[j] = NULL;
00195     }
00196 }
00197 
00198 /********************* Static functions *********************************/
00199 
00200 static size_t count_hash(const char *string)
00201 {
00202     size_t val = 0;
00203     int i;
00204 
00205     for (i = 0; string[i]; i++) {
00206         val <<= 3;
00207         val ^= string[i];
00208         val ^= (val & 0xff00) >> 5;
00209         val ^= (val & 0xff0000) >> 16;
00210     }
00211 
00212     return val % WS_HASH_TABLE_SIZE;
00213 }
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.