]> mj.ucw.cz Git - libucw.git/blob - ucw-json/json.h
JSON: Let initializers of our anonymous union be compatible with ancient GCC's
[libucw.git] / ucw-json / json.h
1 /*
2  *      UCW JSON Library
3  *
4  *      (c) 2015 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #ifndef _UCW_JSON_JSON_H
11 #define _UCW_JSON_JSON_H
12
13 #include <ucw/mempool.h>
14 #include <ucw/fastbuf.h>
15
16 #ifdef CONFIG_UCW_CLEAN_ABI
17 #define json_array_append ucw_json_array_append
18 #define json_delete ucw_json_delete
19 #define json_new ucw_json_new
20 #define json_new_array ucw_json_new_array
21 #define json_new_node ucw_json_new_node
22 #define json_new_number ucw_json_new_number
23 #define json_new_object ucw_json_new_object
24 #define json_next_token ucw_json_next_token
25 #define json_next_value ucw_json_next_value
26 #define json_number_to_int ucw_json_number_to_int
27 #define json_number_to_s64 ucw_json_number_to_s64
28 #define json_number_to_u64 ucw_json_number_to_u64
29 #define json_number_to_uint ucw_json_number_to_uint
30 #define json_object_get ucw_json_object_get
31 #define json_object_set ucw_json_object_set
32 #define json_parse ucw_json_parse
33 #define json_peek_token ucw_json_peek_token
34 #define json_pop ucw_json_pop
35 #define json_push ucw_json_push
36 #define json_reset ucw_json_reset
37 #define json_set_input ucw_json_set_input
38 #define json_set_output ucw_json_set_output
39 #define json_write ucw_json_write
40 #define json_write_value ucw_json_write_value
41 #endif
42
43 /***
44  * === JSON library context
45  *
46  * The context structure remembers the whole state of the JSON
47  * library. All JSON values are allocated from a memory pool associated
48  * with the context. By default, their lifetime is the same as that
49  * of the context.
50  *
51  * Alternatively, you can mark the current state of the context
52  * with json_push() and return to the marked state later using
53  * json_pop(). All JSON values created between these two operations
54  * are released afterwards. See json_push() for details.
55  ***/
56
57 /**
58  * The context is represented a pointer to this structure.
59  * The fields marked with [*] are publicly accessible, the rest is private.
60  **/
61 struct json_context {
62   // Memory management
63   struct mempool *pool;
64   struct mempool_state init_state;
65
66   // Parser context
67   struct fastbuf *in_fb;
68   uint in_line;                         // [*] Current line number
69   uint in_column;                       // [*] Current column number
70   bool in_eof;                          //     End of file was encountered
71   struct json_node *next_token;
72   struct json_node *trivial_token;
73   int next_char;
74
75   // Formatter context
76   struct fastbuf *out_fb;
77   uint out_indent;
78   uint format_options;                  // [*] Formatting options (a combination of JSON_FORMAT_xxx)
79 };
80
81 /** Creates a new JSON context. **/
82 struct json_context *json_new(void);
83
84 /** Deletes a JSON context, deallocating all memory associated with it. **/
85 void json_delete(struct json_context *js);
86
87 /**
88  * Recycles a JSON context. All state is reset, allocated objects are freed.
89  * This is equivalent to mp_delete() followed by mp_new(), but it is faster
90  * and the address of the context is preserved.
91  **/
92 void json_reset(struct json_context *js);
93
94 /**
95  * Push the current state of the context onto state stack.
96  *
97  * Between json_push() and the associated json_pop(), only newly
98  * created JSON values can be modified. Older values can be only
99  * inspected, never modified. In particular, new values cannot be
100  * inserted to old arrays nor objects.
101  *
102  * If you are using json_peek_token(), the saved tokens cannot
103  * be carried over push/pop boundary.
104  **/
105 void json_push(struct json_context *js);
106
107 /**
108  * Create a copy of a string in JSON memory.
109  *
110  * For example, this is useful when you want to use a string of unknown
111  * lifetime as a key in json_object_set().
112  **/
113 static inline const char *json_strdup(struct json_context *js, const char *str)
114 {
115   return mp_strdup(js->pool, str);
116 }
117
118 /**
119  * Pop state of the context off state stack. All JSON values created
120  * since the state was saved by json_push() are released.
121  **/
122 void json_pop(struct json_context *js);
123
124 /***
125  * === JSON values
126  *
127  * Each JSON value is represented by <<struct json_node,struct json_node>>,
128  * which is either an elementary value (null, boolean, number, string),
129  * or a container (array, object) pointing to other values.
130  *
131  * A value can belong to multiple containers simultaneously, so in general,
132  * the relationships between values need not form a tree, but a directed
133  * acyclic graph.
134  *
135  * You are allowed to read contents of nodes directly, but construction
136  * and modification of nodes must be always performed using the appropriate
137  * library functions.
138  ***/
139
140 /** Node types **/
141 enum json_node_type {
142   JSON_INVALID,
143   JSON_NULL,
144   JSON_BOOLEAN,
145   JSON_NUMBER,
146   JSON_STRING,
147   JSON_ARRAY,
148   JSON_OBJECT,
149   // These are not real nodes, but raw tokens.
150   // They are not present in the tree of values, but you may see them
151   // if you call json_next_token() and friends.
152   JSON_BEGIN_ARRAY,
153   JSON_END_ARRAY,
154   JSON_BEGIN_OBJECT,
155   JSON_END_OBJECT,
156   JSON_NAME_SEP,
157   JSON_VALUE_SEP,
158   JSON_EOF,
159 };
160
161 /** Each value is represented by a single node. **/
162 struct json_node {
163   enum json_node_type type;
164   union {                               // Data specific to individual value types
165     bool boolean;
166     double number;
167     const char *string;
168     struct json_node **elements;        // Arrays: Growing array of values
169     struct json_pair *pairs;            // Objects: Growing array of pairs
170   };
171 };
172
173 /** Attributes of objects are stored as (key, value) pairs of this format. **/
174 struct json_pair {
175   const char *key;
176   struct json_node *value;
177   // FIXME: Hash table
178 };
179
180 // Used internally
181 struct json_node *json_new_node(struct json_context *js, enum json_node_type type);
182
183 /** Creates a new null value. **/
184 static inline struct json_node *json_new_null(struct json_context *js UNUSED)
185 {
186   static const struct json_node static_null = { .type = JSON_NULL };
187   return (struct json_node *) &static_null;
188 }
189
190 /** Creates a new boolean value. **/
191 static inline struct json_node *json_new_bool(struct json_context *js UNUSED, bool value)
192 {
193   static const struct json_node static_bool[2] = {
194     [0] = { .type = JSON_BOOLEAN, { .boolean = 0 } },
195     [1] = { .type = JSON_BOOLEAN, { .boolean = 1 } },
196   };
197   return (struct json_node *) &static_bool[value];
198 }
199
200 /** Creates a new numeric value. The @value must be a finite number. **/
201 struct json_node *json_new_number(struct json_context *js, double value);
202
203 /**
204  * Convert a numeric value to an `int`. Returns false if the value
205  * is not numeric or if it is too large for an int.
206  **/
207 bool json_number_to_int(struct json_node *num, int *dest);
208
209 /** Same as above, but for `uint`. **/
210 bool json_number_to_uint(struct json_node *num, uint *dest);
211
212 /** Same as above, but for `s64`. **/
213 bool json_number_to_s64(struct json_node *num, s64 *dest);
214
215 /** Same as above, but for `u64`. **/
216 bool json_number_to_u64(struct json_node *num, u64 *dest);
217
218 /**
219  * Creates a new string value. The @value is kept only as a reference.
220  *
221  * String values can contain an arbitrary UTF-8 string with no null
222  * characters. However, it is not recommended to use UTF-8 values outside
223  * the range of UniCode codepoints (0 to 0x10ffff).
224  **/
225 static inline struct json_node *json_new_string_ref(struct json_context *js, const char *value)
226 {
227   struct json_node *n = json_new_node(js, JSON_STRING);
228   n->string = value;
229   return n;
230 }
231
232 /** Creates a new string value, making a private copy of @value. **/
233 static inline struct json_node *json_new_string(struct json_context *js, const char *value)
234 {
235   return json_new_string_ref(js, mp_strdup(js->pool, value));
236 }
237
238 /** Creates a new array value with no elements. **/
239 struct json_node *json_new_array(struct json_context *js);
240
241 /** Appends a new element to the given array. **/
242 void json_array_append(struct json_node *array, struct json_node *elt);
243
244 /** Creates a new object value with no attributes. **/
245 struct json_node *json_new_object(struct json_context *js);
246
247 /**
248  * Adds a new (@key, @value) pair to the given object. If @key is already
249  * present, the pair is replaced. If @value is NULL, no new pair is created
250  * and a pre-existing pair is deleted.
251  *
252  * The @key is referenced by the object, you must not free it during
253  * the lifetime of the object. When in doubt, use json_strdup().
254  **/
255 void json_object_set(struct json_node *n, const char *key, struct json_node *value);
256
257 /** Returns the value associated with @key, or NULL if no such value exists. **/
258 struct json_node *json_object_get(struct json_node *n, const char *key);
259
260 /***
261  * === Parser
262  *
263  * The simplest way to parse a complete JSON file is to call json_parse(),
264  * which returns a value tree representing the contents of the file.
265  *
266  * Alternatively, you can read the input token by token: call json_set_input()
267  * and then repeat json_next_token(). If you are parsing huge JSON files,
268  * you probably want to do json_push() first, then scan and process some
269  * tokens, and then json_pop().
270  *
271  * All parsing functions throw LibUCW exceptions of class `ucw.json.parse`
272  * upon errors. If you want to catch them, call the parser inside
273  * a transaction.
274  ***/
275
276 /** Parses a JSON file from the given fastbuf stream. **/
277 struct json_node *json_parse(struct json_context *js, struct fastbuf *fb);
278
279 /** Selects the given fastbuf stream as parser input. **/
280 void json_set_input(struct json_context *js, struct fastbuf *in);
281
282 /** Reads the next token from the input. **/
283 struct json_node *json_next_token(struct json_context *js);
284
285 /** Reads the next token, but keeps it in the input. **/
286 struct json_node *json_peek_token(struct json_context *js);
287
288 /** Reads the next JSON value, including nested values. **/
289 struct json_node *json_next_value(struct json_context *js);
290
291 /***
292  * === Writer
293  *
294  * JSON files can be produced by simply calling json_write().
295  *
296  * If you want to generate the output on the fly (for example if it is huge),
297  * call json_set_output() and then iterate json_write_value().
298  *
299  * By default, we produce a single-line compact representation,
300  * but you can choose differently by setting the appropriate
301  * `format_options` in the `json_context`.
302  ***/
303
304 /** Writes a JSON file to the given fastbuf stream, containing the JSON value @n. **/
305 void json_write(struct json_context *js, struct fastbuf *fb, struct json_node *n);
306
307 /** Selects the given fastbuf stream as output. **/
308 void json_set_output(struct json_context *js, struct fastbuf *fb);
309
310 /** Writes a single JSON value to the output stream. **/
311 void json_write_value(struct json_context *js, struct json_node *n);
312
313 /** Formatting options. The `format_options` field in the context is a bitwise OR of these flags. **/
314 enum json_format_option {
315   JSON_FORMAT_ESCAPE_NONASCII = 1,      // Produce pure ASCII output by escaping all Unicode characters in strings
316   JSON_FORMAT_INDENT = 2,               // Produce pretty indented output
317 };
318
319 #endif