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