LCOV - code coverage report
Current view: top level - zephyr/data - json.h Coverage Total Hit
Test: new.info Lines: 41.0 % 78 32
Test Date: 2025-09-05 16:43:28

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

Generated by: LCOV version 2.0-1