LCOV - code coverage report
Current view: top level - zephyr/data - json.h Hit Total Coverage
Test: new.info Lines: 23 53 43.4 %
Date: 2025-01-09 18:14:39

          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_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           0 : struct json_token {
      55           0 :         enum json_tokens type;
      56           0 :         char *start;
      57           0 :         char *end;
      58             : };
      59             : 
      60           0 : struct json_lexer {
      61           0 :         void *(*state)(struct json_lexer *lex);
      62           0 :         char *start;
      63           0 :         char *pos;
      64           0 :         char *end;
      65           0 :         struct json_token tok;
      66             : };
      67             : 
      68           0 : struct json_obj {
      69           0 :         struct json_lexer lex;
      70             : };
      71             : 
      72           0 : struct json_obj_token {
      73           0 :         char *start;
      74           0 :         size_t length;
      75             : };
      76             : 
      77             : 
      78           0 : struct json_obj_descr {
      79           0 :         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           0 :         uint32_t align_shift : 2;
      87             : 
      88             :         /* 127 characters is more than enough for a field name. */
      89           0 :         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           0 :         uint32_t type : 7;
      98             : 
      99             :         /* 65535 bytes is more than enough for many JSON payloads. */
     100           0 :         uint32_t offset : 16;
     101             : 
     102             :         union {
     103             :                 struct {
     104           0 :                         const struct json_obj_descr *sub_descr;
     105           0 :                         size_t sub_descr_len;
     106           0 :                 } object;
     107             :                 struct {
     108           0 :                         const struct json_obj_descr *element_descr;
     109           0 :                         size_t n_elements;
     110           0 :                 } array;
     111           0 :         };
     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           1 : 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           1 : #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           1 : #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           1 :                              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           1 :                                  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           1 :                                    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           1 :                                          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           1 :                                   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           1 :                                     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           1 :                                    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           1 :                                        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           1 : 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           1 : 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           1 : 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           1 : 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           1 : 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           1 : 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           1 : 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           1 : 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           1 : 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           1 : 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           1 : 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           1 : 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_ */

Generated by: LCOV version 1.14