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