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