1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DATA_JSON_H_
8 #define ZEPHYR_INCLUDE_DATA_JSON_H_
9 
10 #include <zephyr/sys/util.h>
11 #include <stddef.h>
12 #include <zephyr/toolchain.h>
13 #include <zephyr/types.h>
14 #include <sys/types.h>
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 /**
21  * @defgroup json JSON
22  * @ingroup utilities
23  * @{
24  */
25 
26 enum json_tokens {
27 	/* Before changing this enum, ensure that its maximum
28 	 * value is still within 7 bits. See comment next to the
29 	 * declaration of `type` in struct json_obj_descr.
30 	 */
31 
32 	JSON_TOK_NONE = '_',
33 	JSON_TOK_OBJECT_START = '{',
34 	JSON_TOK_OBJECT_END = '}',
35 	JSON_TOK_ARRAY_START = '[',
36 	JSON_TOK_ARRAY_END = ']',
37 	JSON_TOK_STRING = '"',
38 	JSON_TOK_STRING_BUF = 's',
39 	JSON_TOK_COLON = ':',
40 	JSON_TOK_COMMA = ',',
41 	JSON_TOK_NUMBER = '0',
42 	JSON_TOK_FLOAT = '1',
43 	JSON_TOK_OPAQUE = '2',
44 	JSON_TOK_OBJ_ARRAY = '3',
45 	JSON_TOK_ENCODED_OBJ = '4',
46 	JSON_TOK_INT64 = '5',
47 	JSON_TOK_UINT64 = '6',
48 	JSON_TOK_FLOAT_FP = '7',
49 	JSON_TOK_DOUBLE_FP = '8',
50 	JSON_TOK_INT = 'i',
51 	JSON_TOK_UINT = 'u',
52 	JSON_TOK_TRUE = 't',
53 	JSON_TOK_FALSE = 'f',
54 	JSON_TOK_MIXED_ARRAY = 'm',
55 	JSON_TOK_NULL = 'n',
56 	JSON_TOK_ERROR = '!',
57 	JSON_TOK_EOF = '\0',
58 };
59 
60 struct json_token {
61 	enum json_tokens type;
62 	char *start;
63 	char *end;
64 };
65 
66 struct json_lexer {
67 	void *(*state)(struct json_lexer *lex);
68 	char *start;
69 	char *pos;
70 	char *end;
71 	struct json_token tok;
72 };
73 
74 struct json_obj {
75 	struct json_lexer lex;
76 };
77 
78 struct json_obj_token {
79 	char *start;
80 	size_t length;
81 };
82 
83 
84 struct json_obj_descr {
85 	const char *field_name;
86 
87 	/* Alignment can be 1, 2, 4, or 8.  The macros to create
88 	 * a struct json_obj_descr will store the alignment's
89 	 * power of 2 in order to keep this value in the 0-3 range
90 	 * and thus use only 2 bits.
91 	 */
92 	uint32_t align_shift : 2;
93 
94 	/* 127 characters is more than enough for a field name. */
95 	uint32_t field_name_len : 7;
96 
97 	/* Valid values here (enum json_tokens): JSON_TOK_STRING,
98 	 * JSON_TOK_NUMBER, JSON_TOK_TRUE, JSON_TOK_FALSE,
99 	 * JSON_TOK_OBJECT_START, JSON_TOK_ARRAY_START.  (All others
100 	 * ignored.) Maximum value is '}' (125), so this has to be 7 bits
101 	 * long.
102 	 */
103 	uint32_t type : 7;
104 
105 	/* 65535 bytes is more than enough for many JSON payloads. */
106 	uint32_t offset : 16;
107 
108 	union {
109 		struct {
110 			const struct json_obj_descr *sub_descr;
111 			size_t sub_descr_len;
112 		} object;
113 		struct {
114 			const struct json_obj_descr *element_descr;
115 			size_t n_elements;
116 		} array;
117 		struct {
118 			size_t size;
119 		} field;
120 	};
121 };
122 
123 /**
124  * @brief Function pointer type to append bytes to a buffer while
125  * encoding JSON data.
126  *
127  * @param bytes Contents to write to the output
128  * @param len Number of bytes to append to output
129  * @param data User-provided pointer
130  *
131  * @return This callback function should return a negative number on
132  * error (which will be propagated to the return value of
133  * json_obj_encode()), or 0 on success.
134  */
135 typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
136 				   void *data);
137 
138 #define Z_ALIGN_SHIFT(type)	(__alignof__(type) == 1 ? 0 : \
139 				 __alignof__(type) == 2 ? 1 : \
140 				 __alignof__(type) == 4 ? 2 : 3)
141 
142 /**
143  * @brief Helper macro to declare a descriptor for supported primitive
144  * values.
145  *
146  * @param struct_ Struct packing the values
147  * @param field_name_ Field name in the struct
148  * @param type_ Token type for JSON value corresponding to a primitive
149  * type. Must be one of: JSON_TOK_STRING for strings, JSON_TOK_NUMBER
150  * for numbers, JSON_TOK_TRUE (or JSON_TOK_FALSE) for booleans.
151  *
152  * Here's an example of use:
153  *
154  *     struct foo {
155  *         int32_t some_int;
156  *     };
157  *
158  *     struct json_obj_descr foo[] = {
159  *         JSON_OBJ_DESCR_PRIM(struct foo, some_int, JSON_TOK_NUMBER),
160  *     };
161  */
162 #define JSON_OBJ_DESCR_PRIM(struct_, field_name_, type_) \
163 	{ \
164 		.field_name = (#field_name_), \
165 		.align_shift = Z_ALIGN_SHIFT(struct_), \
166 		.field_name_len = sizeof(#field_name_) - 1, \
167 		.type = type_, \
168 		.offset = offsetof(struct_, field_name_), \
169 		.field = { \
170 			.size = SIZEOF_FIELD(struct_, field_name_) \
171 		}, \
172 	}
173 
174 /**
175  * @brief Helper macro to declare a descriptor for an object value
176  *
177  * @param struct_ Struct packing the values
178  * @param field_name_ Field name in the struct
179  * @param sub_descr_ Array of json_obj_descr describing the subobject
180  *
181  * Here's an example of use:
182  *
183  *      struct nested {
184  *          int32_t foo;
185  *          struct {
186  *             int32_t baz;
187  *          } bar;
188  *      };
189  *
190  *      struct json_obj_descr nested_bar[] = {
191  *          { ... declare bar.baz descriptor ... },
192  *      };
193  *      struct json_obj_descr nested[] = {
194  *          { ... declare foo descriptor ... },
195  *          JSON_OBJ_DESCR_OBJECT(struct nested, bar, nested_bar),
196  *      };
197  */
198 #define JSON_OBJ_DESCR_OBJECT(struct_, field_name_, sub_descr_) \
199 	{ \
200 		.field_name = (#field_name_), \
201 		.align_shift = Z_ALIGN_SHIFT(struct_), \
202 		.field_name_len = (sizeof(#field_name_) - 1), \
203 		.type = JSON_TOK_OBJECT_START, \
204 		.offset = offsetof(struct_, field_name_), \
205 		.object = { \
206 			.sub_descr = sub_descr_, \
207 			.sub_descr_len = ARRAY_SIZE(sub_descr_), \
208 		}, \
209 	}
210 
211 /**
212  * @internal @brief Helper macro to declare an element descriptor
213  *
214  * @param struct_ Struct packing the values
215  * @param len_field_ Field name in the struct for the number of elements
216  * in the array
217  * @param elem_type_ Element type, must be a primitive type
218  * @param union_ Optional macro argument containing array or object descriptor
219  */
220 #define Z_JSON_ELEMENT_DESCR(struct_, len_field_, elem_type_, union_) \
221 	(const struct json_obj_descr[]) \
222 	{ \
223 		{ \
224 			.align_shift = Z_ALIGN_SHIFT(struct_), \
225 			.type = elem_type_, \
226 			.offset = offsetof(struct_, len_field_), \
227 			union_ \
228 		} \
229 	}
230 
231 /**
232  * @internal @brief Helper macro to declare an array descriptor
233  *
234  * @param elem_descr_ Element descriptor, pointer to a descriptor array
235  * @param elem_descr_len_ Number of elements in elem_descr_
236  */
237 #define Z_JSON_DESCR_ARRAY(elem_descr_, elem_descr_len_) \
238 	{ \
239 		.array = { \
240 			.element_descr = elem_descr_, \
241 			.n_elements = elem_descr_len_, \
242 		}, \
243 	}
244 
245 /**
246  * @internal @brief Helper macro to declare an object descriptor
247  *
248  * @param elem_descr_ Element descriptor, pointer to a descriptor array
249  * @param elem_descr_len_ Number of elements in elem_descr_
250  */
251 #define Z_JSON_DESCR_OBJ(elem_descr_, elem_descr_len_) \
252 		.object = { \
253 			.sub_descr = elem_descr_, \
254 			.sub_descr_len = elem_descr_len_, \
255 		}, \
256 
257 /**
258  * @internal @brief Helper macro to declare a field descriptor
259  *
260  * @param struct_ Struct packing the values
261  * @param field_name_ Field name in the struct
262  */
263 #define Z_JSON_DESCR_FIELD(struct_, field_name_) \
264 	{ \
265 		.field = { \
266 			.size = SIZEOF_FIELD(struct_, field_name_), \
267 		}, \
268 	}
269 
270 /**
271  * @brief Helper macro to declare a descriptor for an array of primitives
272  *
273  * @param struct_ Struct packing the values
274  * @param field_name_ Field name in the struct
275  * @param max_len_ Maximum number of elements in array
276  * @param len_field_ Field name in the struct for the number of elements
277  * in the array
278  * @param elem_type_ Element type, must be a primitive type
279  *
280  * Here's an example of use:
281  *
282  *      struct example {
283  *          int32_t foo[10];
284  *          size_t foo_len;
285  *      };
286  *
287  *      struct json_obj_descr array[] = {
288  *           JSON_OBJ_DESCR_ARRAY(struct example, foo, 10, foo_len,
289  *                                JSON_TOK_NUMBER)
290  *      };
291  */
292 #define JSON_OBJ_DESCR_ARRAY(struct_, field_name_, max_len_, \
293 			     len_field_, elem_type_) \
294 	{ \
295 		.field_name = (#field_name_), \
296 		.align_shift = Z_ALIGN_SHIFT(struct_), \
297 		.field_name_len = sizeof(#field_name_) - 1, \
298 		.type = JSON_TOK_ARRAY_START, \
299 		.offset = offsetof(struct_, field_name_), \
300 		.array = { \
301 			.element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
302 				elem_type_, \
303 				Z_JSON_DESCR_FIELD(struct_, field_name_[0])), \
304 			.n_elements = (max_len_), \
305 		}, \
306 	}
307 
308 /**
309  * @brief Helper macro to declare a descriptor for an array of objects
310  *
311  * @param struct_ Struct packing the values
312  * @param field_name_ Field name in the struct containing the array
313  * @param max_len_ Maximum number of elements in the array
314  * @param len_field_ Field name in the struct for the number of elements
315  * in the array
316  * @param elem_descr_ Element descriptor, pointer to a descriptor array
317  * @param elem_descr_len_ Number of elements in elem_descr_
318  *
319  * Here's an example of use:
320  *
321  *      struct person_height {
322  *          const char *name;
323  *          int32_t height;
324  *      };
325  *
326  *      struct people_heights {
327  *          struct person_height heights[10];
328  *          size_t heights_len;
329  *      };
330  *
331  *      struct json_obj_descr person_height_descr[] = {
332  *           JSON_OBJ_DESCR_PRIM(struct person_height, name, JSON_TOK_STRING),
333  *           JSON_OBJ_DESCR_PRIM(struct person_height, height, JSON_TOK_NUMBER),
334  *      };
335  *
336  *      struct json_obj_descr array[] = {
337  *           JSON_OBJ_DESCR_OBJ_ARRAY(struct people_heights, heights, 10,
338  *                                    heights_len, person_height_descr,
339  *                                    ARRAY_SIZE(person_height_descr)),
340  *      };
341  */
342 #define JSON_OBJ_DESCR_OBJ_ARRAY(struct_, field_name_, max_len_, \
343 				 len_field_, elem_descr_, elem_descr_len_) \
344 	{ \
345 		.field_name = (#field_name_), \
346 		.align_shift = Z_ALIGN_SHIFT(struct_), \
347 		.field_name_len = sizeof(#field_name_) - 1, \
348 		.type = JSON_TOK_ARRAY_START, \
349 		.offset = offsetof(struct_, field_name_), \
350 		.array = { \
351 			.element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
352 				JSON_TOK_OBJECT_START, \
353 				Z_JSON_DESCR_OBJ(elem_descr_, elem_descr_len_)), \
354 			.n_elements = (max_len_), \
355 		}, \
356 	}
357 
358 /**
359  * @brief Helper macro to declare a descriptor for an array of array
360  *
361  * @param struct_ Struct packing the values
362  * @param field_name_ Field name in the struct containing the array
363  * @param max_len_ Maximum number of elements in the array
364  * @param len_field_ Field name in the struct for the number of elements
365  * in the array
366  * @param elem_descr_ Element descriptor, pointer to a descriptor array
367  * @param elem_descr_len_ Number of elements in elem_descr_
368  *
369  * Here's an example of use:
370  *
371  *      struct person_height {
372  *          const char *name;
373  *          int32_t height;
374  *      };
375  *
376  *      struct person_heights_array {
377  *          struct person_height heights;
378  *      }
379  *
380  *      struct people_heights {
381  *          struct person_height_array heights[10];
382  *          size_t heights_len;
383  *      };
384  *
385  *      struct json_obj_descr person_height_descr[] = {
386  *          JSON_OBJ_DESCR_PRIM(struct person_height, name, JSON_TOK_STRING),
387  *          JSON_OBJ_DESCR_PRIM(struct person_height, height, JSON_TOK_NUMBER),
388  *      };
389  *
390  *      struct json_obj_descr person_height_array_descr[] = {
391  *          JSON_OBJ_DESCR_OBJECT(struct person_heights_array,
392  *                                heights, person_height_descr),
393  *      };
394  *
395  *      struct json_obj_descr array_array[] = {
396  *           JSON_OBJ_DESCR_ARRAY_ARRAY(struct people_heights, heights, 10,
397  *                                      heights_len, person_height_array_descr,
398  *                                      ARRAY_SIZE(person_height_array_descr)),
399  *      };
400  */
401 #define JSON_OBJ_DESCR_ARRAY_ARRAY(struct_, field_name_, max_len_, len_field_, \
402 				   elem_descr_, elem_descr_len_) \
403 	{ \
404 		.field_name = (#field_name_), \
405 		.align_shift = Z_ALIGN_SHIFT(struct_), \
406 		.field_name_len = sizeof(#field_name_) - 1, \
407 		.type = JSON_TOK_ARRAY_START, \
408 		.offset = offsetof(struct_, field_name_), \
409 		.array = { \
410 			.element_descr = Z_JSON_ELEMENT_DESCR( \
411 				struct_, len_field_, JSON_TOK_ARRAY_START, \
412 				Z_JSON_DESCR_ARRAY( \
413 					elem_descr_, \
414 					1 + ZERO_OR_COMPILE_ERROR(elem_descr_len_ == 1))), \
415 			.n_elements = (max_len_), \
416 		}, \
417 	}
418 
419 /**
420  * @brief Variant of JSON_OBJ_DESCR_ARRAY_ARRAY that can be used when the
421  *        structure and JSON field names differ.
422  *
423  * This is useful when the JSON field is not a valid C identifier.
424  *
425  * @param struct_ Struct packing the values
426  * @param json_field_name_ String, field name in JSON strings
427  * @param struct_field_name_ Field name in the struct containing the array
428  * @param max_len_ Maximum number of elements in the array
429  * @param len_field_ Field name in the struct for the number of elements
430  * in the array
431  * @param elem_descr_ Element descriptor, pointer to a descriptor array
432  * @param elem_descr_len_ Number of elements in elem_descr_
433  *
434  * @see JSON_OBJ_DESCR_ARRAY_ARRAY
435  */
436 #define JSON_OBJ_DESCR_ARRAY_ARRAY_NAMED(struct_, json_field_name_, struct_field_name_, \
437 					 max_len_, len_field_, elem_descr_, elem_descr_len_) \
438 	{ \
439 		.field_name = (#json_field_name_), \
440 		.align_shift = Z_ALIGN_SHIFT(struct_), \
441 		.field_name_len = sizeof(#json_field_name_) - 1, \
442 		.type = JSON_TOK_ARRAY_START, \
443 		.offset = offsetof(struct_, struct_field_name_), \
444 		.array = { \
445 			.element_descr = Z_JSON_ELEMENT_DESCR( \
446 				struct_, len_field_, JSON_TOK_ARRAY_START, \
447 				Z_JSON_DESCR_ARRAY( \
448 					elem_descr_, \
449 					1 + ZERO_OR_COMPILE_ERROR(elem_descr_len_ == 1))), \
450 			.n_elements = (max_len_), \
451 		}, \
452 	}
453 
454 /**
455  * @brief Variant of JSON_OBJ_DESCR_PRIM that can be used when the
456  *        structure and JSON field names differ.
457  *
458  * This is useful when the JSON field is not a valid C identifier.
459  *
460  * @param struct_ Struct packing the values.
461  * @param json_field_name_ String, field name in JSON strings
462  * @param struct_field_name_ Field name in the struct
463  * @param type_ Token type for JSON value corresponding to a primitive
464  * type.
465  *
466  * @see JSON_OBJ_DESCR_PRIM
467  */
468 #define JSON_OBJ_DESCR_PRIM_NAMED(struct_, json_field_name_, \
469 				  struct_field_name_, type_) \
470 	{ \
471 		.field_name = (json_field_name_), \
472 		.align_shift = Z_ALIGN_SHIFT(struct_), \
473 		.field_name_len = sizeof(json_field_name_) - 1, \
474 		.type = type_, \
475 		.offset = offsetof(struct_, struct_field_name_), \
476 		.field = { \
477 			.size = SIZEOF_FIELD(struct_, struct_field_name_) \
478 		}, \
479 	}
480 
481 /**
482  * @brief Variant of JSON_OBJ_DESCR_OBJECT that can be used when the
483  *        structure and JSON field names differ.
484  *
485  * This is useful when the JSON field is not a valid C identifier.
486  *
487  * @param struct_ Struct packing the values
488  * @param json_field_name_ String, field name in JSON strings
489  * @param struct_field_name_ Field name in the struct
490  * @param sub_descr_ Array of json_obj_descr describing the subobject
491  *
492  * @see JSON_OBJ_DESCR_OBJECT
493  */
494 #define JSON_OBJ_DESCR_OBJECT_NAMED(struct_, json_field_name_, \
495 				    struct_field_name_, sub_descr_) \
496 	{ \
497 		.field_name = (json_field_name_), \
498 		.align_shift = Z_ALIGN_SHIFT(struct_), \
499 		.field_name_len = (sizeof(json_field_name_) - 1), \
500 		.type = JSON_TOK_OBJECT_START, \
501 		.offset = offsetof(struct_, struct_field_name_), \
502 		.object = { \
503 			.sub_descr = sub_descr_, \
504 			.sub_descr_len = ARRAY_SIZE(sub_descr_), \
505 		}, \
506 	}
507 
508 /**
509  * @brief Variant of JSON_OBJ_DESCR_ARRAY that can be used when the
510  *        structure and JSON field names differ.
511  *
512  * This is useful when the JSON field is not a valid C identifier.
513  *
514  * @param struct_ Struct packing the values
515  * @param json_field_name_ String, field name in JSON strings
516  * @param struct_field_name_ Field name in the struct
517  * @param max_len_ Maximum number of elements in array
518  * @param len_field_ Field name in the struct for the number of elements
519  * in the array
520  * @param elem_type_ Element type, must be a primitive type
521  *
522  * @see JSON_OBJ_DESCR_ARRAY
523  */
524 #define JSON_OBJ_DESCR_ARRAY_NAMED(struct_, json_field_name_,\
525 				   struct_field_name_, max_len_, len_field_, \
526 				   elem_type_) \
527 	{ \
528 		.field_name = (json_field_name_), \
529 		.align_shift = Z_ALIGN_SHIFT(struct_), \
530 		.field_name_len = sizeof(json_field_name_) - 1, \
531 		.type = JSON_TOK_ARRAY_START, \
532 		.offset = offsetof(struct_, struct_field_name_), \
533 		.array = { \
534 			.element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
535 				elem_type_, \
536 				Z_JSON_DESCR_FIELD(struct_, struct_field_name_[0])), \
537 			.n_elements = (max_len_), \
538 		}, \
539 	}
540 
541 /**
542  * @brief Variant of JSON_OBJ_DESCR_OBJ_ARRAY that can be used when
543  *        the structure and JSON field names differ.
544  *
545  * This is useful when the JSON field is not a valid C identifier.
546  *
547  * @param struct_ Struct packing the values
548  * @param json_field_name_ String, field name of the array in JSON strings
549  * @param struct_field_name_ Field name in the struct containing the array
550  * @param max_len_ Maximum number of elements in the array
551  * @param len_field_ Field name in the struct for the number of elements
552  * in the array
553  * @param elem_descr_ Element descriptor, pointer to a descriptor array
554  * @param elem_descr_len_ Number of elements in elem_descr_
555  *
556  * Here's an example of use:
557  *
558  *      struct person_height {
559  *          const char *name;
560  *          int32_t height;
561  *      };
562  *
563  *      struct people_heights {
564  *          struct person_height heights[10];
565  *          size_t heights_len;
566  *      };
567  *
568  *      struct json_obj_descr person_height_descr[] = {
569  *           JSON_OBJ_DESCR_PRIM(struct person_height, name, JSON_TOK_STRING),
570  *           JSON_OBJ_DESCR_PRIM(struct person_height, height, JSON_TOK_NUMBER),
571  *      };
572  *
573  *      struct json_obj_descr array[] = {
574  *           JSON_OBJ_DESCR_OBJ_ARRAY_NAMED(struct people_heights,
575  *                                          "people-heights", heights,
576  *                                          10, heights_len,
577  *                                          person_height_descr,
578  *                                          ARRAY_SIZE(person_height_descr)),
579  *      };
580  */
581 #define JSON_OBJ_DESCR_OBJ_ARRAY_NAMED(struct_, json_field_name_, \
582 				       struct_field_name_, max_len_, \
583 				       len_field_, elem_descr_, \
584 				       elem_descr_len_) \
585 	{ \
586 		.field_name = json_field_name_, \
587 		.align_shift = Z_ALIGN_SHIFT(struct_), \
588 		.field_name_len = sizeof(json_field_name_) - 1, \
589 		.type = JSON_TOK_ARRAY_START, \
590 		.offset = offsetof(struct_, struct_field_name_), \
591 		.array = { \
592 			.element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
593 				JSON_TOK_OBJECT_START, \
594 				Z_JSON_DESCR_OBJ(elem_descr_, elem_descr_len_)), \
595 			.n_elements = (max_len_), \
596 		}, \
597 	}
598 
599 /**
600  * @brief Parses the JSON-encoded object pointed to by @a json, with
601  * size @a len, according to the descriptor pointed to by @a descr.
602  * Values are stored in a struct pointed to by @a val.  Set up the
603  * descriptor like this:
604  *
605  *    struct s { int32_t foo; char *bar; }
606  *    struct json_obj_descr descr[] = {
607  *       JSON_OBJ_DESCR_PRIM(struct s, foo, JSON_TOK_NUMBER),
608  *       JSON_OBJ_DESCR_PRIM(struct s, bar, JSON_TOK_STRING),
609  *    };
610  *
611  * Since this parser is designed for machine-to-machine communications, some
612  * liberties were taken to simplify the design:
613  * (1) strings are not unescaped (but only valid escape sequences are
614  * accepted);
615  * (2) no UTF-8 validation is performed; and
616  * (3) only integer numbers are supported (no strtod() in the minimal libc).
617  *
618  * @param json Pointer to JSON-encoded value to be parsed
619  * @param len Length of JSON-encoded value
620  * @param descr Pointer to the descriptor array
621  * @param descr_len Number of elements in the descriptor array. Must be less
622  * than 63 due to implementation detail reasons (if more fields are
623  * necessary, use two descriptors)
624  * @param val Pointer to the struct to hold the decoded values
625  *
626  * @return < 0 if error, bitmap of decoded fields on success (bit 0
627  * is set if first field in the descriptor has been properly decoded, etc).
628  */
629 int64_t json_obj_parse(char *json, size_t len,
630 	const struct json_obj_descr *descr, size_t descr_len,
631 	void *val);
632 
633 /**
634  * @brief Parses the JSON-encoded array pointed to by @a json, with
635  * size @a len, according to the descriptor pointed to by @a descr.
636  * Values are stored in a struct pointed to by @a val.  Set up the
637  * descriptor like this:
638  *
639  *    struct s { int32_t foo; char *bar; }
640  *    struct json_obj_descr descr[] = {
641  *       JSON_OBJ_DESCR_PRIM(struct s, foo, JSON_TOK_NUMBER),
642  *       JSON_OBJ_DESCR_PRIM(struct s, bar, JSON_TOK_STRING),
643  *    };
644  *    struct a { struct s baz[10]; size_t count; }
645  *    struct json_obj_descr array[] = {
646  *       JSON_OBJ_DESCR_OBJ_ARRAY(struct a, baz, 10, count,
647  *                                descr, ARRAY_SIZE(descr)),
648  *    };
649  *
650  * Since this parser is designed for machine-to-machine communications, some
651  * liberties were taken to simplify the design:
652  * (1) strings are not unescaped (but only valid escape sequences are
653  * accepted);
654  * (2) no UTF-8 validation is performed; and
655  * (3) only integer numbers are supported (no strtod() in the minimal libc).
656  *
657  * @param json Pointer to JSON-encoded array to be parsed
658  * @param len Length of JSON-encoded array
659  * @param descr Pointer to the descriptor array
660  * @param val Pointer to the struct to hold the decoded values
661  *
662  * @return 0 if array has been successfully parsed. A negative value
663  * indicates an error (as defined on errno.h).
664  */
665 int json_arr_parse(char *json, size_t len,
666 	const struct json_obj_descr *descr, void *val);
667 
668 /**
669  * @brief Initialize single-object array parsing
670  *
671  * JSON-encoded array data is going to be parsed one object at a time. Data is provided by
672  * @a payload with the size of @a len bytes.
673  *
674  * Function validate that Json Array start is detected and initialize @a json object for
675  * Json object parsing separately.
676  *
677  * @param json Provide storage for parser states. To be used when parsing the array.
678  * @param payload Pointer to JSON-encoded array to be parsed
679  * @param len Length of JSON-encoded array
680  *
681  * @return 0 if array start is detected and initialization is successful or negative error
682  * code in case of failure.
683  */
684 int json_arr_separate_object_parse_init(struct json_obj *json, char *payload, size_t len);
685 
686 /**
687  * @brief Parse a single object from array.
688  *
689  * Parses the JSON-encoded object pointed to by @a json object array, with
690  * size @a len, according to the descriptor pointed to by @a descr.
691  *
692  * @param json Pointer to JSON-object message state
693  * @param descr Pointer to the descriptor array
694  * @param descr_len Number of elements in the descriptor array. Must be less than 31.
695  * @param val Pointer to the struct to hold the decoded values
696  *
697  * @return < 0 if error, 0 for end of message, bitmap of decoded fields on success (bit 0
698  * is set if first field in the descriptor has been properly decoded, etc).
699  */
700 int json_arr_separate_parse_object(struct json_obj *json, const struct json_obj_descr *descr,
701 				   size_t descr_len, void *val);
702 
703 /**
704  * @brief Escapes the string so it can be used to encode JSON objects
705  *
706  * @param str The string to escape; the escape string is stored the
707  * buffer pointed to by this parameter
708  * @param len Points to a size_t containing the size before and after
709  * the escaping process
710  * @param buf_size The size of buffer str points to
711  *
712  * @return 0 if string has been escaped properly, or -ENOMEM if there
713  * was not enough space to escape the buffer
714  */
715 ssize_t json_escape(char *str, size_t *len, size_t buf_size);
716 
717 /**
718  * @brief Calculates the JSON-escaped string length
719  *
720  * @param str The string to analyze
721  * @param len String size
722  *
723  * @return The length str would have if it were escaped
724  */
725 size_t json_calc_escaped_len(const char *str, size_t len);
726 
727 /**
728  * @brief Calculates the string length to fully encode an object
729  *
730  * @param descr Pointer to the descriptor array
731  * @param descr_len Number of elements in the descriptor array
732  * @param val Struct holding the values
733  *
734  * @return Number of bytes necessary to encode the values if >0,
735  * an error code is returned.
736  */
737 ssize_t json_calc_encoded_len(const struct json_obj_descr *descr,
738 			      size_t descr_len, const void *val);
739 
740 /**
741  * @brief Calculates the string length to fully encode an array
742  *
743  * @param descr Pointer to the descriptor array
744  * @param val Struct holding the values
745  *
746  * @return Number of bytes necessary to encode the values if >0,
747  * an error code is returned.
748  */
749 ssize_t json_calc_encoded_arr_len(const struct json_obj_descr *descr,
750 				  const void *val);
751 
752 /**
753  * @brief Encodes an object in a contiguous memory location
754  *
755  * @param descr Pointer to the descriptor array
756  * @param descr_len Number of elements in the descriptor array
757  * @param val Struct holding the values
758  * @param buffer Buffer to store the JSON data
759  * @param buf_size Size of buffer, in bytes, with space for the terminating
760  * NUL character
761  *
762  * @return 0 if object has been successfully encoded. A negative value
763  * indicates an error (as defined on errno.h).
764  */
765 int json_obj_encode_buf(const struct json_obj_descr *descr, size_t descr_len,
766 			const void *val, char *buffer, size_t buf_size);
767 
768 /**
769  * @brief Encodes an array in a contiguous memory location
770  *
771  * @param descr Pointer to the descriptor array
772  * @param val Struct holding the values
773  * @param buffer Buffer to store the JSON data
774  * @param buf_size Size of buffer, in bytes, with space for the terminating
775  * NUL character
776  *
777  * @return 0 if object has been successfully encoded. A negative value
778  * indicates an error (as defined on errno.h).
779  */
780 int json_arr_encode_buf(const struct json_obj_descr *descr, const void *val,
781 			char *buffer, size_t buf_size);
782 
783 /**
784  * @brief Encodes an object using an arbitrary writer function
785  *
786  * @param descr Pointer to the descriptor array
787  * @param descr_len Number of elements in the descriptor array
788  * @param val Struct holding the values
789  * @param append_bytes Function to append bytes to the output
790  * @param data Data pointer to be passed to the append_bytes callback
791  * function.
792  *
793  * @return 0 if object has been successfully encoded. A negative value
794  * indicates an error.
795  */
796 int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len,
797 		    const void *val, json_append_bytes_t append_bytes,
798 		    void *data);
799 
800 /**
801  * @brief Encodes an array using an arbitrary writer function
802  *
803  * @param descr Pointer to the descriptor array
804  * @param val Struct holding the values
805  * @param append_bytes Function to append bytes to the output
806  * @param data Data pointer to be passed to the append_bytes callback
807  * function.
808  *
809  * @return 0 if object has been successfully encoded. A negative value
810  * indicates an error.
811  */
812 int json_arr_encode(const struct json_obj_descr *descr, const void *val,
813 		    json_append_bytes_t append_bytes, void *data);
814 
815 /**
816  * @brief Descriptor for a mixed-type JSON array.
817  *
818  * This structure describes a top-level JSON array whose elements may be
819  * of different types (primitives, objects, arrays, or nested mixed arrays).
820  * Each element in the array is described by an entry in a descriptor array.
821  *
822  * Mixed arrays are useful for parsing and encoding JSON arrays that do not
823  * have a homogeneous element type, such as:
824  *
825  *   [ "string", 42, { "foo": 1 }, [1,2,3], true ]
826  *
827  * @note This structure and its associated macros are intended for use with
828  *       the mixed array parsing and encoding APIs (see json_mixed_arr_parse()).
829  */
830 struct json_mixed_arr_descr {
831 	uint32_t type : 7;
832 	size_t count_offset;
833 
834 	union {
835 		struct {
836 			size_t offset;
837 			size_t size;
838 		} primitive;
839 
840 		struct {
841 			const struct json_obj_descr *sub_descr;
842 			size_t sub_descr_len;
843 			size_t offset;
844 		} object;
845 
846 		struct {
847 			const struct json_obj_descr *element_descr;
848 			size_t n_elements;
849 			size_t offset;
850 		} array;
851 
852 		struct {
853 			const struct json_mixed_arr_descr *sub_descr;
854 			size_t sub_descr_len;
855 			size_t offset;
856 		} mixed_array;
857 	};
858 };
859 
860 /**
861  * @brief Helper macro to declare a mixed array primitive element descriptor.
862  *
863  * @param struct_		Struct containing the value.
864  * @param field_name_	Field name in the struct.
865  * @param type_		Token type for the JSON value (see enum json_tokens).
866  * @param count_field_	Field name in the struct for the number of elements.
867  *
868  * Example:
869  *	struct foo { int x; size_t x_count; };
870  *	const struct json_mixed_arr_descr foo_descr[] = {
871  *		JSON_MIXED_ARR_DESCR_PRIM(struct foo, x, JSON_TOK_NUMBER, x_count),
872  *	};
873  */
874 #define JSON_MIXED_ARR_DESCR_PRIM(struct_, field_name_, type_, count_field_) \
875 { \
876 	.type = type_, \
877 	.count_offset = offsetof(struct_, count_field_), \
878 	.primitive = { \
879 	    .offset = offsetof(struct_, field_name_), \
880 	    .size = SIZEOF_FIELD(struct_, field_name_) \
881 	} \
882 }
883 
884 /**
885  * @brief Helper macro to declare a mixed array object element descriptor.
886  *
887  * @param struct_		Struct containing the object.
888  * @param field_name_	Field name in the struct.
889  * @param sub_descr_	Array of json_obj_descr describing the object fields.
890  * @param count_field_	Field name in the struct for the number of elements.
891  *
892  * Example:
893  *	struct bar { int y; };
894  *	struct foo { struct bar b; size_t b_count; };
895  *	const struct json_obj_descr bar_descr[] = { ... };
896  *	const struct json_mixed_arr_descr foo_descr[] = {
897  *		JSON_MIXED_ARR_DESCR_OBJECT(struct foo, b, bar_descr, b_count),
898  *	};
899  */
900 #define JSON_MIXED_ARR_DESCR_OBJECT(struct_, field_name_, sub_descr_, count_field_) \
901 { \
902 	.type = JSON_TOK_OBJECT_START, \
903 	.count_offset = offsetof(struct_, count_field_), \
904 	.object = { \
905 		.sub_descr = sub_descr_, \
906 		.sub_descr_len = ARRAY_SIZE(sub_descr_), \
907 		.offset = offsetof(struct_, field_name_) \
908 	} \
909 }
910 
911 /**
912  * @brief Helper macro to declare a mixed array homogeneous array element descriptor.
913  *
914  * @param struct_		Struct containing the array.
915  * @param field_name_	Field name in the struct.
916  * @param max_len_		Maximum number of elements in the array.
917  * @param elem_descr_	Element descriptor (pointer to json_obj_descr array).
918  * @param count_field_	Field name in the struct for the number of elements.
919  *
920  * Example:
921  *	struct foo {
922  *		int arr[4];
923  *		size_t arr_count;
924  *	};
925  *	const struct json_obj_descr arr_elem_descr[] = {
926  *		JSON_OBJ_DESCR_ARRAY(struct foo, arr, 4, arr_count, JSON_TOK_NUMBER),
927  *	};
928  *	const struct json_mixed_arr_descr foo_descr[] = {
929  *		JSON_MIXED_ARR_DESCR_ARRAY(struct foo, arr, 4, arr_elem_descr, arr_count),
930  *	};
931  */
932 #define JSON_MIXED_ARR_DESCR_ARRAY(struct_, field_name_, max_len_, elem_descr_, count_field_) \
933 { \
934 	.type = JSON_TOK_ARRAY_START, \
935 	.count_offset = offsetof(struct_, count_field_), \
936 	.array = { \
937 		.element_descr = elem_descr_, \
938 		.n_elements = (max_len_), \
939 		.offset = offsetof(struct_, field_name_) \
940 	} \
941 }
942 
943 /**
944  * @brief Helper macro to declare a nested mixed array element descriptor.
945  *
946  * @param struct_		Struct containing the nested mixed array.
947  * @param field_name_	Field name in the struct.
948  * @param sub_descr_	Mixed array descriptor for the nested array.
949  * @param count_field_	Field name in the struct for the number of elements.
950  *
951  * Example:
952  *	struct foo { ...; size_t nested_count; };
953  *	const struct json_mixed_arr_descr nested_descr[] = { ... };
954  *	const struct json_mixed_arr_descr foo_descr[] = {
955  *		JSON_MIXED_ARR_DESCR_MIXED_ARRAY(struct foo, nested, nested_descr, nested_count),
956  *	};
957  */
958 #define JSON_MIXED_ARR_DESCR_MIXED_ARRAY(struct_, field_name_, sub_descr_, count_field_) \
959 { \
960 	.type = JSON_TOK_MIXED_ARRAY, \
961 	.count_offset = offsetof(struct_, count_field_), \
962 	.mixed_array = { \
963 		.sub_descr = sub_descr_, \
964 		.sub_descr_len = ARRAY_SIZE(sub_descr_), \
965 		.offset = offsetof(struct_, field_name_) \
966 	} \
967 }
968 
969 /**
970  * @brief Parse a JSON mixed array into a C structure.
971  *
972  * This function parses a JSON array (which may contain elements of varying types)
973  * according to the provided mixed array descriptor and stores the result in the
974  * user-supplied structure.
975  *
976  * @param json		Pointer to the input JSON string.
977  * @param len		Length of the input JSON string.
978  * @param descr		Descriptor array describing the structure of the mixed array.
979  * @param descr_len	Number of elements in the descriptor array.
980  * @param val		Pointer to the structure to populate with parsed data.
981  *
982  * @return < 0 if error, number of elements parsed on success.
983  */
984 int json_mixed_arr_parse(char *json, size_t len,
985 			 const struct json_mixed_arr_descr *descr,
986 			 size_t descr_len, void *val);
987 
988 /**
989  * @brief Encode a C structure as a JSON mixed array.
990  *
991  * This function encodes a C structure, described by the mixed array descriptor,
992  * as a JSON array.
993  *
994  * @param descr		Descriptor array describing the structure of the mixed array.
995  * @param descr_len	Number of elements in the descriptor array.
996  * @param val		Pointer to the structure to encode.
997  * @param append_bytes Function to append bytes to the output
998  * @param data Data pointer to be passed to the append_bytes callback
999  * function.
1000  *
1001  * @return 0 if mixed array has been successfully encoded. Negative error code on failure.
1002  */
1003 int json_mixed_arr_encode(const struct json_mixed_arr_descr *descr,
1004 			  size_t descr_len, void *val,
1005 			  json_append_bytes_t append_bytes,
1006 			  void *data);
1007 
1008 /**
1009  * @brief Encode a C structure as a JSON mixed array into a buffer.
1010  *
1011  * This function encodes a C structure, described by the mixed array descriptor,
1012  * as a JSON array and writes the result into the provided buffer.
1013  *
1014  * @param descr		Descriptor array describing the structure of the mixed array.
1015  * @param descr_len	Number of elements in the descriptor array.
1016  * @param val		Pointer to the structure to encode.
1017  * @param buffer	Output buffer to write the JSON string.
1018  * @param buf_size	Size of the output buffer.
1019  *
1020  * @return 0 if mixed array has been successfully encoded. Negative error code on failure.
1021  */
1022 int json_mixed_arr_encode_buf(const struct json_mixed_arr_descr *descr,
1023 			      size_t descr_len, void *val,
1024 			      char *buffer, size_t buf_size);
1025 
1026 /**
1027  * @brief Calculate the length of the encoded JSON mixed array.
1028  *
1029  * This function calculates the number of bytes required to encode the given
1030  * structure as a JSON mixed array, according to the provided descriptor.
1031  *
1032  * @param descr		Descriptor array describing the structure of the mixed array.
1033  * @param descr_len	Number of elements in the descriptor array.
1034  * @param val		Pointer to the structure to encode.
1035  *
1036  * @return		Number of bytes required for encoding, or negative error code.
1037  */
1038 ssize_t json_calc_mixed_arr_len(const struct json_mixed_arr_descr *descr,
1039 				size_t descr_len, void *val);
1040 
1041 #ifdef __cplusplus
1042 }
1043 #endif
1044 
1045 /**
1046  * @}
1047  */
1048 #endif /* ZEPHYR_INCLUDE_DATA_JSON_H_ */
1049