Zephyr Project API  3.3.0
A Scalable Open Source RTOS
json.h
Go to the documentation of this file.
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
17extern "C" {
18#endif
19
33 /* Before changing this enum, ensure that its maximum
34 * value is still within 7 bits. See comment next to the
35 * declaration of `type` in struct json_obj_descr.
36 */
37
41 /* JSON_TOK_LIST_START will be removed use JSON_TOK_ARRAY_START */
42 JSON_TOK_LIST_START __deprecated = '[',
44 /* JSON_TOK_LIST_END will be removed use JSON_TOK_ARRAY_END */
45 JSON_TOK_LIST_END __deprecated = ']',
59};
60
61struct json_token {
63 char *start;
64 char *end;
65};
66
67struct json_lexer {
68 void *(*state)(struct json_lexer *lex);
69 char *start;
70 char *pos;
71 char *end;
73};
74
75struct json_obj {
77};
78
80 char *start;
81 size_t length;
82};
83
84
86 const char *field_name;
87
88 /* Alignment can be 1, 2, 4, or 8. The macros to create
89 * a struct json_obj_descr will store the alignment's
90 * power of 2 in order to keep this value in the 0-3 range
91 * and thus use only 2 bits.
92 */
94
95 /* 127 characters is more than enough for a field name. */
97
98 /* Valid values here (enum json_tokens): JSON_TOK_STRING,
99 * JSON_TOK_NUMBER, JSON_TOK_TRUE, JSON_TOK_FALSE,
100 * JSON_TOK_OBJECT_START, JSON_TOK_ARRAY_START. (All others
101 * ignored.) Maximum value is '}' (125), so this has to be 7 bits
102 * long.
103 */
105
106 /* 65535 bytes is more than enough for many JSON payloads. */
108
109 union {
110 struct {
114 struct {
118 };
119};
120
133typedef int (*json_append_bytes_t)(const char *bytes, size_t len,
134 void *data);
135
136#define Z_ALIGN_SHIFT(type) (__alignof__(type) == 1 ? 0 : \
137 __alignof__(type) == 2 ? 1 : \
138 __alignof__(type) == 4 ? 2 : 3)
139
160#define JSON_OBJ_DESCR_PRIM(struct_, field_name_, type_) \
161 { \
162 .field_name = (#field_name_), \
163 .align_shift = Z_ALIGN_SHIFT(struct_), \
164 .field_name_len = sizeof(#field_name_) - 1, \
165 .type = type_, \
166 .offset = offsetof(struct_, field_name_), \
167 }
168
193#define JSON_OBJ_DESCR_OBJECT(struct_, field_name_, sub_descr_) \
194 { \
195 .field_name = (#field_name_), \
196 .align_shift = Z_ALIGN_SHIFT(struct_), \
197 .field_name_len = (sizeof(#field_name_) - 1), \
198 .type = JSON_TOK_OBJECT_START, \
199 .offset = offsetof(struct_, field_name_), \
200 { \
201 .object = { \
202 .sub_descr = sub_descr_, \
203 .sub_descr_len = ARRAY_SIZE(sub_descr_), \
204 }, \
205 }, \
206 }
207
217#define Z_JSON_ELEMENT_DESCR(struct_, len_field_, elem_type_, union_) \
218 (const struct json_obj_descr[]) \
219 { \
220 { \
221 .align_shift = Z_ALIGN_SHIFT(struct_), \
222 .type = elem_type_, \
223 .offset = offsetof(struct_, len_field_), \
224 union_ \
225 } \
226 }
227
234#define Z_JSON_DESCR_ARRAY(elem_descr_, elem_descr_len_) \
235 { \
236 .array = { \
237 .element_descr = elem_descr_, \
238 .n_elements = elem_descr_len_, \
239 }, \
240 }
241
248#define Z_JSON_DESCR_OBJ(elem_descr_, elem_descr_len_) \
249 { \
250 .object = { \
251 .sub_descr = elem_descr_, \
252 .sub_descr_len = elem_descr_len_, \
253 }, \
254 }
255
278#define JSON_OBJ_DESCR_ARRAY(struct_, field_name_, max_len_, \
279 len_field_, elem_type_) \
280 { \
281 .field_name = (#field_name_), \
282 .align_shift = Z_ALIGN_SHIFT(struct_), \
283 .field_name_len = sizeof(#field_name_) - 1, \
284 .type = JSON_TOK_ARRAY_START, \
285 .offset = offsetof(struct_, field_name_), \
286 { \
287 .array = { \
288 .element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
289 elem_type_,), \
290 .n_elements = (max_len_), \
291 }, \
292 }, \
293 }
294
329#define JSON_OBJ_DESCR_OBJ_ARRAY(struct_, field_name_, max_len_, \
330 len_field_, elem_descr_, elem_descr_len_) \
331 { \
332 .field_name = (#field_name_), \
333 .align_shift = Z_ALIGN_SHIFT(struct_), \
334 .field_name_len = sizeof(#field_name_) - 1, \
335 .type = JSON_TOK_ARRAY_START, \
336 .offset = offsetof(struct_, field_name_), \
337 { \
338 .array = { \
339 .element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
340 JSON_TOK_OBJECT_START, \
341 Z_JSON_DESCR_OBJ(elem_descr_, elem_descr_len_)), \
342 .n_elements = (max_len_), \
343 }, \
344 }, \
345 }
346
390#define JSON_OBJ_DESCR_ARRAY_ARRAY(struct_, field_name_, max_len_, len_field_, \
391 elem_descr_, elem_descr_len_) \
392 { \
393 .field_name = (#field_name_), \
394 .align_shift = Z_ALIGN_SHIFT(struct_), \
395 .field_name_len = sizeof(#field_name_) - 1, \
396 .type = JSON_TOK_ARRAY_START, \
397 .offset = offsetof(struct_, field_name_), \
398 { \
399 .array = { \
400 .element_descr = Z_JSON_ELEMENT_DESCR( \
401 struct_, len_field_, JSON_TOK_ARRAY_START, \
402 Z_JSON_DESCR_ARRAY( \
403 elem_descr_, \
404 1 + ZERO_OR_COMPILE_ERROR(elem_descr_len_ == 1))), \
405 .n_elements = (max_len_), \
406 }, \
407 }, \
408 }
409
424#define JSON_OBJ_DESCR_PRIM_NAMED(struct_, json_field_name_, \
425 struct_field_name_, type_) \
426 { \
427 .field_name = (json_field_name_), \
428 .align_shift = Z_ALIGN_SHIFT(struct_), \
429 .field_name_len = sizeof(json_field_name_) - 1, \
430 .type = type_, \
431 .offset = offsetof(struct_, struct_field_name_), \
432 }
433
447#define JSON_OBJ_DESCR_OBJECT_NAMED(struct_, json_field_name_, \
448 struct_field_name_, sub_descr_) \
449 { \
450 .field_name = (json_field_name_), \
451 .align_shift = Z_ALIGN_SHIFT(struct_), \
452 .field_name_len = (sizeof(json_field_name_) - 1), \
453 .type = JSON_TOK_OBJECT_START, \
454 .offset = offsetof(struct_, struct_field_name_), \
455 { \
456 .object = { \
457 .sub_descr = sub_descr_, \
458 .sub_descr_len = ARRAY_SIZE(sub_descr_), \
459 }, \
460 }, \
461 }
462
479#define JSON_OBJ_DESCR_ARRAY_NAMED(struct_, json_field_name_,\
480 struct_field_name_, max_len_, len_field_, \
481 elem_type_) \
482 { \
483 .field_name = (json_field_name_), \
484 .align_shift = Z_ALIGN_SHIFT(struct_), \
485 .field_name_len = sizeof(json_field_name_) - 1, \
486 .type = JSON_TOK_ARRAY_START, \
487 .offset = offsetof(struct_, struct_field_name_), \
488 { \
489 .array = { \
490 .element_descr = \
491 Z_JSON_ELEMENT_DESCR(struct_, len_field_, elem_type_,), \
492 .n_elements = (max_len_), \
493 }, \
494 }, \
495 }
496
537#define JSON_OBJ_DESCR_OBJ_ARRAY_NAMED(struct_, json_field_name_, \
538 struct_field_name_, max_len_, \
539 len_field_, elem_descr_, \
540 elem_descr_len_) \
541 { \
542 .field_name = json_field_name_, \
543 .align_shift = Z_ALIGN_SHIFT(struct_), \
544 .field_name_len = sizeof(json_field_name_) - 1, \
545 .type = JSON_TOK_ARRAY_START, \
546 .offset = offsetof(struct_, struct_field_name_), \
547 { \
548 .array = { \
549 .element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \
550 JSON_TOK_OBJECT_START, \
551 Z_JSON_DESCR_OBJ(elem_descr_, elem_descr_len_)), \
552 .n_elements = (max_len_), \
553 }, \
554 }, \
555 }
556
587int64_t json_obj_parse(char *json, size_t len,
588 const struct json_obj_descr *descr, size_t descr_len,
589 void *val);
590
623int json_arr_parse(char *json, size_t len,
624 const struct json_obj_descr *descr, void *val);
625
642int json_arr_separate_object_parse_init(struct json_obj *json, char *payload, size_t len);
643
658int json_arr_separate_parse_object(struct json_obj *json, const struct json_obj_descr *descr,
659 size_t descr_len, void *val);
660
673ssize_t json_escape(char *str, size_t *len, size_t buf_size);
674
683size_t json_calc_escaped_len(const char *str, size_t len);
684
696 size_t descr_len, const void *val);
697
711int json_obj_encode_buf(const struct json_obj_descr *descr, size_t descr_len,
712 const void *val, char *buffer, size_t buf_size);
713
726int json_arr_encode_buf(const struct json_obj_descr *descr, const void *val,
727 char *buffer, size_t buf_size);
728
742int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len,
743 const void *val, json_append_bytes_t append_bytes,
744 void *data);
745
758int json_arr_encode(const struct json_obj_descr *descr, const void *val,
759 json_append_bytes_t append_bytes, void *data);
760
761#ifdef __cplusplus
762}
763#endif
764
768#endif /* ZEPHYR_INCLUDE_DATA_JSON_H_ */
json_tokens
Definition: json.h:32
ssize_t json_calc_encoded_len(const struct json_obj_descr *descr, size_t descr_len, const void *val)
Calculates the string length to fully encode an object.
ssize_t json_escape(char *str, size_t *len, size_t buf_size)
Escapes the string so it can be used to encode JSON objects.
int json_arr_encode(const struct json_obj_descr *descr, const void *val, json_append_bytes_t append_bytes, void *data)
Encodes an array using an arbitrary writer function.
size_t json_calc_escaped_len(const char *str, size_t len)
Calculates the JSON-escaped string length.
int json_arr_separate_object_parse_init(struct json_obj *json, char *payload, size_t len)
Initialize single-object array parsing.
int json_arr_separate_parse_object(struct json_obj *json, const struct json_obj_descr *descr, size_t descr_len, void *val)
Parse a single object from array.
int64_t json_obj_parse(char *json, size_t len, const struct json_obj_descr *descr, size_t descr_len, void *val)
Parses the JSON-encoded object pointed to by json, with size len, according to the descriptor pointed...
int json_arr_parse(char *json, size_t len, const struct json_obj_descr *descr, void *val)
Parses the JSON-encoded array pointed to by json, with size len, according to the descriptor pointed ...
int json_obj_encode_buf(const struct json_obj_descr *descr, size_t descr_len, const void *val, char *buffer, size_t buf_size)
Encodes an object in a contiguous memory location.
int(* json_append_bytes_t)(const char *bytes, size_t len, void *data)
Function pointer type to append bytes to a buffer while encoding JSON data.
Definition: json.h:133
int json_arr_encode_buf(const struct json_obj_descr *descr, const void *val, char *buffer, size_t buf_size)
Encodes an array in a contiguous memory location.
int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len, const void *val, json_append_bytes_t append_bytes, void *data)
Encodes an object using an arbitrary writer function.
@ JSON_TOK_OBJ_ARRAY
Definition: json.h:53
@ JSON_TOK_ARRAY_END
Definition: json.h:46
@ JSON_TOK_COLON
Definition: json.h:48
@ JSON_TOK_LIST_END
Definition: json.h:45
@ JSON_TOK_COMMA
Definition: json.h:49
@ JSON_TOK_OBJECT_START
Definition: json.h:39
@ JSON_TOK_OBJECT_END
Definition: json.h:40
@ JSON_TOK_TRUE
Definition: json.h:54
@ JSON_TOK_FALSE
Definition: json.h:55
@ JSON_TOK_LIST_START
Definition: json.h:42
@ JSON_TOK_NONE
Definition: json.h:38
@ JSON_TOK_NULL
Definition: json.h:56
@ JSON_TOK_OPAQUE
Definition: json.h:52
@ JSON_TOK_ARRAY_START
Definition: json.h:43
@ JSON_TOK_FLOAT
Definition: json.h:51
@ JSON_TOK_STRING
Definition: json.h:47
@ JSON_TOK_EOF
Definition: json.h:58
@ JSON_TOK_NUMBER
Definition: json.h:50
@ JSON_TOK_ERROR
Definition: json.h:57
__SIZE_TYPE__ ssize_t
Definition: types.h:28
__UINT32_TYPE__ uint32_t
Definition: stdint.h:90
__INT64_TYPE__ int64_t
Definition: stdint.h:75
Definition: json.h:67
char * pos
Definition: json.h:70
char * start
Definition: json.h:69
struct json_token tok
Definition: json.h:72
char * end
Definition: json.h:71
Definition: json.h:85
const struct json_obj_descr * element_descr
Definition: json.h:115
struct json_obj_descr::@106::@109 array
const char * field_name
Definition: json.h:86
uint32_t align_shift
Definition: json.h:93
const struct json_obj_descr * sub_descr
Definition: json.h:111
uint32_t field_name_len
Definition: json.h:96
struct json_obj_descr::@106::@108 object
uint32_t offset
Definition: json.h:107
uint32_t type
Definition: json.h:104
size_t n_elements
Definition: json.h:116
size_t sub_descr_len
Definition: json.h:112
Definition: json.h:79
size_t length
Definition: json.h:81
char * start
Definition: json.h:80
Definition: json.h:75
struct json_lexer lex
Definition: json.h:76
Definition: json.h:61
char * start
Definition: json.h:63
enum json_tokens type
Definition: json.h:62
char * end
Definition: json.h:64
static fdata_t data[2]
Definition: test_fifo_contexts.c:15
static ZTEST_BMEM char buffer[8]
Definition: test_mbox_api.c:551
Macros to abstract toolchain specific capabilities.
Misc utilities.