HomePort
map.c
Go to the documentation of this file.
1 /*
2  * Copyright 2011 Aalborg University. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without modification, are
5  * permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice, this list of
8  * conditions and the following disclaimer.
9  *
10  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11  * of conditions and the following disclaimer in the documentation and/or other materials
12  * provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY Aalborg University ''AS IS'' AND ANY EXPRESS OR IMPLIED
15  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Aalborg University OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * The views and conclusions contained in the software and documentation are those of the
25  * authors and should not be interpreted as representing official policies, either expressed
26  */
27 
28 #include "hpd/hpd_types.h"
29 #include "hpd/common/hpd_map.h"
30 #include "hpd/common/hpd_common.h"
31 
32 TAILQ_HEAD(hpd_map, hpd_pair);
33 
34 struct hpd_pair {
35  TAILQ_ENTRY(hpd_pair) HPD_TAILQ_FIELD; //< Tailq members
36  char *k; //< Key (not null)
37  char *v; //< Value
38 };
39 
41 {
42  if (!map) return HPD_E_NULL;
43 
44  HPD_CALLOC(*map, 1, hpd_map_t);
45  TAILQ_INIT(*map);
46  return HPD_E_SUCCESS;
47 
48  alloc_error:
49  return HPD_E_ALLOC;
50 }
51 
53 {
54  if (!map || !pair) return HPD_E_NULL;
55 
56  (*pair) = TAILQ_FIRST(map);
57  return HPD_E_SUCCESS;
58 }
59 
61 {
62  if (!pair || !(*pair)) return HPD_E_NULL;
63 
64  (*pair) = TAILQ_NEXT(*pair, HPD_TAILQ_FIELD);
65  return HPD_E_SUCCESS;
66 }
67 
69 {
70  if (!map || !pair) return HPD_E_NULL;
71 
72  TAILQ_REMOVE(map, pair, HPD_TAILQ_FIELD);
73  free(pair->k);
74  free(pair->v);
75  free(pair);
76  return HPD_E_SUCCESS;
77 }
78 
80 {
81  if (!map) return HPD_E_NULL;
82 
84  hpd_pair_t *pair, *tmp;
85  TAILQ_FOREACH_SAFE(pair, map, HPD_TAILQ_FIELD, tmp) {
86  rc = hpd_map_remove(map, pair);
87  }
88  free(map);
89  return rc;
90 }
91 
92 hpd_error_t hpd_map_get(hpd_map_t *map, const char *k, const char **v)
93 {
94  if (!map || !k || !v) return HPD_E_NULL;
95 
96  hpd_pair_t *attr;
97  (*v) = NULL;
98  TAILQ_FOREACH(attr, map, HPD_TAILQ_FIELD) {
99  if (strcmp(attr->k, k) == 0) {
100  (*v) = attr->v;
101  return HPD_E_SUCCESS;
102  }
103  }
104  return HPD_E_NOT_FOUND;
105 }
106 
107 hpd_error_t hpd_map_get_n(hpd_map_t *map, const char *k, size_t k_len, const char **v)
108 {
109  if (!map || !k || !v) return HPD_E_NULL;
110 
111  hpd_pair_t *attr;
112  (*v) = NULL;
113  TAILQ_FOREACH(attr, map, HPD_TAILQ_FIELD) {
114  if (strncmp(attr->k, k, k_len) == 0) {
115  (*v) = attr->v;
116  return HPD_E_SUCCESS;
117  }
118  }
119  (*v) = NULL;
120  return HPD_E_NOT_FOUND;
121 }
122 
123 static hpd_error_t map_insert(hpd_map_t *map, const char *k, const char *v)
124 {
125  hpd_pair_t *attr = NULL;
126  HPD_CALLOC(attr, 1, hpd_pair_t);
127  HPD_STR_CPY(attr->k, k);
128  HPD_STR_CPY(attr->v, v);
129  TAILQ_INSERT_TAIL(map, attr, tailq);
130  return HPD_E_SUCCESS;
131 
132  alloc_error:
133  if (attr) {
134  free(attr->k);
135  free(attr->v);
136  free(attr);
137  }
138  return HPD_E_ALLOC;
139 }
140 
141 static hpd_error_t map_replace(hpd_pair_t *attr, const char *v) {
142  HPD_STR_CPY(attr->v, v);
143  return HPD_E_SUCCESS;
144 
145  alloc_error:
146  return HPD_E_ALLOC;
147 }
148 
149 static hpd_error_t map_insert_n(hpd_map_t *map, const char *k, size_t k_len, const char *v, size_t v_len)
150 {
151  hpd_pair_t *attr = NULL;
152  HPD_CALLOC(attr, 1, hpd_pair_t);
153  HPD_STR_N_CPY(attr->k, k, k_len);
154  HPD_STR_N_CPY(attr->v, v, v_len);
155  TAILQ_INSERT_TAIL(map, attr, tailq);
156  return HPD_E_SUCCESS;
157 
158  alloc_error:
159  if (attr) {
160  free(attr->k);
161  free(attr->v);
162  free(attr);
163  }
164  return HPD_E_ALLOC;
165 }
166 
167 static hpd_error_t map_replace_n(hpd_pair_t *attr, const char *v, size_t v_len) {
168  HPD_STR_N_CPY(attr->v, v, v_len);
169  return HPD_E_SUCCESS;
170 
171  alloc_error:
172  return HPD_E_ALLOC;
173 }
174 
175 hpd_error_t hpd_map_set(hpd_map_t *map, const char *k, const char *v)
176 {
177  if (!map || !k) return HPD_E_NULL;
178 
179  hpd_error_t rc;
180  hpd_pair_t *attr = NULL;
181  TAILQ_FOREACH(attr, map, HPD_TAILQ_FIELD)
182  if (strcmp(attr->k, k) == 0)
183  break;
184 
185  if (v == NULL) {
186  if (attr && (rc = hpd_map_remove(map, attr))) return rc;
187  return HPD_E_SUCCESS;
188  } else if (!attr) {
189  return map_insert(map, k, v);
190  } else {
191  return map_replace(attr, v);
192  }
193 }
194 
195 hpd_error_t hpd_map_set_n(hpd_map_t *map, const char *k, size_t k_len, const char *v, size_t v_len)
196 {
197  if (!map || !k) return HPD_E_NULL;
198 
199  hpd_error_t rc;
200  hpd_pair_t *attr = NULL;
201  TAILQ_FOREACH(attr, map, HPD_TAILQ_FIELD)
202  if (strncmp(attr->k, k, k_len) == 0)
203  break;
204 
205  if (v == NULL) {
206  if (attr && (rc = hpd_map_remove(map, attr))) return rc;
207  return HPD_E_SUCCESS;
208  } else if (!attr) {
209  return map_insert_n(map, k, k_len, v, v_len);
210  } else {
211  return map_replace_n(attr, v, v_len);
212  }
213 }
214 
216 {
217  if (!map) return HPD_E_NULL;
218 
219  const char *key, *val, *val2;
220  while ((key = va_arg(vp, const char *))) {
221  val = va_arg(vp, const char *);
222  if (!val) return HPD_E_NULL;
223  hpd_map_get(map, key, &val2);
224  if (!val2 || strcmp(val, val2) != 0) return HPD_E_NOT_FOUND;
225  }
226  return HPD_E_SUCCESS;
227 }
228 
229 hpd_error_t hpd_pair_get(const hpd_pair_t *pair, const char **key, const char **value)
230 {
231  if (!pair || (!key && !value)) return HPD_E_NULL;
232 
233  if (key) (*key) = pair->k;
234  if (value) (*value) = pair->v;
235  return HPD_E_SUCCESS;
236 }
hpd_error_t hpd_map_v_matches(hpd_map_t *map, va_list vp)
Definition: map.c:215
static hpd_error_t map_insert_n(hpd_map_t *map, const char *k, size_t k_len, const char *v, size_t v_len)
Definition: map.c:149
#define HPD_STR_CPY(DST, SRC)
Definition: hpd_common.h:64
hpd_error_t hpd_map_remove(hpd_map_t *map, hpd_pair_t *pair)
Definition: map.c:68
static hpd_error_t map_insert(hpd_map_t *map, const char *k, const char *v)
Definition: map.c:123
hpd_error_t hpd_pair_get(const hpd_pair_t *pair, const char **key, const char **value)
[hpd_action_t functions]
Definition: map.c:229
data value
Definition: map.c:34
free(data.url)
#define HPD_STR_N_CPY(DST, SRC, LEN)
Definition: hpd_common.h:69
#define HPD_TAILQ_FIELD
Definition: hpd_queue.h:37
#define HPD_CALLOC(PTR, NUM, CAST)
Allocates and zeros a structure.
Definition: hpd_common.h:44
hpd_error_t hpd_map_alloc(hpd_map_t **map)
Definition: map.c:40
TAILQ_HEAD(hpd_map, hpd_pair)
data key
hpd_error_t hpd_map_set(hpd_map_t *map, const char *k, const char *v)
Definition: map.c:175
enum hpd_error hpd_error_t
Definition: hpd_types.h:167
hpd_error_t hpd_map_get(hpd_map_t *map, const char *k, const char **v)
Definition: map.c:92
hpd_error_t hpd_map_next(hpd_pair_t **pair)
Definition: map.c:60
static hpd_error_t map_replace(hpd_pair_t *attr, const char *v)
Definition: map.c:141
hpd_error_t hpd_map_first(hpd_map_t *map, hpd_pair_t **pair)
Definition: map.c:52
hpd_error_t hpd_map_free(hpd_map_t *map)
Definition: map.c:79
static hpd_error_t map_replace_n(hpd_pair_t *attr, const char *v, size_t v_len)
Definition: map.c:167
hpd_error_t hpd_map_get_n(hpd_map_t *map, const char *k, size_t k_len, const char **v)
Definition: map.c:107
struct hpd_map hpd_map_t
Definition: hpd_map.h:40
hpd_error_t hpd_map_set_n(hpd_map_t *map, const char *k, size_t k_len, const char *v, size_t v_len)
Definition: map.c:195