2
Copyright (c) 2003 by Juliusz Chroboczek
4
Permission is hereby granted, free of charge, to any person obtaining a copy
5
of this software and associated documentation files (the "Software"), to deal
6
in the Software without restriction, including without limitation the rights
7
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
copies of the Software, and to permit persons to whom the Software is
9
furnished to do so, subject to the following conditions:
11
The above copyright notice and this permission notice shall be included in
12
all copies or substantial portions of the Software.
14
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30
#define LOG2_NUMBUCKETS 10
31
#define NUMBUCKETS (1 << LOG2_NUMBUCKETS)
38
for(i = 0; string[i] != '\0'; i++)
39
u = (u<<5) + (u >> (LOG2_NUMBUCKETS - 5)) + (unsigned char)string[i];
40
return (u & (NUMBUCKETS - 1));
46
if(a >= 'A' && a <= 'Z')
53
strcpy_lwr(char *dst, char *src)
65
strcmp_lwr(char *a, char *b)
67
while(*a != '\0' && *b != '\0') {
68
if(lwr(*a) != lwr(*b)) {
88
return calloc(NUMBUCKETS, sizeof(HashBucketPtr));
92
destroyHashTable(HashTablePtr table)
97
for(i = 0; i < NUMBUCKETS; i++) {
100
table[i] = table[i]->next;
110
getHash(HashTablePtr table, char *key)
114
for(bp = table[i]; bp; bp = bp->next) {
115
if(strcmp_lwr(bp->key, key) == 0)
122
putHash(HashTablePtr table, char *key, char *value, int prio)
125
char *keycopy = NULL, *valuecopy = NULL;
127
for(bp = table[i]; bp; bp = bp->next) {
128
if(strcmp_lwr(bp->key, key) == 0) {
129
if(prio > bp->prio) {
130
keycopy = malloc(strlen(key) + 1);
131
if(keycopy == NULL) goto fail;
132
strcpy_lwr(keycopy, key);
133
valuecopy = malloc(strlen(value) + 1);
134
if(valuecopy == NULL) goto fail;
135
strcpy(valuecopy, value);
139
bp->value = valuecopy;
144
keycopy = malloc(strlen(key) + 1);
147
strcpy_lwr(keycopy, key);
148
valuecopy = malloc(strlen(value) + 1);
149
if(valuecopy == NULL)
151
strcpy(valuecopy, value);
152
bp = malloc(sizeof(HashBucketRec));
156
bp->value = valuecopy;
163
if(keycopy) free(keycopy);
164
if(valuecopy) free(valuecopy);
169
hashElements(HashTablePtr table)
175
for(i = 0; i < NUMBUCKETS; i++) {
176
for(bp = table[i]; bp; bp = bp->next) {
184
key_first_cmp(const void *v1, const void *v2)
186
const HashBucketPtr *b1 = v1, *b2 = v2;
187
int c1 = strcmp_lwr((*b1)->key, (*b2)->key);
188
if(c1 != 0) return c1;
189
return strcmp((*b1)->value, (*b2)->value);
193
value_first_cmp(const void *v1, const void *v2)
195
const HashBucketPtr *b1 = v1, *b2 = v2;
196
int c1 = strcmp((*b1)->value, (*b2)->value);
197
if(c1 != 0) return c1;
198
return strcmp_lwr((*b1)->key, (*b2)->key);
202
hashArray(HashTablePtr table, int value_first)
207
n = hashElements(table);
208
dst = malloc((n + 1) * sizeof(HashBucketPtr));
213
for(i = 0; i < NUMBUCKETS; i++) {
216
table[i] = table[i]->next;
219
qsort(dst, j, sizeof(HashBucketPtr),
220
value_first ? value_first_cmp : key_first_cmp);
228
destroyHashArray(HashBucketPtr *array)
233
free(array[i]->value);