xref: /netbsd-src/crypto/external/bsd/heimdal/dist/lib/asn1/hash.c (revision d3273b5b76f5afaafe308cead5511dbb8df8c5e9)
1*d3273b5bSchristos /*	$NetBSD: hash.c,v 1.2 2017/01/28 21:31:45 christos Exp $	*/
2ca1c9b0cSelric 
3ca1c9b0cSelric /*
4ca1c9b0cSelric  * Copyright (c) 1997 Kungliga Tekniska Högskolan
5ca1c9b0cSelric  * (Royal Institute of Technology, Stockholm, Sweden).
6ca1c9b0cSelric  * All rights reserved.
7ca1c9b0cSelric  *
8ca1c9b0cSelric  * Redistribution and use in source and binary forms, with or without
9ca1c9b0cSelric  * modification, are permitted provided that the following conditions
10ca1c9b0cSelric  * are met:
11ca1c9b0cSelric  *
12ca1c9b0cSelric  * 1. Redistributions of source code must retain the above copyright
13ca1c9b0cSelric  *    notice, this list of conditions and the following disclaimer.
14ca1c9b0cSelric  *
15ca1c9b0cSelric  * 2. Redistributions in binary form must reproduce the above copyright
16ca1c9b0cSelric  *    notice, this list of conditions and the following disclaimer in the
17ca1c9b0cSelric  *    documentation and/or other materials provided with the distribution.
18ca1c9b0cSelric  *
19ca1c9b0cSelric  * 3. Neither the name of the Institute nor the names of its contributors
20ca1c9b0cSelric  *    may be used to endorse or promote products derived from this software
21ca1c9b0cSelric  *    without specific prior written permission.
22ca1c9b0cSelric  *
23ca1c9b0cSelric  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ca1c9b0cSelric  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ca1c9b0cSelric  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ca1c9b0cSelric  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ca1c9b0cSelric  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ca1c9b0cSelric  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ca1c9b0cSelric  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ca1c9b0cSelric  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ca1c9b0cSelric  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ca1c9b0cSelric  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ca1c9b0cSelric  * SUCH DAMAGE.
34ca1c9b0cSelric  */
35ca1c9b0cSelric 
36ca1c9b0cSelric /*
37ca1c9b0cSelric  * Hash table functions
38ca1c9b0cSelric  */
39ca1c9b0cSelric 
40ca1c9b0cSelric #include "gen_locl.h"
41ca1c9b0cSelric 
42*d3273b5bSchristos __RCSID("$NetBSD: hash.c,v 1.2 2017/01/28 21:31:45 christos Exp $");
43ca1c9b0cSelric 
44ca1c9b0cSelric static Hashentry *_search(Hashtab * htab,	/* The hash table */
45ca1c9b0cSelric 			  void *ptr);	/* And key */
46ca1c9b0cSelric 
47ca1c9b0cSelric Hashtab *
hashtabnew(int sz,int (* cmp)(void *,void *),unsigned (* hash)(void *))48ca1c9b0cSelric hashtabnew(int sz,
49ca1c9b0cSelric 	   int (*cmp) (void *, void *),
50ca1c9b0cSelric 	   unsigned (*hash) (void *))
51ca1c9b0cSelric {
52ca1c9b0cSelric     Hashtab *htab;
53ca1c9b0cSelric     int i;
54ca1c9b0cSelric 
55ca1c9b0cSelric     assert(sz > 0);
56ca1c9b0cSelric 
57ca1c9b0cSelric     htab = (Hashtab *) malloc(sizeof(Hashtab) + (sz - 1) * sizeof(Hashentry *));
58ca1c9b0cSelric     if (htab == NULL)
59ca1c9b0cSelric 	return NULL;
60ca1c9b0cSelric 
61ca1c9b0cSelric     for (i = 0; i < sz; ++i)
62ca1c9b0cSelric 	htab->tab[i] = NULL;
63ca1c9b0cSelric 
64ca1c9b0cSelric     htab->cmp = cmp;
65ca1c9b0cSelric     htab->hash = hash;
66ca1c9b0cSelric     htab->sz = sz;
67ca1c9b0cSelric     return htab;
68ca1c9b0cSelric }
69ca1c9b0cSelric 
70ca1c9b0cSelric /* Intern search function */
71ca1c9b0cSelric 
72ca1c9b0cSelric static Hashentry *
_search(Hashtab * htab,void * ptr)73ca1c9b0cSelric _search(Hashtab * htab, void *ptr)
74ca1c9b0cSelric {
75ca1c9b0cSelric     Hashentry *hptr;
76ca1c9b0cSelric 
77ca1c9b0cSelric     assert(htab && ptr);
78ca1c9b0cSelric 
79ca1c9b0cSelric     for (hptr = htab->tab[(*htab->hash) (ptr) % htab->sz];
80ca1c9b0cSelric 	 hptr;
81ca1c9b0cSelric 	 hptr = hptr->next)
82ca1c9b0cSelric 	if ((*htab->cmp) (ptr, hptr->ptr) == 0)
83ca1c9b0cSelric 	    break;
84ca1c9b0cSelric     return hptr;
85ca1c9b0cSelric }
86ca1c9b0cSelric 
87ca1c9b0cSelric /* Search for element in hash table */
88ca1c9b0cSelric 
89ca1c9b0cSelric void *
hashtabsearch(Hashtab * htab,void * ptr)90ca1c9b0cSelric hashtabsearch(Hashtab * htab, void *ptr)
91ca1c9b0cSelric {
92ca1c9b0cSelric     Hashentry *tmp;
93ca1c9b0cSelric 
94ca1c9b0cSelric     tmp = _search(htab, ptr);
95ca1c9b0cSelric     return tmp ? tmp->ptr : tmp;
96ca1c9b0cSelric }
97ca1c9b0cSelric 
98ca1c9b0cSelric /* add element to hash table */
99ca1c9b0cSelric /* if already there, set new value */
100ca1c9b0cSelric /* !NULL if succesful */
101ca1c9b0cSelric 
102ca1c9b0cSelric void *
hashtabadd(Hashtab * htab,void * ptr)103ca1c9b0cSelric hashtabadd(Hashtab * htab, void *ptr)
104ca1c9b0cSelric {
105ca1c9b0cSelric     Hashentry *h = _search(htab, ptr);
106ca1c9b0cSelric     Hashentry **tabptr;
107ca1c9b0cSelric 
108ca1c9b0cSelric     assert(htab && ptr);
109ca1c9b0cSelric 
110ca1c9b0cSelric     if (h)
111ca1c9b0cSelric 	free((void *) h->ptr);
112ca1c9b0cSelric     else {
113ca1c9b0cSelric 	h = (Hashentry *) malloc(sizeof(Hashentry));
114ca1c9b0cSelric 	if (h == NULL) {
115ca1c9b0cSelric 	    return NULL;
116ca1c9b0cSelric 	}
117ca1c9b0cSelric 	tabptr = &htab->tab[(*htab->hash) (ptr) % htab->sz];
118ca1c9b0cSelric 	h->next = *tabptr;
119ca1c9b0cSelric 	*tabptr = h;
120ca1c9b0cSelric 	h->prev = tabptr;
121ca1c9b0cSelric 	if (h->next)
122ca1c9b0cSelric 	    h->next->prev = &h->next;
123ca1c9b0cSelric     }
124ca1c9b0cSelric     h->ptr = ptr;
125ca1c9b0cSelric     return h;
126ca1c9b0cSelric }
127ca1c9b0cSelric 
128ca1c9b0cSelric /* delete element with key key. Iff freep, free Hashentry->ptr */
129ca1c9b0cSelric 
130ca1c9b0cSelric int
_hashtabdel(Hashtab * htab,void * ptr,int freep)131ca1c9b0cSelric _hashtabdel(Hashtab * htab, void *ptr, int freep)
132ca1c9b0cSelric {
133ca1c9b0cSelric     Hashentry *h;
134ca1c9b0cSelric 
135ca1c9b0cSelric     assert(htab && ptr);
136ca1c9b0cSelric 
137ca1c9b0cSelric     h = _search(htab, ptr);
138ca1c9b0cSelric     if (h) {
139ca1c9b0cSelric 	if (freep)
140ca1c9b0cSelric 	    free(h->ptr);
141ca1c9b0cSelric 	if ((*(h->prev) = h->next))
142ca1c9b0cSelric 	    h->next->prev = h->prev;
143ca1c9b0cSelric 	free(h);
144ca1c9b0cSelric 	return 0;
145ca1c9b0cSelric     } else
146ca1c9b0cSelric 	return -1;
147ca1c9b0cSelric }
148ca1c9b0cSelric 
149ca1c9b0cSelric /* Do something for each element */
150ca1c9b0cSelric 
151ca1c9b0cSelric void
hashtabforeach(Hashtab * htab,int (* func)(void * ptr,void * arg),void * arg)152ca1c9b0cSelric hashtabforeach(Hashtab * htab, int (*func) (void *ptr, void *arg),
153ca1c9b0cSelric 	       void *arg)
154ca1c9b0cSelric {
155ca1c9b0cSelric     Hashentry **h, *g;
156ca1c9b0cSelric 
157ca1c9b0cSelric     assert(htab);
158ca1c9b0cSelric 
159ca1c9b0cSelric     for (h = htab->tab; h < &htab->tab[htab->sz]; ++h)
160ca1c9b0cSelric 	for (g = *h; g; g = g->next)
161ca1c9b0cSelric 	    if ((*func) (g->ptr, arg))
162ca1c9b0cSelric 		return;
163ca1c9b0cSelric }
164ca1c9b0cSelric 
165ca1c9b0cSelric /* standard hash-functions for strings */
166ca1c9b0cSelric 
167ca1c9b0cSelric unsigned
hashadd(const char * s)168ca1c9b0cSelric hashadd(const char *s)
169ca1c9b0cSelric {				/* Standard hash function */
170ca1c9b0cSelric     unsigned i;
171ca1c9b0cSelric 
172ca1c9b0cSelric     assert(s);
173ca1c9b0cSelric 
174ca1c9b0cSelric     for (i = 0; *s; ++s)
175ca1c9b0cSelric 	i += *s;
176ca1c9b0cSelric     return i;
177ca1c9b0cSelric }
178ca1c9b0cSelric 
179ca1c9b0cSelric unsigned
hashcaseadd(const char * s)180ca1c9b0cSelric hashcaseadd(const char *s)
181ca1c9b0cSelric {				/* Standard hash function */
182ca1c9b0cSelric     unsigned i;
183ca1c9b0cSelric 
184ca1c9b0cSelric     assert(s);
185ca1c9b0cSelric 
186ca1c9b0cSelric     for (i = 0; *s; ++s)
187ca1c9b0cSelric 	i += toupper((unsigned char)*s);
188ca1c9b0cSelric     return i;
189ca1c9b0cSelric }
190ca1c9b0cSelric 
191ca1c9b0cSelric #define TWELVE (sizeof(unsigned))
192ca1c9b0cSelric #define SEVENTYFIVE (6*sizeof(unsigned))
193ca1c9b0cSelric #define HIGH_BITS (~((unsigned)(~0) >> TWELVE))
194ca1c9b0cSelric 
195ca1c9b0cSelric unsigned
hashjpw(const char * ss)196ca1c9b0cSelric hashjpw(const char *ss)
197ca1c9b0cSelric {				/* another hash function */
198ca1c9b0cSelric     unsigned h = 0;
199ca1c9b0cSelric     unsigned g;
200ca1c9b0cSelric     const unsigned char *s = (const unsigned char *)ss;
201ca1c9b0cSelric 
202ca1c9b0cSelric     for (; *s; ++s) {
203ca1c9b0cSelric 	h = (h << TWELVE) + *s;
204ca1c9b0cSelric 	if ((g = h & HIGH_BITS))
205ca1c9b0cSelric 	    h = (h ^ (g >> SEVENTYFIVE)) & ~HIGH_BITS;
206ca1c9b0cSelric     }
207ca1c9b0cSelric     return h;
208ca1c9b0cSelric }
209