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