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