]> git.ipfire.org Git - thirdparty/dhcp.git/blob - keama/data.h
copy rights update
[thirdparty/dhcp.git] / keama / data.h
1 /*
2 * Copyright (C) 2017-2022 Internet Systems Consortium, Inc. ("ISC")
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 * Internet Systems Consortium, Inc.
17 * PO Box 360
18 * Newmarket, NH 03857 USA
19 * <info@isc.org>
20 * http://www.isc.org/
21 */
22
23 #ifndef DATA_H
24 #define DATA_H
25
26 #include <stdint.h>
27 #include <stdio.h>
28
29 /* From FreeBSD sys/queue.h */
30
31 /*
32 * Tail queue declarations.
33 */
34 #define TAILQ_HEAD(name, type) \
35 struct name { \
36 struct type *tqh_first; /* first element */ \
37 struct type **tqh_last; /* addr of last next element */ \
38 }
39
40 #define TAILQ_ENTRY(type) \
41 struct { \
42 struct type *tqe_next; /* next element */ \
43 struct type **tqe_prev; /* address of previous next element */ \
44 }
45
46 /*
47 * Tail queue functions.
48 */
49 #define TAILQ_CONCAT(head1, head2) do { \
50 if (!TAILQ_EMPTY(head2)) { \
51 *(head1)->tqh_last = (head2)->tqh_first; \
52 (head2)->tqh_first->next.tqe_prev = (head1)->tqh_last; \
53 (head1)->tqh_last = (head2)->tqh_last; \
54 TAILQ_INIT((head2)); \
55 } \
56 } while (0)
57
58 #define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
59
60 #define TAILQ_FIRST(head) ((head)->tqh_first)
61
62 #define TAILQ_FOREACH(var, head) \
63 for ((var) = TAILQ_FIRST((head)); \
64 (var); \
65 (var) = TAILQ_NEXT((var)))
66
67 #define TAILQ_FOREACH_SAFE(var, head, tvar) \
68 for ((var) = TAILQ_FIRST((head)); \
69 (var) && ((tvar) = TAILQ_NEXT((var)), 1); \
70 (var) = (tvar))
71
72 #define TAILQ_INIT(head) do { \
73 TAILQ_FIRST((head)) = NULL; \
74 (head)->tqh_last = &TAILQ_FIRST((head)); \
75 } while (0)
76
77 #define TAILQ_INSERT_AFTER(head, listelm, elm) do { \
78 if ((TAILQ_NEXT((elm)) = TAILQ_NEXT((listelm))) != NULL) \
79 TAILQ_NEXT((elm))->next.tqe_prev = \
80 &TAILQ_NEXT((elm)); \
81 else { \
82 (head)->tqh_last = &TAILQ_NEXT((elm)); \
83 } \
84 TAILQ_NEXT((listelm)) = (elm); \
85 (elm)->next.tqe_prev = &TAILQ_NEXT((listelm)); \
86 } while (0)
87
88 #define TAILQ_INSERT_BEFORE(listelm, elm) do { \
89 (elm)->next.tqe_prev = (listelm)->next.tqe_prev; \
90 TAILQ_NEXT((elm)) = (listelm); \
91 *(listelm)->next.tqe_prev = (elm); \
92 (listelm)->next.tqe_prev = &TAILQ_NEXT((elm)); \
93 } while (0)
94
95 #define TAILQ_INSERT_HEAD(head, elm) do { \
96 if ((TAILQ_NEXT((elm)) = TAILQ_FIRST((head))) != NULL) \
97 TAILQ_FIRST((head))->next.tqe_prev = \
98 &TAILQ_NEXT((elm)); \
99 else \
100 (head)->tqh_last = &TAILQ_NEXT((elm)); \
101 TAILQ_FIRST((head)) = (elm); \
102 (elm)->next.tqe_prev = &TAILQ_FIRST((head)); \
103 } while (0)
104
105 #define TAILQ_INSERT_TAIL(head, elm) do { \
106 TAILQ_NEXT((elm)) = NULL; \
107 (elm)->next.tqe_prev = (head)->tqh_last; \
108 *(head)->tqh_last = (elm); \
109 (head)->tqh_last = &TAILQ_NEXT((elm)); \
110 } while (0)
111
112 #define TAILQ_LAST(head, headname) \
113 (*(((struct headname *)((head)->tqh_last))->tqh_last))
114
115 #define TAILQ_NEXT(elm) ((elm)->next.tqe_next)
116
117 #define TAILQ_PREV(elm, headname) \
118 (*(((struct headname *)((elm)->next.tqe_prev))->tqh_last))
119
120 #define TAILQ_REMOVE(head, elm) do { \
121 if ((TAILQ_NEXT((elm))) != NULL) \
122 TAILQ_NEXT((elm))->next.tqe_prev = \
123 (elm)->next.tqe_prev; \
124 else \
125 (head)->tqh_last = (elm)->next.tqe_prev; \
126 *(elm)->next.tqe_prev = TAILQ_NEXT((elm)); \
127 (elm)->next.tqe_next = (void *)-1; \
128 (elm)->next.tqe_prev = (void *)-1; \
129 } while (0)
130
131 #define TAILQ_SWAP(head1, head2, type) do { \
132 struct type *swap_first = (head1)->tqh_first; \
133 struct type **swap_last = (head1)->tqh_last; \
134 (head1)->tqh_first = (head2)->tqh_first; \
135 (head1)->tqh_last = (head2)->tqh_last; \
136 (head2)->tqh_first = swap_first; \
137 (head2)->tqh_last = swap_last; \
138 if ((swap_first = (head1)->tqh_first) != NULL) \
139 swap_first->next.tqe_prev = &(head1)->tqh_first; \
140 else \
141 (head1)->tqh_last = &(head1)->tqh_first; \
142 if ((swap_first = (head2)->tqh_first) != NULL) \
143 swap_first->next.tqe_prev = &(head2)->tqh_first; \
144 else \
145 (head2)->tqh_last = &(head2)->tqh_first; \
146 } while (0)
147
148 /* From bind9 lib/isc/include/isc/boolean.h */
149
150 typedef enum { isc_boolean_false = 0, isc_boolean_true = 1 } isc_boolean_t;
151
152 #define ISC_FALSE isc_boolean_false
153 #define ISC_TRUE isc_boolean_true
154 #define ISC_TF(x) ((x) ? ISC_TRUE : ISC_FALSE)
155
156 /* From Kea src/lib/cc/data.h */
157
158 struct element;
159
160 /* Element types */
161 #define ELEMENT_NONE 0
162 #define ELEMENT_INTEGER 1
163 #define ELEMENT_REAL 2
164 #define ELEMENT_BOOLEAN 3
165 #define ELEMENT_NULL 4
166 #define ELEMENT_STRING 5
167 #define ELEMENT_LIST 6
168 #define ELEMENT_MAP 7
169
170 /* Element string */
171 struct string {
172 size_t length; /* string length */
173 char *content; /* string data */
174 };
175
176 struct string *allocString(void);
177 /* In makeString() l == -1 means use strlen(s) */
178 struct string *makeString(int l, const char *s);
179 /* format ZlLsSbBfXI6 + h */
180 struct string *makeStringExt(int l, const char *s, char fmt);
181 /* format 6lLIsSbBj */
182 struct string *makeStringArray(int l, const char *s, char fmt);
183 void appendString(struct string *s, const char *a);
184 void concatString(struct string *s, const struct string *a);
185 isc_boolean_t eqString(const struct string *s, const struct string *o);
186 /* quoting */
187 struct string *quote(struct string *);
188
189 /* Comments */
190 struct comment {
191 char *line; /* comment line */
192 TAILQ_ENTRY(comment) next; /* next line */
193 };
194 TAILQ_HEAD(comments, comment);
195
196 struct comment *createComment(const char *line);
197
198 /* Element list */
199 TAILQ_HEAD(list, element);
200
201 /* Element map */
202 TAILQ_HEAD(map, element);
203
204 /* Element value */
205 union value {
206 int64_t int_value; /* integer */
207 double double_value; /* real */
208 isc_boolean_t bool_value; /* boolean */
209 /**/ /* null */
210 struct string string_value; /* string */
211 struct list list_value; /* list */
212 struct map map_value; /* map */
213 };
214
215 /* Element */
216 struct element {
217 int type; /* element type (ELEMENT_XXX) */
218 int kind; /* element kind (e.g. ROOT_GROUP) */
219 isc_boolean_t skip; /* skip as not converted */
220 char *key; /* element key (for map) */
221 union value value; /* value */
222 struct comments comments; /* associated comments */
223 TAILQ_ENTRY(element) next; /* next item in list or map chain */
224 };
225
226 /* Value getters */
227 int64_t intValue(const struct element *e);
228 double doubleValue(const struct element *e);
229 isc_boolean_t boolValue(const struct element *e);
230 struct string *stringValue(struct element *e);
231 struct list *listValue(struct element *e);
232 struct map *mapValue(struct element *e);
233
234 /* Creators */
235 struct element *create(void);
236 struct element *createInt(int64_t i);
237 struct element *createDouble(double d);
238 struct element *createBool(isc_boolean_t b);
239 struct element *createNull(void);
240 struct element *createString(const struct string *s);
241 struct element *createList(void);
242 struct element *createMap(void);
243
244 /* Reset */
245 void resetInt(struct element *e, int64_t i);
246 void resetDouble(struct element *e, double d);
247 void resetBool(struct element *e, isc_boolean_t b);
248 void resetNull(struct element *e);
249 void resetString(struct element *e, const struct string *s);
250 void resetList(struct element *e);
251 void resetMap(struct element *e);
252 void resetBy(struct element *e, struct element *o);
253
254 /* List functions */
255 struct element *listGet(struct element *l, int i);
256 void listSet(struct element *l, struct element *e, int i);
257 void listPush(struct element *l, struct element *e);
258 void listRemove(struct element *l, int i);
259 size_t listSize(const struct element *l);
260 void concat(struct element *l, struct element *o);
261
262 /* Map functions */
263 struct element *mapGet(struct element *m, const char *k);
264 void mapSet(struct element *m, struct element *e, const char *k);
265 void mapRemove(struct element *m, const char *k);
266 isc_boolean_t mapContains(const struct element *m, const char *k);
267 size_t mapSize(const struct element *m);
268 void merge(struct element *m, struct element *o);
269
270 /* Tools */
271 const char *type2name(int t);
272 int name2type(const char *n);
273 void print(FILE *fp, const struct element *e,
274 isc_boolean_t skip, unsigned indent);
275 void printList(FILE *fp, const struct list *l,
276 isc_boolean_t skip, unsigned indent);
277 void printMap(FILE *fp, const struct map *m,
278 isc_boolean_t skip, unsigned indent);
279 void printString(FILE *fp, const struct string *s);
280 isc_boolean_t skip_to_end(const struct element *e);
281
282 struct element *copy(struct element *e);
283 struct element *copyList(struct element *l);
284 struct element *copyMap(struct element *m);
285
286 /* Handles */
287 TAILQ_HEAD(handles, handle);
288
289 struct handle {
290 unsigned order; /* order */
291 char *key; /* key */
292 struct element *value; /* value */
293 struct handles values; /* children */
294 TAILQ_ENTRY(handle) next; /* siblings */
295 };
296
297 struct handle* mapPop(struct element *);
298 void derive(struct handle *, struct handle *);
299
300 /* Hexadecimal literals */
301 struct string *hexaValue(struct element *);
302 struct element *createHexa(struct string *);
303
304 #endif /* DATA_H */