From 44499768a853013d0b01ac8fe590cf62942e1e5d Mon Sep 17 00:00:00 2001 From: Marti Bolivar Date: Wed, 31 May 2017 11:14:11 -0400 Subject: [PATCH] lib: json: add JSON_OBJ_DESCR_*_NAMED variants The set of valid JSON field names is larger than the set of C identifiers. This can result in structure field names which pack decoded JSON values which necessarily differ from the field names in the JSON. Support this by adding _NAMED variants to each of the JSON_OBJ_DESCR_* helper macros. For example, JSON_OBJ_DESCR_PRIM_NAMED allows users to declare a descriptor field for a primitive type, whose structure field name is different from the JSON field name. Signed-off-by: Marti Bolivar --- lib/json/json.h | 89 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/lib/json/json.h b/lib/json/json.h index 9b3e92cdfc9..5f3c751b94d 100644 --- a/lib/json/json.h +++ b/lib/json/json.h @@ -172,6 +172,95 @@ typedef int (*json_append_bytes_t)(const u8_t *bytes, size_t len, .n_elements = (max_len_), \ } +/** + * @brief Variant of JSON_OBJ_DESCR_PRIM that can be used when the + * structure and JSON field names differ. + * + * This is useful when the JSON field is not a valid C identifier. + * + * @param struct_ Struct packing the values. + * + * @param json_field_name_ String, field name in JSON strings + * + * @param struct_field_name_ Field name in the struct + * + * @param type_ Token type for JSON value corresponding to a primitive + * type. + * + * @see JSON_OBJ_DESCR_PRIM + */ +#define JSON_OBJ_DESCR_PRIM_NAMED(struct_, json_field_name_, \ + struct_field_name_, type_) \ + { \ + .field_name = (json_field_name_), \ + .field_name_len = sizeof(json_field_name_) - 1, \ + .offset = offsetof(struct_, struct_field_name_), \ + .type = type_, \ + } + +/** + * @brief Variant of JSON_OBJ_DESCR_OBJECT that can be used when the + * structure and JSON field names differ. + * + * This is useful when the JSON field is not a valid C identifier. + * + * @param struct_ Struct packing the values + * + * @param json_field_name_ String, field name in JSON strings + * + * @param struct_field_name_ Field name in the struct + * + * @param sub_descr_ Array of json_obj_descr describing the subobject + * + * @see JSON_OBJ_DESCR_OBJECT + */ +#define JSON_OBJ_DESCR_OBJECT_NAMED(struct_, json_field_name_, \ + struct_field_name_, sub_descr_) \ + { \ + .field_name = (json_field_name_), \ + .field_name_len = (sizeof(json_field_name_) - 1), \ + .offset = offsetof(struct_, struct_field_name_), \ + .type = JSON_TOK_OBJECT_START, \ + .sub_descr = sub_descr_, \ + .sub_descr_len = ARRAY_SIZE(sub_descr_) \ + } + +/** + * @brief Variant of JSON_OBJ_DESCR_ARRAY that can be used when the + * structure and JSON field names differ. + * + * This is useful when the JSON field is not a valid C identifier. + * + * @param struct_ Struct packing the values + * + * @param json_field_name_ String, field name in JSON strings + * + * @param struct_field_name_ Field name in the struct + * + * @param max_len_ Maximum number of elements in array + * + * @param len_field_ Field name in the struct for the number of elements + * in the array + * + * @param elem_type_ Element type + * + * @see JSON_OBJ_DESCR_ARRAY + */ +#define JSON_OBJ_DESCR_ARRAY_NAMED(struct_, json_field_name_,\ + struct_field_name_, max_len_, len_field_, \ + elem_type_) \ + { \ + .field_name = (json_field_name_), \ + .field_name_len = sizeof(json_field_name_) - 1, \ + .offset = offsetof(struct_, struct_field_name_), \ + .type = JSON_TOK_LIST_START, \ + .element_descr = &(struct json_obj_descr) { \ + .type = elem_type_, \ + .offset = offsetof(struct_, len_field_), \ + }, \ + .n_elements = (max_len_), \ + } + /** * @brief Parses the JSON-encoded object pointer to by @param json, with * size @param len, according to the descriptor pointed to by @param descr.