1 /* Structures for JSON parsing using only fixed-extent memory
2  *
3  * This file is Copyright (c) 2010-2019 by the GPSD project
4  * SPDX-License-Identifier: BSD-2-clause
5  */
6 
7 #include <ctype.h>
8 #include <stdbool.h>
9 #include <sys/time.h>      // for struct timespec
10 
11 /* the json_type is the type of the C variable the JSON
12  * value gets placed in.  It is NOT the JSON type as used
13  * in the JSON standard.  But it does partly specify how
14  * the JSON value is decoded.
15  *
16  * For example a t_character must be in quotes, but a t_byte
17  * is a bare number. */
18 typedef enum {t_integer, t_uinteger, t_real,
19 	      t_string, t_boolean, t_character,
20 	      t_time,
21 	      t_object, t_structobject, t_array,
22 	      t_check, t_ignore,
23 	      t_short, t_ushort, t_byte, t_ubyte}
24     json_type;
25 
26 struct json_enum_t {
27     char	*name;
28     int		value;
29 };
30 
31 struct json_array_t {
32     json_type element_type;
33     union {
34 	struct {
35 	    const struct json_attr_t *subtype;
36 	    char *base;
37 	    size_t stride;
38 	} objects;
39 	struct {
40 	    char **ptrs;
41 	    char *store;
42 	    int storelen;
43 	} strings;
44 	struct {
45 	    int *store;
46 	} bytes;
47 	struct {
48 	    unsigned int *store;
49 	} ubytes;
50 	struct {
51 	    int *store;
52 	} integers;
53 	struct {
54 	    unsigned int *store;
55 	} uintegers;
56 	struct {
57 	    short *store;
58 	} shorts;
59 	struct {
60 	    unsigned short *store;
61 	} ushorts;
62 	struct {
63 	    double *store;
64 	} reals;
65 	struct {
66 	    bool *store;
67 	} booleans;
68 	struct {
69 	    struct timespec *store;
70 	} timespecs;
71     } arr;
72     int *count, maxlen;
73 };
74 
75 struct json_attr_t {
76     char *attribute;
77     json_type type;
78     union {
79 	bool *boolean;
80 	char *byte;
81 	char *character;
82 	char *string;
83 	double *real;
84 	int *integer;
85 	short *shortint;
86 	size_t offset;
87 	struct json_array_t array;
88 	unsigned char *ubyte;
89 	unsigned int *uinteger;
90 	unsigned short *ushortint;
91         struct timespec *ts;
92     } addr;
93     union {
94 	bool boolean;
95 	char byte;
96 	char character;
97 	char *check;
98 	double real;
99 	int integer;
100 	short shortint;
101 	unsigned char ubyte;
102 	unsigned int uinteger;
103 	unsigned short ushortint;
104         struct timespec ts;
105     } dflt;
106     size_t len;
107     const struct json_enum_t *map;
108     bool nodefault;
109 };
110 
111 #define JSON_ATTR_MAX	31	/* max chars in JSON attribute name */
112 #define JSON_VAL_MAX	512	/* max chars in JSON value part */
113 
114 #ifdef __cplusplus
115 extern "C" {
116 #endif
117 int json_read_object(const char *, const struct json_attr_t *,
118 		     const char **);
119 int json_read_array(const char *, const struct json_array_t *,
120 		    const char **);
121 const char *json_error_string(int);
122 
123 void json_enable_debug(int, FILE *);
124 #ifdef __cplusplus
125 }
126 #endif
127 
128 #define JSON_ERR_OBSTART	1	/* non-WS when expecting object start */
129 #define JSON_ERR_ATTRSTART	2	/* non-WS when expecting attrib start */
130 #define JSON_ERR_BADATTR	3	/* unknown attribute name */
131 #define JSON_ERR_ATTRLEN	4	/* attribute name too long */
132 #define JSON_ERR_NOARRAY	5	/* saw [ when not expecting array */
133 #define JSON_ERR_NOBRAK 	6	/* array element specified, but no [ */
134 #define JSON_ERR_STRLONG	7	/* string value too long */
135 #define JSON_ERR_TOKLONG	8	/* token value too long */
136 #define JSON_ERR_BADTRAIL	9	/* garbage while expecting comma or } or ] */
137 #define JSON_ERR_ARRAYSTART	10	/* didn't find expected array start */
138 #define JSON_ERR_OBJARR 	11	/* error while parsing object array */
139 #define JSON_ERR_SUBTOOLONG	12	/* too many array elements */
140 #define JSON_ERR_BADSUBTRAIL	13	/* garbage while expecting array comma */
141 #define JSON_ERR_SUBTYPE	14	/* unsupported array element type */
142 #define JSON_ERR_BADSTRING	15	/* error while string parsing */
143 #define JSON_ERR_CHECKFAIL	16	/* check attribute not matched */
144 #define JSON_ERR_NOPARSTR	17	/* can't support strings in parallel arrays */
145 #define JSON_ERR_BADENUM	18	/* invalid enumerated value */
146 #define JSON_ERR_QNONSTRING	19	/* saw quoted value when expecting nonstring */
147 #define JSON_ERR_NONQSTRING	19	/* didn't see quoted value when expecting string */
148 #define JSON_ERR_MISC		20	/* other data conversion error */
149 #define JSON_ERR_BADNUM		21	/* error while parsing a numerical argument */
150 #define JSON_ERR_NULLPTR	22	/* unexpected null value or attribute pointer */
151 #define JSON_ERR_NOCURLY	23	/* object element specified, but no { */
152 
153 /*
154  * Use the following macros to declare template initializers for structobject
155  * arrays.  Writing the equivalents out by hand is error-prone.
156  *
157  * STRUCTOBJECT takes a structure name s, and a fieldname f in s.
158  *
159  * STRUCTARRAY takes the name of a structure array, a pointer to a an
160  * initializer defining the subobject type, and the address of an integer to
161  * store the length in.
162  */
163 #define STRUCTOBJECT(s, f)	.addr.offset = offsetof(s, f)
164 #define STRUCTARRAY(a, e, n) \
165 	.addr.array.element_type = t_structobject, \
166 	.addr.array.arr.objects.subtype = e, \
167 	.addr.array.arr.objects.base = (char*)a, \
168 	.addr.array.arr.objects.stride = sizeof(a[0]), \
169 	.addr.array.count = n, \
170 	.addr.array.maxlen = NITEMS(a)
171 
172 /* json.h ends here */
173