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_PRIM 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 413 * @param type_ Token type for JSON value corresponding to a primitive 414 * type. 415 * 416 * @see JSON_OBJ_DESCR_PRIM 417 */ 418 #define JSON_OBJ_DESCR_PRIM_NAMED(struct_, json_field_name_, \ 419 struct_field_name_, type_) \ 420 { \ 421 .field_name = (json_field_name_), \ 422 .align_shift = Z_ALIGN_SHIFT(struct_), \ 423 .field_name_len = sizeof(json_field_name_) - 1, \ 424 .type = type_, \ 425 .offset = offsetof(struct_, struct_field_name_), \ 426 } 427 428 /** 429 * @brief Variant of JSON_OBJ_DESCR_OBJECT 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 sub_descr_ Array of json_obj_descr describing the subobject 438 * 439 * @see JSON_OBJ_DESCR_OBJECT 440 */ 441 #define JSON_OBJ_DESCR_OBJECT_NAMED(struct_, json_field_name_, \ 442 struct_field_name_, sub_descr_) \ 443 { \ 444 .field_name = (json_field_name_), \ 445 .align_shift = Z_ALIGN_SHIFT(struct_), \ 446 .field_name_len = (sizeof(json_field_name_) - 1), \ 447 .type = JSON_TOK_OBJECT_START, \ 448 .offset = offsetof(struct_, struct_field_name_), \ 449 { \ 450 .object = { \ 451 .sub_descr = sub_descr_, \ 452 .sub_descr_len = ARRAY_SIZE(sub_descr_), \ 453 }, \ 454 }, \ 455 } 456 457 /** 458 * @brief Variant of JSON_OBJ_DESCR_ARRAY that can be used when the 459 * structure and JSON field names differ. 460 * 461 * This is useful when the JSON field is not a valid C identifier. 462 * 463 * @param struct_ Struct packing the values 464 * @param json_field_name_ String, field name in JSON strings 465 * @param struct_field_name_ Field name in the struct 466 * @param max_len_ Maximum number of elements in array 467 * @param len_field_ Field name in the struct for the number of elements 468 * in the array 469 * @param elem_type_ Element type, must be a primitive type 470 * 471 * @see JSON_OBJ_DESCR_ARRAY 472 */ 473 #define JSON_OBJ_DESCR_ARRAY_NAMED(struct_, json_field_name_,\ 474 struct_field_name_, max_len_, len_field_, \ 475 elem_type_) \ 476 { \ 477 .field_name = (json_field_name_), \ 478 .align_shift = Z_ALIGN_SHIFT(struct_), \ 479 .field_name_len = sizeof(json_field_name_) - 1, \ 480 .type = JSON_TOK_ARRAY_START, \ 481 .offset = offsetof(struct_, struct_field_name_), \ 482 { \ 483 .array = { \ 484 .element_descr = \ 485 Z_JSON_ELEMENT_DESCR(struct_, len_field_, elem_type_,), \ 486 .n_elements = (max_len_), \ 487 }, \ 488 }, \ 489 } 490 491 /** 492 * @brief Variant of JSON_OBJ_DESCR_OBJ_ARRAY that can be used when 493 * the structure and JSON field names differ. 494 * 495 * This is useful when the JSON field is not a valid C identifier. 496 * 497 * @param struct_ Struct packing the values 498 * @param json_field_name_ String, field name of the array in JSON strings 499 * @param struct_field_name_ Field name in the struct containing the array 500 * @param max_len_ Maximum number of elements in the array 501 * @param len_field_ Field name in the struct for the number of elements 502 * in the array 503 * @param elem_descr_ Element descriptor, pointer to a descriptor array 504 * @param elem_descr_len_ Number of elements in elem_descr_ 505 * 506 * Here's an example of use: 507 * 508 * struct person_height { 509 * const char *name; 510 * int32_t height; 511 * }; 512 * 513 * struct people_heights { 514 * struct person_height heights[10]; 515 * size_t heights_len; 516 * }; 517 * 518 * struct json_obj_descr person_height_descr[] = { 519 * JSON_OBJ_DESCR_PRIM(struct person_height, name, JSON_TOK_STRING), 520 * JSON_OBJ_DESCR_PRIM(struct person_height, height, JSON_TOK_NUMBER), 521 * }; 522 * 523 * struct json_obj_descr array[] = { 524 * JSON_OBJ_DESCR_OBJ_ARRAY_NAMED(struct people_heights, 525 * "people-heights", heights, 526 * 10, heights_len, 527 * person_height_descr, 528 * ARRAY_SIZE(person_height_descr)), 529 * }; 530 */ 531 #define JSON_OBJ_DESCR_OBJ_ARRAY_NAMED(struct_, json_field_name_, \ 532 struct_field_name_, max_len_, \ 533 len_field_, elem_descr_, \ 534 elem_descr_len_) \ 535 { \ 536 .field_name = json_field_name_, \ 537 .align_shift = Z_ALIGN_SHIFT(struct_), \ 538 .field_name_len = sizeof(json_field_name_) - 1, \ 539 .type = JSON_TOK_ARRAY_START, \ 540 .offset = offsetof(struct_, struct_field_name_), \ 541 { \ 542 .array = { \ 543 .element_descr = Z_JSON_ELEMENT_DESCR(struct_, len_field_, \ 544 JSON_TOK_OBJECT_START, \ 545 Z_JSON_DESCR_OBJ(elem_descr_, elem_descr_len_)), \ 546 .n_elements = (max_len_), \ 547 }, \ 548 }, \ 549 } 550 551 /** 552 * @brief Parses the JSON-encoded object pointed to by @a json, with 553 * size @a len, according to the descriptor pointed to by @a descr. 554 * Values are stored in a struct pointed to by @a val. Set up the 555 * descriptor like this: 556 * 557 * struct s { int32_t foo; char *bar; } 558 * struct json_obj_descr descr[] = { 559 * JSON_OBJ_DESCR_PRIM(struct s, foo, JSON_TOK_NUMBER), 560 * JSON_OBJ_DESCR_PRIM(struct s, bar, JSON_TOK_STRING), 561 * }; 562 * 563 * Since this parser is designed for machine-to-machine communications, some 564 * liberties were taken to simplify the design: 565 * (1) strings are not unescaped (but only valid escape sequences are 566 * accepted); 567 * (2) no UTF-8 validation is performed; and 568 * (3) only integer numbers are supported (no strtod() in the minimal libc). 569 * 570 * @param json Pointer to JSON-encoded value to be parsed 571 * @param len Length of JSON-encoded value 572 * @param descr Pointer to the descriptor array 573 * @param descr_len Number of elements in the descriptor array. Must be less 574 * than 63 due to implementation detail reasons (if more fields are 575 * necessary, use two descriptors) 576 * @param val Pointer to the struct to hold the decoded values 577 * 578 * @return < 0 if error, bitmap of decoded fields on success (bit 0 579 * is set if first field in the descriptor has been properly decoded, etc). 580 */ 581 int64_t json_obj_parse(char *json, size_t len, 582 const struct json_obj_descr *descr, size_t descr_len, 583 void *val); 584 585 /** 586 * @brief Parses the JSON-encoded array pointed to by @a json, with 587 * size @a len, according to the descriptor pointed to by @a descr. 588 * Values are stored in a struct pointed to by @a val. Set up the 589 * descriptor like this: 590 * 591 * struct s { int32_t foo; char *bar; } 592 * struct json_obj_descr descr[] = { 593 * JSON_OBJ_DESCR_PRIM(struct s, foo, JSON_TOK_NUMBER), 594 * JSON_OBJ_DESCR_PRIM(struct s, bar, JSON_TOK_STRING), 595 * }; 596 * struct a { struct s baz[10]; size_t count; } 597 * struct json_obj_descr array[] = { 598 * JSON_OBJ_DESCR_OBJ_ARRAY(struct a, baz, 10, count, 599 * descr, ARRAY_SIZE(descr)), 600 * }; 601 * 602 * Since this parser is designed for machine-to-machine communications, some 603 * liberties were taken to simplify the design: 604 * (1) strings are not unescaped (but only valid escape sequences are 605 * accepted); 606 * (2) no UTF-8 validation is performed; and 607 * (3) only integer numbers are supported (no strtod() in the minimal libc). 608 * 609 * @param json Pointer to JSON-encoded array to be parsed 610 * @param len Length of JSON-encoded array 611 * @param descr Pointer to the descriptor array 612 * @param val Pointer to the struct to hold the decoded values 613 * 614 * @return 0 if array has been successfully parsed. A negative value 615 * indicates an error (as defined on errno.h). 616 */ 617 int json_arr_parse(char *json, size_t len, 618 const struct json_obj_descr *descr, void *val); 619 620 /** 621 * @brief Initialize single-object array parsing 622 * 623 * JSON-encoded array data is going to be parsed one object at a time. Data is provided by 624 * @a payload with the size of @a len bytes. 625 * 626 * Function validate that Json Array start is detected and initialize @a json object for 627 * Json object parsing separately. 628 * 629 * @param json Provide storage for parser states. To be used when parsing the array. 630 * @param payload Pointer to JSON-encoded array to be parsed 631 * @param len Length of JSON-encoded array 632 * 633 * @return 0 if array start is detected and initialization is successful or negative error 634 * code in case of failure. 635 */ 636 int json_arr_separate_object_parse_init(struct json_obj *json, char *payload, size_t len); 637 638 /** 639 * @brief Parse a single object from array. 640 * 641 * Parses the JSON-encoded object pointed to by @a json object array, with 642 * size @a len, according to the descriptor pointed to by @a descr. 643 * 644 * @param json Pointer to JSON-object message state 645 * @param descr Pointer to the descriptor array 646 * @param descr_len Number of elements in the descriptor array. Must be less than 31. 647 * @param val Pointer to the struct to hold the decoded values 648 * 649 * @return < 0 if error, 0 for end of message, bitmap of decoded fields on success (bit 0 650 * is set if first field in the descriptor has been properly decoded, etc). 651 */ 652 int json_arr_separate_parse_object(struct json_obj *json, const struct json_obj_descr *descr, 653 size_t descr_len, void *val); 654 655 /** 656 * @brief Escapes the string so it can be used to encode JSON objects 657 * 658 * @param str The string to escape; the escape string is stored the 659 * buffer pointed to by this parameter 660 * @param len Points to a size_t containing the size before and after 661 * the escaping process 662 * @param buf_size The size of buffer str points to 663 * 664 * @return 0 if string has been escaped properly, or -ENOMEM if there 665 * was not enough space to escape the buffer 666 */ 667 ssize_t json_escape(char *str, size_t *len, size_t buf_size); 668 669 /** 670 * @brief Calculates the JSON-escaped string length 671 * 672 * @param str The string to analyze 673 * @param len String size 674 * 675 * @return The length str would have if it were escaped 676 */ 677 size_t json_calc_escaped_len(const char *str, size_t len); 678 679 /** 680 * @brief Calculates the string length to fully encode an object 681 * 682 * @param descr Pointer to the descriptor array 683 * @param descr_len Number of elements in the descriptor array 684 * @param val Struct holding the values 685 * 686 * @return Number of bytes necessary to encode the values if >0, 687 * an error code is returned. 688 */ 689 ssize_t json_calc_encoded_len(const struct json_obj_descr *descr, 690 size_t descr_len, const void *val); 691 692 /** 693 * @brief Calculates the string length to fully encode an array 694 * 695 * @param descr Pointer to the descriptor array 696 * @param val Struct holding the values 697 * 698 * @return Number of bytes necessary to encode the values if >0, 699 * an error code is returned. 700 */ 701 ssize_t json_calc_encoded_arr_len(const struct json_obj_descr *descr, 702 const void *val); 703 704 /** 705 * @brief Encodes an object in a contiguous memory location 706 * 707 * @param descr Pointer to the descriptor array 708 * @param descr_len Number of elements in the descriptor array 709 * @param val Struct holding the values 710 * @param buffer Buffer to store the JSON data 711 * @param buf_size Size of buffer, in bytes, with space for the terminating 712 * NUL character 713 * 714 * @return 0 if object has been successfully encoded. A negative value 715 * indicates an error (as defined on errno.h). 716 */ 717 int json_obj_encode_buf(const struct json_obj_descr *descr, size_t descr_len, 718 const void *val, char *buffer, size_t buf_size); 719 720 /** 721 * @brief Encodes an array in a contiguous memory location 722 * 723 * @param descr Pointer to the descriptor array 724 * @param val Struct holding the values 725 * @param buffer Buffer to store the JSON data 726 * @param buf_size Size of buffer, in bytes, with space for the terminating 727 * NUL character 728 * 729 * @return 0 if object has been successfully encoded. A negative value 730 * indicates an error (as defined on errno.h). 731 */ 732 int json_arr_encode_buf(const struct json_obj_descr *descr, const void *val, 733 char *buffer, size_t buf_size); 734 735 /** 736 * @brief Encodes an object using an arbitrary writer function 737 * 738 * @param descr Pointer to the descriptor array 739 * @param descr_len Number of elements in the descriptor array 740 * @param val Struct holding the values 741 * @param append_bytes Function to append bytes to the output 742 * @param data Data pointer to be passed to the append_bytes callback 743 * function. 744 * 745 * @return 0 if object has been successfully encoded. A negative value 746 * indicates an error. 747 */ 748 int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len, 749 const void *val, json_append_bytes_t append_bytes, 750 void *data); 751 752 /** 753 * @brief Encodes an array using an arbitrary writer function 754 * 755 * @param descr Pointer to the descriptor array 756 * @param val Struct holding the values 757 * @param append_bytes Function to append bytes to the output 758 * @param data Data pointer to be passed to the append_bytes callback 759 * function. 760 * 761 * @return 0 if object has been successfully encoded. A negative value 762 * indicates an error. 763 */ 764 int json_arr_encode(const struct json_obj_descr *descr, const void *val, 765 json_append_bytes_t append_bytes, void *data); 766 767 #ifdef __cplusplus 768 } 769 #endif 770 771 /** 772 * @} 773 */ 774 #endif /* ZEPHYR_INCLUDE_DATA_JSON_H_ */ 775