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