Topics

Json descripte


christian tavares
 

Hello! I have a json and I would like to descript it, but the problem that json is a array objects of array objects. I was seeing the include/json.h and I can't find the way to describe that json. 

The format is : 

{
"product":[
[
{
"test":"1",
"mode":"test",
}
],
[
{
"test":"2",
"mode":"test",
}
]
]
}

Someone could help me ?


Leandro Pereira
 

Christian,

On 06/25/2018 11:13 AM, christian tavares wrote:
Hello! I have a json and I would like to descript it, but the problem that json is a array objects of array objects. I was seeing the include/json.h and I can't find the way to describe that json.
The JSON parser is quite unorthodox, so it can be quite tricky to declare the descriptor. However, it's quite efficient, type-safe, and can also be used to generate JSON, so once you get the hang of it. you'll see it's not that hard to use, all things considered.

The first step is identifying how to lay the structs down. It's maybe a good idea to start with the innermost struct; please disregard the names, I don't have a lot of context to come up with better ones:

struct product {
const char *test;
const char *mode;
};

Then you can create an struct containing these structs. Since you're going to have an array, you also need a size_t item to hold the number of elements in that array; you'll see it referenced down below when the descriptors are being declared:

#define PRODUCT_LIST_MAX_ITEMS 32
struct product_list {
struct product products[PRODUCT_LIST_MAX_ITEMS];
size_t products_len;
};

And another one, containing the manifest of product lists:

struct manifest {
struct product_list items[PRODUCT_LIST_MAX_ITEMS];
size_t items_len;
};

(In this case, you'll have space for 1024 (32 * 32) items, which might be a *lot* to allocate, in say, the stack of your typical thread in Zephyr; please adjust as required, maybe using different constants for different structs... I would need more context to come up with better sizes.)

Once you have all this, you can start working by defining the descriptors. I usually start with the simplest structs (the ones without nested objects, such as other objects, or arrays):

static const struct json_obj_descr product_desc[] = {
JSON_OBJ_DESCR_PRIM(struct product,
test, JSON_TOK_STRING),
JSON_OBJ_DESCR_PRIM(struct product,
mode, JSON_TOK_STRING),
};

(I don't know much how the JSON you're working with is generated, but if you have the choice of using stronger types -- instead of strings --
please do it. The parser will refuse to parse values that have types different than the ones declared in the descriptors.)

Then define the descriptor for the product_list struct:

static const struct json_obj_descr product_list_desc[] = {
JSON_OBJ_DESCR_ARRAY(struct product_list,
products,
PRODUCT_LIST_MAX_ITEMS,
products_len,
product_desc,
ARRAY_SIZE(product_desc)),
};

Then define the descriptor for the manifest struct:

static const struct json_obj_descr manifest_desc[] = {
JSON_OBJ_DESCR_ARRAY(struct manifest,
items,
PRODUCT_LIST_MAX_ITEMS,
items_len,
product_list_desc,
ARRAY_SIZE(product_list_desc)),
};

Then you can just use json_obj_parse() by pointing it to manifest_desc as the descriptor array, and a pointer to a struct manifest allocated somewhere.

Also note that I wrote this directly while composing the message; I haven't compiled this. So there might be some mismatched parenthesis or missing punctuation somewhere.

Hope this helps,
Leandro