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