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_COLON = ':',
39 	JSON_TOK_COMMA = ',',
40 	JSON_TOK_NUMBER = '0',
41 	JSON_TOK_FLOAT = '1',
42 	JSON_TOK_OPAQUE = '2',
43 	JSON_TOK_OBJ_ARRAY = '3',
44 	JSON_TOK_ENCODED_OBJ = '4',
45 	JSON_TOK_TRUE = 't',
46 	JSON_TOK_FALSE = 'f',
47 	JSON_TOK_NULL = 'n',
48 	JSON_TOK_ERROR = '!',
49 	JSON_TOK_EOF = '\0',
50 };
51 
52 struct json_token {
53 	enum json_tokens type;
54 	char *start;
55 	char *end;
56 };
57 
58 struct json_lexer {
59 	void *(*state)(struct json_lexer *lex);
60 	char *start;
61 	char *pos;
62 	char *end;
63 	struct json_token tok;
64 };
65 
66 struct json_obj {
67 	struct json_lexer lex;
68 };
69 
70 struct json_obj_token {
71 	char *start;
72 	size_t length;
73 };
74 
75 
76 struct json_obj_descr {
77 	const char *field_name;
78 
79 	/* Alignment can be 1, 2, 4, or 8.  The macros to create
80 	 * a struct json_obj_descr will store the alignment's
81 	 * power of 2 in order to keep this value in the 0-3 range
82 	 * and thus use only 2 bits.
83 	 */
84 	uint32_t align_shift : 2;
85 
86 	/* 127 characters is more than enough for a field name. */
87 	uint32_t field_name_len : 7;
88 
89 	/* Valid values here (enum json_tokens): JSON_TOK_STRING,
90 	 * JSON_TOK_NUMBER, JSON_TOK_TRUE, JSON_TOK_FALSE,
91 	 * JSON_TOK_OBJECT_START, JSON_TOK_ARRAY_START.  (All others
92 	 * ignored.) Maximum value is '}' (125), so this has to be 7 bits
93 	 * long.
94 	 */
95 	uint32_t type : 7;
96 
97 	/* 65535 bytes is more than enough for many JSON payloads. */
98 	uint32_t offset : 16;
99 
100 	union {
101 		struct {
102 			const struct json_obj_descr *sub_descr;
103 			size_t sub_descr_len;
104 		} object;
105 		struct {
106 			const struct json_obj_descr *element_descr;
107 			size_t n_elements;
108 		} array;
109 	};
110 };
111 
112 /**
113  * @brief Function pointer type to append bytes to a buffer while
114  * encoding JSON data.
115  *
116  * @param bytes Contents to write to the output
117  * @param len Number of bytes to append to output
118  * @param data User-provided pointer
119  *
120  * @return This callback function should return a negative number on
121  * error (which will be propagated to the return value of
122  * json_obj_encode()), or 0 on success.
123  */
124 typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
125 				   void *data);
126 
127 #define Z_ALIGN_SHIFT(type)	(__alignof__(type) == 1 ? 0 : \
128 				 __alignof__(type) == 2 ? 1 : \
129 				 __alignof__(type) == 4 ? 2 : 3)
130 
131 /**
132  * @brief Helper macro to declare a descriptor for supported primitive
133  * values.
134  *
135  * @param struct_ Struct packing the values
136  * @param field_name_ Field name in the struct
137  * @param type_ Token type for JSON value corresponding to a primitive
138  * type. Must be one of: JSON_TOK_STRING for strings, JSON_TOK_NUMBER
139  * for numbers, JSON_TOK_TRUE (or JSON_TOK_FALSE) for booleans.
140  *
141  * Here's an example of use:
142  *
143  *     struct foo {
144  *         int32_t some_int;
145  *     };
146  *
147  *     struct json_obj_descr foo[] = {
148  *         JSON_OBJ_DESCR_PRIM(struct foo, some_int, JSON_TOK_NUMBER),
149  *     };
150  */
151 #define JSON_OBJ_DESCR_PRIM(struct_, field_name_, type_) \
152 	{ \
153 		.field_name = (#field_name_), \
154 		.align_shift = Z_ALIGN_SHIFT(struct_), \
155 		.field_name_len = sizeof(#field_name_) - 1, \
156 		.type = type_, \
157 		.offset = offsetof(struct_, field_name_), \
158 	}
159 
160 /**
161  * @brief Helper macro to declare a descriptor for an object value
162  *
163  * @param struct_ Struct packing the values
164  * @param field_name_ Field name in the struct
165  * @param sub_descr_ Array of json_obj_descr describing the subobject
166  *
167  * Here's an example of use:
168  *
169  *      struct nested {
170  *          int32_t foo;
171  *          struct {
172  *             int32_t baz;
173  *          } bar;
174  *      };
175  *
176  *      struct json_obj_descr nested_bar[] = {
177  *          { ... declare bar.baz descriptor ... },
178  *      };
179  *      struct json_obj_descr nested[] = {
180  *          { ... declare foo descriptor ... },
181  *          JSON_OBJ_DESCR_OBJECT(struct nested, bar, nested_bar),
182  *      };
183  */
184 #define JSON_OBJ_DESCR_OBJECT(struct_, field_name_, sub_descr_) \
185 	{ \
186 		.field_name = (#field_name_), \
187 		.align_shift = Z_ALIGN_SHIFT(struct_), \
188 		.field_name_len = (sizeof(#field_name_) - 1), \
189 		.type = JSON_TOK_OBJECT_START, \
190 		.offset = offsetof(struct_, field_name_), \
191 		.object = { \
192 			.sub_descr = sub_descr_, \
193 			.sub_descr_len = ARRAY_SIZE(sub_descr_), \
194 		}, \
195 	}
196 
197 /**
198  * @internal @brief Helper macro to declare an element descriptor
199  *
200  * @param struct_ Struct packing the values
201  * @param len_field_ Field name in the struct for the number of elements
202  * in the array
203  * @param elem_type_ Element type, must be a primitive type
204  * @param union_ Optional macro argument containing array or object descriptor
205  */
206 #define Z_JSON_ELEMENT_DESCR(struct_, len_field_, elem_type_, union_) \
207 	(const struct json_obj_descr[]) \
208 	{ \
209 		{ \
210 			.align_shift = Z_ALIGN_SHIFT(struct_), \
211 			.type = elem_type_, \
212 			.offset = offsetof(struct_, len_field_), \
213 			union_ \
214 		} \
215 	}
216 
217 /**
218  * @internal @brief Helper macro to declare an array descriptor
219  *
220  * @param elem_descr_ Element descriptor, pointer to a descriptor array
221  * @param elem_descr_len_ Number of elements in elem_descr_
222  */
223 #define Z_JSON_DESCR_ARRAY(elem_descr_, elem_descr_len_) \
224 	{ \
225 		.array = { \
226 			.element_descr = elem_descr_, \
227 			.n_elements = elem_descr_len_, \
228 		}, \
229 	}
230 
231 /**
232  * @internal @brief Helper macro to declare an object 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_OBJ(elem_descr_, elem_descr_len_) \
238 	{ \
239 		.object = { \
240 			.sub_descr = elem_descr_, \
241 			.sub_descr_len = elem_descr_len_, \
242 		}, \
243 	}
244 
245 /**
246  * @brief Helper macro to declare a descriptor for an array of primitives
247  *
248  * @param struct_ Struct packing the values
249  * @param field_name_ Field name in the struct
250  * @param max_len_ Maximum number of elements in array
251  * @param len_field_ Field name in the struct for the number of elements
252  * in the array
253  * @param elem_type_ Element type, must be a primitive type
254  *
255  * Here's an example of use:
256  *
257  *      struct example {
258  *          int32_t foo[10];
259  *          size_t foo_len;
260  *      };
261  *
262  *      struct json_obj_descr array[] = {
263  *           JSON_OBJ_DESCR_ARRAY(struct example, foo, 10, foo_len,
264  *                                JSON_TOK_NUMBER)
265  *      };
266  */
267 #define JSON_OBJ_DESCR_ARRAY(struct_, field_name_, max_len_, \
268 			     len_field_, elem_type_) \
269 	{ \
270 		.field_name = (#field_name_), \
271 		.align_shift = Z_ALIGN_SHIFT(struct_), \
272 		.field_name_len = sizeof(#field_name_) - 1, \
273 		.type = JSON_TOK_ARRAY_START, \
274 		.offset = offsetof(struct_, field_name_), \
275 		.array = { \
276 			.element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
277 				elem_type_,), \
278 			.n_elements = (max_len_), \
279 		}, \
280 	}
281 
282 /**
283  * @brief Helper macro to declare a descriptor for an array of objects
284  *
285  * @param struct_ Struct packing the values
286  * @param field_name_ Field name in the struct containing the array
287  * @param max_len_ Maximum number of elements in the array
288  * @param len_field_ Field name in the struct for the number of elements
289  * in the array
290  * @param elem_descr_ Element descriptor, pointer to a descriptor array
291  * @param elem_descr_len_ Number of elements in elem_descr_
292  *
293  * Here's an example of use:
294  *
295  *      struct person_height {
296  *          const char *name;
297  *          int32_t height;
298  *      };
299  *
300  *      struct people_heights {
301  *          struct person_height heights[10];
302  *          size_t heights_len;
303  *      };
304  *
305  *      struct json_obj_descr person_height_descr[] = {
306  *           JSON_OBJ_DESCR_PRIM(struct person_height, name, JSON_TOK_STRING),
307  *           JSON_OBJ_DESCR_PRIM(struct person_height, height, JSON_TOK_NUMBER),
308  *      };
309  *
310  *      struct json_obj_descr array[] = {
311  *           JSON_OBJ_DESCR_OBJ_ARRAY(struct people_heights, heights, 10,
312  *                                    heights_len, person_height_descr,
313  *                                    ARRAY_SIZE(person_height_descr)),
314  *      };
315  */
316 #define JSON_OBJ_DESCR_OBJ_ARRAY(struct_, field_name_, max_len_, \
317 				 len_field_, elem_descr_, elem_descr_len_) \
318 	{ \
319 		.field_name = (#field_name_), \
320 		.align_shift = Z_ALIGN_SHIFT(struct_), \
321 		.field_name_len = sizeof(#field_name_) - 1, \
322 		.type = JSON_TOK_ARRAY_START, \
323 		.offset = offsetof(struct_, field_name_), \
324 		.array = { \
325 			.element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
326 				JSON_TOK_OBJECT_START, \
327 				Z_JSON_DESCR_OBJ(elem_descr_, elem_descr_len_)), \
328 			.n_elements = (max_len_), \
329 		}, \
330 	}
331 
332 /**
333  * @brief Helper macro to declare a descriptor for an array of array
334  *
335  * @param struct_ Struct packing the values
336  * @param field_name_ Field name in the struct containing the array
337  * @param max_len_ Maximum number of elements in the array
338  * @param len_field_ Field name in the struct for the number of elements
339  * in the array
340  * @param elem_descr_ Element descriptor, pointer to a descriptor array
341  * @param elem_descr_len_ Number of elements in elem_descr_
342  *
343  * Here's an example of use:
344  *
345  *      struct person_height {
346  *          const char *name;
347  *          int32_t height;
348  *      };
349  *
350  *      struct person_heights_array {
351  *          struct person_height heights;
352  *      }
353  *
354  *      struct people_heights {
355  *          struct person_height_array heights[10];
356  *          size_t heights_len;
357  *      };
358  *
359  *      struct json_obj_descr person_height_descr[] = {
360  *          JSON_OBJ_DESCR_PRIM(struct person_height, name, JSON_TOK_STRING),
361  *          JSON_OBJ_DESCR_PRIM(struct person_height, height, JSON_TOK_NUMBER),
362  *      };
363  *
364  *      struct json_obj_descr person_height_array_descr[] = {
365  *          JSON_OBJ_DESCR_OBJECT(struct person_heights_array,
366  *                                heights, person_height_descr),
367  *      };
368  *
369  *      struct json_obj_descr array_array[] = {
370  *           JSON_OBJ_DESCR_ARRAY_ARRAY(struct people_heights, heights, 10,
371  *                                      heights_len, person_height_array_descr,
372  *                                      ARRAY_SIZE(person_height_array_descr)),
373  *      };
374  */
375 #define JSON_OBJ_DESCR_ARRAY_ARRAY(struct_, field_name_, max_len_, len_field_, \
376 				   elem_descr_, elem_descr_len_) \
377 	{ \
378 		.field_name = (#field_name_), \
379 		.align_shift = Z_ALIGN_SHIFT(struct_), \
380 		.field_name_len = sizeof(#field_name_) - 1, \
381 		.type = JSON_TOK_ARRAY_START, \
382 		.offset = offsetof(struct_, field_name_), \
383 		.array = { \
384 			.element_descr = Z_JSON_ELEMENT_DESCR( \
385 				struct_, len_field_, JSON_TOK_ARRAY_START, \
386 				Z_JSON_DESCR_ARRAY( \
387 					elem_descr_, \
388 					1 + ZERO_OR_COMPILE_ERROR(elem_descr_len_ == 1))), \
389 			.n_elements = (max_len_), \
390 		}, \
391 	}
392 
393 /**
394  * @brief Variant of JSON_OBJ_DESCR_ARRAY_ARRAY that can be used when the
395  *        structure and JSON field names differ.
396  *
397  * This is useful when the JSON field is not a valid C identifier.
398  *
399  * @param struct_ Struct packing the values
400  * @param json_field_name_ String, field name in JSON strings
401  * @param struct_field_name_ Field name in the struct containing the array
402  * @param max_len_ Maximum number of elements in the array
403  * @param len_field_ Field name in the struct for the number of elements
404  * in the array
405  * @param elem_descr_ Element descriptor, pointer to a descriptor array
406  * @param elem_descr_len_ Number of elements in elem_descr_
407  *
408  * @see JSON_OBJ_DESCR_ARRAY_ARRAY
409  */
410 #define JSON_OBJ_DESCR_ARRAY_ARRAY_NAMED(struct_, json_field_name_, struct_field_name_, \
411 					 max_len_, len_field_, elem_descr_, elem_descr_len_) \
412 	{ \
413 		.field_name = (#json_field_name_), \
414 		.align_shift = Z_ALIGN_SHIFT(struct_), \
415 		.field_name_len = sizeof(#json_field_name_) - 1, \
416 		.type = JSON_TOK_ARRAY_START, \
417 		.offset = offsetof(struct_, struct_field_name_), \
418 		.array = { \
419 			.element_descr = Z_JSON_ELEMENT_DESCR( \
420 				struct_, len_field_, JSON_TOK_ARRAY_START, \
421 				Z_JSON_DESCR_ARRAY( \
422 					elem_descr_, \
423 					1 + ZERO_OR_COMPILE_ERROR(elem_descr_len_ == 1))), \
424 			.n_elements = (max_len_), \
425 		}, \
426 	}
427 
428 /**
429  * @brief Variant of JSON_OBJ_DESCR_PRIM that can be used when the
430  *        structure and JSON field names differ.
431  *
432  * This is useful when the JSON field is not a valid C identifier.
433  *
434  * @param struct_ Struct packing the values.
435  * @param json_field_name_ String, field name in JSON strings
436  * @param struct_field_name_ Field name in the struct
437  * @param type_ Token type for JSON value corresponding to a primitive
438  * type.
439  *
440  * @see JSON_OBJ_DESCR_PRIM
441  */
442 #define JSON_OBJ_DESCR_PRIM_NAMED(struct_, json_field_name_, \
443 				  struct_field_name_, type_) \
444 	{ \
445 		.field_name = (json_field_name_), \
446 		.align_shift = Z_ALIGN_SHIFT(struct_), \
447 		.field_name_len = sizeof(json_field_name_) - 1, \
448 		.type = type_, \
449 		.offset = offsetof(struct_, struct_field_name_), \
450 	}
451 
452 /**
453  * @brief Variant of JSON_OBJ_DESCR_OBJECT that can be used when the
454  *        structure and JSON field names differ.
455  *
456  * This is useful when the JSON field is not a valid C identifier.
457  *
458  * @param struct_ Struct packing the values
459  * @param json_field_name_ String, field name in JSON strings
460  * @param struct_field_name_ Field name in the struct
461  * @param sub_descr_ Array of json_obj_descr describing the subobject
462  *
463  * @see JSON_OBJ_DESCR_OBJECT
464  */
465 #define JSON_OBJ_DESCR_OBJECT_NAMED(struct_, json_field_name_, \
466 				    struct_field_name_, sub_descr_) \
467 	{ \
468 		.field_name = (json_field_name_), \
469 		.align_shift = Z_ALIGN_SHIFT(struct_), \
470 		.field_name_len = (sizeof(json_field_name_) - 1), \
471 		.type = JSON_TOK_OBJECT_START, \
472 		.offset = offsetof(struct_, struct_field_name_), \
473 		.object = { \
474 			.sub_descr = sub_descr_, \
475 			.sub_descr_len = ARRAY_SIZE(sub_descr_), \
476 		}, \
477 	}
478 
479 /**
480  * @brief Variant of JSON_OBJ_DESCR_ARRAY that can be used when the
481  *        structure and JSON field names differ.
482  *
483  * This is useful when the JSON field is not a valid C identifier.
484  *
485  * @param struct_ Struct packing the values
486  * @param json_field_name_ String, field name in JSON strings
487  * @param struct_field_name_ Field name in the struct
488  * @param max_len_ Maximum number of elements in array
489  * @param len_field_ Field name in the struct for the number of elements
490  * in the array
491  * @param elem_type_ Element type, must be a primitive type
492  *
493  * @see JSON_OBJ_DESCR_ARRAY
494  */
495 #define JSON_OBJ_DESCR_ARRAY_NAMED(struct_, json_field_name_,\
496 				   struct_field_name_, max_len_, len_field_, \
497 				   elem_type_) \
498 	{ \
499 		.field_name = (json_field_name_), \
500 		.align_shift = Z_ALIGN_SHIFT(struct_), \
501 		.field_name_len = sizeof(json_field_name_) - 1, \
502 		.type = JSON_TOK_ARRAY_START, \
503 		.offset = offsetof(struct_, struct_field_name_), \
504 		.array = { \
505 			.element_descr = \
506 				Z_JSON_ELEMENT_DESCR(struct_, len_field_, elem_type_,), \
507 			.n_elements = (max_len_), \
508 		}, \
509 	}
510 
511 /**
512  * @brief Variant of JSON_OBJ_DESCR_OBJ_ARRAY that can be used when
513  *        the structure and JSON field names differ.
514  *
515  * This is useful when the JSON field is not a valid C identifier.
516  *
517  * @param struct_ Struct packing the values
518  * @param json_field_name_ String, field name of the array in JSON strings
519  * @param struct_field_name_ Field name in the struct containing the array
520  * @param max_len_ Maximum number of elements in the array
521  * @param len_field_ Field name in the struct for the number of elements
522  * in the array
523  * @param elem_descr_ Element descriptor, pointer to a descriptor array
524  * @param elem_descr_len_ Number of elements in elem_descr_
525  *
526  * Here's an example of use:
527  *
528  *      struct person_height {
529  *          const char *name;
530  *          int32_t height;
531  *      };
532  *
533  *      struct people_heights {
534  *          struct person_height heights[10];
535  *          size_t heights_len;
536  *      };
537  *
538  *      struct json_obj_descr person_height_descr[] = {
539  *           JSON_OBJ_DESCR_PRIM(struct person_height, name, JSON_TOK_STRING),
540  *           JSON_OBJ_DESCR_PRIM(struct person_height, height, JSON_TOK_NUMBER),
541  *      };
542  *
543  *      struct json_obj_descr array[] = {
544  *           JSON_OBJ_DESCR_OBJ_ARRAY_NAMED(struct people_heights,
545  *                                          "people-heights", heights,
546  *                                          10, heights_len,
547  *                                          person_height_descr,
548  *                                          ARRAY_SIZE(person_height_descr)),
549  *      };
550  */
551 #define JSON_OBJ_DESCR_OBJ_ARRAY_NAMED(struct_, json_field_name_, \
552 				       struct_field_name_, max_len_, \
553 				       len_field_, elem_descr_, \
554 				       elem_descr_len_) \
555 	{ \
556 		.field_name = json_field_name_, \
557 		.align_shift = Z_ALIGN_SHIFT(struct_), \
558 		.field_name_len = sizeof(json_field_name_) - 1, \
559 		.type = JSON_TOK_ARRAY_START, \
560 		.offset = offsetof(struct_, struct_field_name_), \
561 		.array = { \
562 			.element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
563 				JSON_TOK_OBJECT_START, \
564 				Z_JSON_DESCR_OBJ(elem_descr_, elem_descr_len_)), \
565 			.n_elements = (max_len_), \
566 		}, \
567 	}
568 
569 /**
570  * @brief Parses the JSON-encoded object pointed to by @a json, with
571  * size @a len, according to the descriptor pointed to by @a descr.
572  * Values are stored in a struct pointed to by @a val.  Set up the
573  * descriptor like this:
574  *
575  *    struct s { int32_t foo; char *bar; }
576  *    struct json_obj_descr descr[] = {
577  *       JSON_OBJ_DESCR_PRIM(struct s, foo, JSON_TOK_NUMBER),
578  *       JSON_OBJ_DESCR_PRIM(struct s, bar, JSON_TOK_STRING),
579  *    };
580  *
581  * Since this parser is designed for machine-to-machine communications, some
582  * liberties were taken to simplify the design:
583  * (1) strings are not unescaped (but only valid escape sequences are
584  * accepted);
585  * (2) no UTF-8 validation is performed; and
586  * (3) only integer numbers are supported (no strtod() in the minimal libc).
587  *
588  * @param json Pointer to JSON-encoded value to be parsed
589  * @param len Length of JSON-encoded value
590  * @param descr Pointer to the descriptor array
591  * @param descr_len Number of elements in the descriptor array. Must be less
592  * than 63 due to implementation detail reasons (if more fields are
593  * necessary, use two descriptors)
594  * @param val Pointer to the struct to hold the decoded values
595  *
596  * @return < 0 if error, bitmap of decoded fields on success (bit 0
597  * is set if first field in the descriptor has been properly decoded, etc).
598  */
599 int64_t json_obj_parse(char *json, size_t len,
600 	const struct json_obj_descr *descr, size_t descr_len,
601 	void *val);
602 
603 /**
604  * @brief Parses the JSON-encoded array pointed to by @a json, with
605  * size @a len, according to the descriptor pointed to by @a descr.
606  * Values are stored in a struct pointed to by @a val.  Set up the
607  * descriptor like this:
608  *
609  *    struct s { int32_t foo; char *bar; }
610  *    struct json_obj_descr descr[] = {
611  *       JSON_OBJ_DESCR_PRIM(struct s, foo, JSON_TOK_NUMBER),
612  *       JSON_OBJ_DESCR_PRIM(struct s, bar, JSON_TOK_STRING),
613  *    };
614  *    struct a { struct s baz[10]; size_t count; }
615  *    struct json_obj_descr array[] = {
616  *       JSON_OBJ_DESCR_OBJ_ARRAY(struct a, baz, 10, count,
617  *                                descr, ARRAY_SIZE(descr)),
618  *    };
619  *
620  * Since this parser is designed for machine-to-machine communications, some
621  * liberties were taken to simplify the design:
622  * (1) strings are not unescaped (but only valid escape sequences are
623  * accepted);
624  * (2) no UTF-8 validation is performed; and
625  * (3) only integer numbers are supported (no strtod() in the minimal libc).
626  *
627  * @param json Pointer to JSON-encoded array to be parsed
628  * @param len Length of JSON-encoded array
629  * @param descr Pointer to the descriptor array
630  * @param val Pointer to the struct to hold the decoded values
631  *
632  * @return 0 if array has been successfully parsed. A negative value
633  * indicates an error (as defined on errno.h).
634  */
635 int json_arr_parse(char *json, size_t len,
636 	const struct json_obj_descr *descr, void *val);
637 
638 /**
639  * @brief Initialize single-object array parsing
640  *
641  * JSON-encoded array data is going to be parsed one object at a time. Data is provided by
642  * @a payload with the size of @a len bytes.
643  *
644  * Function validate that Json Array start is detected and initialize @a json object for
645  * Json object parsing separately.
646  *
647  * @param json Provide storage for parser states. To be used when parsing the array.
648  * @param payload Pointer to JSON-encoded array to be parsed
649  * @param len Length of JSON-encoded array
650  *
651  * @return 0 if array start is detected and initialization is successful or negative error
652  * code in case of failure.
653  */
654 int json_arr_separate_object_parse_init(struct json_obj *json, char *payload, size_t len);
655 
656 /**
657  * @brief Parse a single object from array.
658  *
659  * Parses the JSON-encoded object pointed to by @a json object array, with
660  * size @a len, according to the descriptor pointed to by @a descr.
661  *
662  * @param json Pointer to JSON-object message state
663  * @param descr Pointer to the descriptor array
664  * @param descr_len Number of elements in the descriptor array. Must be less than 31.
665  * @param val Pointer to the struct to hold the decoded values
666  *
667  * @return < 0 if error, 0 for end of message, bitmap of decoded fields on success (bit 0
668  * is set if first field in the descriptor has been properly decoded, etc).
669  */
670 int json_arr_separate_parse_object(struct json_obj *json, const struct json_obj_descr *descr,
671 				   size_t descr_len, void *val);
672 
673 /**
674  * @brief Escapes the string so it can be used to encode JSON objects
675  *
676  * @param str The string to escape; the escape string is stored the
677  * buffer pointed to by this parameter
678  * @param len Points to a size_t containing the size before and after
679  * the escaping process
680  * @param buf_size The size of buffer str points to
681  *
682  * @return 0 if string has been escaped properly, or -ENOMEM if there
683  * was not enough space to escape the buffer
684  */
685 ssize_t json_escape(char *str, size_t *len, size_t buf_size);
686 
687 /**
688  * @brief Calculates the JSON-escaped string length
689  *
690  * @param str The string to analyze
691  * @param len String size
692  *
693  * @return The length str would have if it were escaped
694  */
695 size_t json_calc_escaped_len(const char *str, size_t len);
696 
697 /**
698  * @brief Calculates the string length to fully encode an object
699  *
700  * @param descr Pointer to the descriptor array
701  * @param descr_len Number of elements in the descriptor array
702  * @param val Struct holding the values
703  *
704  * @return Number of bytes necessary to encode the values if >0,
705  * an error code is returned.
706  */
707 ssize_t json_calc_encoded_len(const struct json_obj_descr *descr,
708 			      size_t descr_len, const void *val);
709 
710 /**
711  * @brief Calculates the string length to fully encode an array
712  *
713  * @param descr Pointer to the descriptor array
714  * @param val Struct holding the values
715  *
716  * @return Number of bytes necessary to encode the values if >0,
717  * an error code is returned.
718  */
719 ssize_t json_calc_encoded_arr_len(const struct json_obj_descr *descr,
720 				  const void *val);
721 
722 /**
723  * @brief Encodes an object in a contiguous memory location
724  *
725  * @param descr Pointer to the descriptor array
726  * @param descr_len Number of elements in the descriptor array
727  * @param val Struct holding the values
728  * @param buffer Buffer to store the JSON data
729  * @param buf_size Size of buffer, in bytes, with space for the terminating
730  * NUL character
731  *
732  * @return 0 if object has been successfully encoded. A negative value
733  * indicates an error (as defined on errno.h).
734  */
735 int json_obj_encode_buf(const struct json_obj_descr *descr, size_t descr_len,
736 			const void *val, char *buffer, size_t buf_size);
737 
738 /**
739  * @brief Encodes an array in a contiguous memory location
740  *
741  * @param descr Pointer to the descriptor array
742  * @param val Struct holding the values
743  * @param buffer Buffer to store the JSON data
744  * @param buf_size Size of buffer, in bytes, with space for the terminating
745  * NUL character
746  *
747  * @return 0 if object has been successfully encoded. A negative value
748  * indicates an error (as defined on errno.h).
749  */
750 int json_arr_encode_buf(const struct json_obj_descr *descr, const void *val,
751 			char *buffer, size_t buf_size);
752 
753 /**
754  * @brief Encodes an object using an arbitrary writer function
755  *
756  * @param descr Pointer to the descriptor array
757  * @param descr_len Number of elements in the descriptor array
758  * @param val Struct holding the values
759  * @param append_bytes Function to append bytes to the output
760  * @param data Data pointer to be passed to the append_bytes callback
761  * function.
762  *
763  * @return 0 if object has been successfully encoded. A negative value
764  * indicates an error.
765  */
766 int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len,
767 		    const void *val, json_append_bytes_t append_bytes,
768 		    void *data);
769 
770 /**
771  * @brief Encodes an array using an arbitrary writer function
772  *
773  * @param descr Pointer to the descriptor array
774  * @param val Struct holding the values
775  * @param append_bytes Function to append bytes to the output
776  * @param data Data pointer to be passed to the append_bytes callback
777  * function.
778  *
779  * @return 0 if object has been successfully encoded. A negative value
780  * indicates an error.
781  */
782 int json_arr_encode(const struct json_obj_descr *descr, const void *val,
783 		    json_append_bytes_t append_bytes, void *data);
784 
785 #ifdef __cplusplus
786 }
787 #endif
788 
789 /**
790  * @}
791  */
792 #endif /* ZEPHYR_INCLUDE_DATA_JSON_H_ */
793