Formatting changes.
[radsecproxy.git] / hash.c
1 /* Copyright (c) 2006-2010, UNINETT AS
2  * Copyright (c) 2010-2012, NORDUnet A/S */
3 /* See LICENSE for licensing information. */
4
5 #include <stdlib.h>
6 #include <string.h>
7 #include <pthread.h>
8 #include "list.h"
9 #include "hash.h"
10
11 /* allocates and initialises hash structure; returns NULL if malloc fails */
12 struct hash *hash_create() {
13     struct hash *h = malloc(sizeof(struct hash));
14     if (!h)
15         return NULL;
16     h->hashlist = list_create();
17     if (!h->hashlist) {
18         free(h);
19         return NULL;
20     }
21     pthread_mutex_init(&h->mutex, NULL);
22     return h;
23 }
24
25 /* frees all memory associated with the hash */
26 void hash_destroy(struct hash *h) {
27     struct list_node *ln;
28
29     if (!h)
30         return;
31     for (ln = list_first(h->hashlist); ln; ln = list_next(ln)) {
32         free(((struct hash_entry *)ln->data)->key);
33         free(((struct hash_entry *)ln->data)->data);
34     }
35     list_destroy(h->hashlist);
36     pthread_mutex_destroy(&h->mutex);
37 }
38
39 /* insert entry in hash; returns 1 if ok, 0 if malloc fails */
40 int hash_insert(struct hash *h, void *key, uint32_t keylen, void *data) {
41     struct hash_entry *e;
42
43     if (!h)
44         return 0;
45     e = malloc(sizeof(struct hash_entry));
46     if (!e)
47         return 0;
48     memset(e, 0, sizeof(struct hash_entry));
49     e->key = malloc(keylen);
50     if (!e->key) {
51         free(e);
52         return 0;
53     }
54     memcpy(e->key, key, keylen);
55     e->keylen = keylen;
56     e->data = data;
57     pthread_mutex_lock(&h->mutex);
58     if (!list_push(h->hashlist, e)) {
59         pthread_mutex_unlock(&h->mutex);
60         free(e->key);
61         free(e);
62         return 0;
63     }
64     pthread_mutex_unlock(&h->mutex);
65     return 1;
66 }
67
68 /* reads entry from hash */
69 void *hash_read(struct hash *h, void *key, uint32_t keylen) {
70     struct list_node *ln;
71     struct hash_entry *e;
72
73     if (!h)
74         return 0;
75     pthread_mutex_lock(&h->mutex);
76     for (ln = list_first(h->hashlist); ln; ln = list_next(ln)) {
77         e = (struct hash_entry *)ln->data;
78         if (e->keylen == keylen && !memcmp(e->key, key, keylen)) {
79             pthread_mutex_unlock(&h->mutex);
80             return e->data;
81         }
82     }
83     pthread_mutex_unlock(&h->mutex);
84     return NULL;
85 }
86
87 /* extracts entry from hash */
88 void *hash_extract(struct hash *h, void *key, uint32_t keylen) {
89     struct list_node *ln;
90     struct hash_entry *e;
91
92     if (!h)
93         return 0;
94     pthread_mutex_lock(&h->mutex);
95     for (ln = list_first(h->hashlist); ln; ln = list_next(ln)) {
96         e = (struct hash_entry *)ln->data;
97         if (e->keylen == keylen && !memcmp(e->key, key, keylen)) {
98             free(e->key);
99             list_removedata(h->hashlist, e);
100             free(e);
101             pthread_mutex_unlock(&h->mutex);
102             return e->data;
103         }
104     }
105     pthread_mutex_unlock(&h->mutex);
106     return NULL;
107 }
108
109 /* returns first entry */
110 struct hash_entry *hash_first(struct hash *hash) {
111     struct list_node *ln;
112     struct hash_entry *e;
113     if (!hash || !((ln = list_first(hash->hashlist))))
114         return NULL;
115     e = (struct hash_entry *)ln->data;
116     e->next = ln->next;
117     return e;
118 }
119
120 /* returns the next node after the argument */
121 struct hash_entry *hash_next(struct hash_entry *entry) {
122     struct hash_entry *e;
123     if (!entry || !entry->next)
124         return NULL;
125     e = (struct hash_entry *)entry->next->data;
126     e->next = (struct list_node *)entry->next->next;
127     return e;
128 }
129
130 /* Local Variables: */
131 /* c-file-style: "stroustrup" */
132 /* End: */