sdk 2.1.0
nRF9160
Hi,
I need to parse a JSON file and for that I'm trying to use zephyr's json.h library.
Based on the automatic test file I built a piece of code for this task, but it is not working when the nested structure is an array...
Let me explain my tests:
1-when the nested structure is not declared as an array everything works as expected
struct test_nested {
int nested_int;
const char *nested_string[10];
size_t nested_string_len;
};
struct test_struct {
struct test_nested nested_obj_array;
int some_int;
};
static const struct json_obj_descr nested_descr[] = {
JSON_OBJ_DESCR_PRIM(struct test_nested, nested_int, JSON_TOK_NUMBER),
JSON_OBJ_DESCR_ARRAY(struct test_nested, nested_string, 10, nested_string_len, JSON_TOK_STRING),
};
static const struct json_obj_descr test_descr[] = {
JSON_OBJ_DESCR_OBJECT(struct test_struct, nested_obj_array, nested_descr),
JSON_OBJ_DESCR_PRIM(struct test_struct, some_int, JSON_TOK_NUMBER),
};
struct test_struct test2;
char encoded2[] = "{\"nested_obj_array\":"
"{\"nested_int\":22,"
"\"nested_string\":[\"string11\",\"string12\",\"string13\",\"string14\"]},"
"\"some_int\":123"
"}";
LOG_DBG("encoded:%s", encoded2);
const struct test_struct expected2 = {
.nested_obj_array = {.nested_int = 22, .nested_string = {"string11", "string12", "string13", "string14"}, .nested_string_len = 4},
.some_int = 123,
};
int ret;
ret = json_obj_parse(encoded2, sizeof(encoded2) - 1, test_descr,
ARRAY_SIZE(test_descr), &test2);
if (ret != (1 << ARRAY_SIZE(test_descr)) - 1) {
LOG_DBG("Not all fields decoded correctly! ret:%d != size:%d", ret, (1 << ARRAY_SIZE(test_descr)) - 1);
}
if (test2.some_int != expected2.some_int) {
LOG_DBG("some_int not decoded correctly.");
}
LOG_DBG("test2.some_int=%d", test2.some_int);
if (test2.nested_obj_array.nested_string_len != expected2.nested_obj_array.nested_string_len) {
LOG_DBG("Number of nested_string fields not decoded correctly. decode:%d, expected:%d", test2.nested_obj_array.nested_string_len, expected2.nested_obj_array.nested_string_len);
}
LOG_DBG("test2.nested_obj_array.nested_string_len=%d", test2.nested_obj_array.nested_string_len);
for (int i = 0; i < expected2.nested_obj_array.nested_string_len; i++) {
if (0 != strcmp(test2.nested_obj_array.nested_string[i], expected2.nested_obj_array.nested_string[i])) {
LOG_DBG("test2.nested_obj_array.nested_string[%d] not decoded correctly", i);
}
LOG_DBG("test2.nested_obj_array.nested_string[%d]=%s", i, test2.nested_obj_array.nested_string[i]);
}
if (test2.nested_obj_array.nested_int != expected2.nested_obj_array.nested_int) {
LOG_DBG("nested_int not decoded correctly.");
}
LOG_DBG("test2.nested_obj_array.nested_int=%d", test2.nested_obj_array.nested_int);
output:
[00:00:28.371,063] <dbg> encoded:{"nested_obj_array":{"nested_int":22,"nested_string":["string11","string12","string13","string14"]},"some_int":123}
[00:00:28.372,039] <dbg> test2.some_int=123
[00:00:28.372,589] <dbg> test2.nested_obj_array.nested_string_len=4
[00:00:28.373,229] <dbg> test2.nested_obj_array.nested_string[0]=string11
[00:00:28.373,901] <dbg> test2.nested_obj_array.nested_string[1]=string12
[00:00:28.374,542] <dbg> test2.nested_obj_array.nested_string[2]=string13
[00:00:28.375,213] <dbg> test2.nested_obj_array.nested_string[3]=string14
[00:00:28.375,854] <dbg> test2.nested_obj_array.nested_int=22
2-when the nested structure is declared as an array but only contains one argument, it also works
struct test_nested {
int nested_int;
const char *nested_string[10];
size_t nested_string_len;
};
struct test_struct {
struct test_nested nested_obj_array[5];
size_t nested_obj_array_len;
int some_int;
};
static const struct json_obj_descr nested_descr[] = {
JSON_OBJ_DESCR_PRIM(struct test_nested, nested_int, JSON_TOK_NUMBER),
JSON_OBJ_DESCR_ARRAY(struct test_nested, nested_string, 10, nested_string_len, JSON_TOK_STRING),
};
static const struct json_obj_descr test_descr[] = {
JSON_OBJ_DESCR_OBJ_ARRAY(struct test_struct, nested_obj_array, 5, nested_obj_array_len,
nested_descr, ARRAY_SIZE(nested_descr)),
// JSON_OBJ_DESCR_OBJECT(struct test_struct, nested_obj_array, nested_descr),
JSON_OBJ_DESCR_PRIM(struct test_struct, some_int, JSON_TOK_NUMBER),
};
struct test_struct test3;
char encoded3[] = "{\"nested_obj_array\":["
"{\"nested_int\":22,"
"\"nested_string\":[\"string11\",\"string12\",\"string13\",\"string14\"]}"
"],"
"\"some_int\":123"
"}";
LOG_DBG("encoded:%s", encoded3);
const struct test_struct expected3 = {
.nested_obj_array = {[0] = {.nested_int = 22, .nested_string = {"string11", "string12", "string13", "string14"}, .nested_string_len = 4}
},
.some_int = 123,
.nested_obj_array_len = 1,
};
int ret;
ret = json_obj_parse(encoded3, sizeof(encoded3) - 1, test_descr,
ARRAY_SIZE(test_descr), &test3);
if (ret != (1 << ARRAY_SIZE(test_descr)) - 1) {
LOG_DBG("Not all fields decoded correctly! ret:%d != size:%d", ret, (1 << ARRAY_SIZE(test_descr)) - 1);
}
if (test3.some_int != expected3.some_int) {
LOG_DBG("some_int not decoded correctly.");
}
LOG_DBG("test3.some_int=%d", test3.some_int);
if (test3.nested_obj_array_len != expected3.nested_obj_array_len) {
LOG_DBG("Number of nested_obj_array_len fields not decoded correctly. decode:%d, expected:%d", test3.nested_obj_array_len, expected3.nested_obj_array_len);
}
LOG_DBG("test3.nested_obj_array_len=%d", test3.nested_obj_array_len);
for (size_t j = 0; j < expected3.nested_obj_array_len; j++) {
if (test3.nested_obj_array[j].nested_string_len != expected3.nested_obj_array[j].nested_string_len) {
LOG_DBG("Number of nested_obj_array[%d].nested_string_len fields not decoded correctly. decode:%d, expected:%d", j, test3.nested_obj_array[j].nested_string_len, expected3.nested_obj_array[j].nested_string_len);
}
LOG_DBG("test3.nested_obj_array[%d].nested_string_len=%d", j, test3.nested_obj_array[j].nested_string_len);
for (int i = 0; i < expected3.nested_obj_array[j].nested_string_len; i++) {
if (0 != strcmp(test3.nested_obj_array[j].nested_string[i], expected3.nested_obj_array[j].nested_string[i])) {
LOG_DBG("nested_obj_array[%d].nested_string[%d] not decoded correctly", j, i);
}
LOG_DBG("test3.nested_obj_array[%d].nested_string[%d]=%s", j, i, test3.nested_obj_array[j].nested_string[i]);
}
if (test3.nested_obj_array[j].nested_int != expected3.nested_obj_array[j].nested_int) {
LOG_DBG("nested_int not decoded correctly.");
}
LOG_DBG("test3.nested_obj_array[%d].nested_int=%d", j, test3.nested_obj_array[j].nested_int);
}
output:
[00:01:30.089,050] <dbg> encoded:{"nested_obj_array":[{"nested_int":22,"nested_string":["string11","string12","string13","string14"]}],"some_int":123}
[00:01:30.090,057] <dbg> test3.some_int=123
[00:01:30.090,606] <dbg> test3.nested_obj_array_len=1
[00:01:30.091,217] <dbg> test3.nested_obj_array[0].nested_string_len=4
[00:01:30.091,857] <dbg> test3.nested_obj_array[0].nested_string[0]=string11
[00:01:30.092,529] <dbg> test3.nested_obj_array[0].nested_string[1]=string12
[00:01:30.093,200] <dbg> test3.nested_obj_array[0].nested_string[2]=string13
[00:01:30.093,902] <dbg> test3.nested_obj_array[0].nested_string[3]=string14
[00:01:30.094,573] <dbg> test3.nested_obj_array[0].nested_int=22
3-when the nested structure is declared as an array but contains several arguments it does not parse correctly...
struct test_nested {
int nested_int;
const char *nested_string[10];
size_t nested_string_len;
};
struct test_struct {
struct test_nested nested_obj_array[5];
size_t nested_obj_array_len;
int some_int;
};
static const struct json_obj_descr nested_descr[] = {
JSON_OBJ_DESCR_PRIM(struct test_nested, nested_int, JSON_TOK_NUMBER),
JSON_OBJ_DESCR_ARRAY(struct test_nested, nested_string, 10, nested_string_len, JSON_TOK_STRING),
};
static const struct json_obj_descr test_descr[] = {
JSON_OBJ_DESCR_OBJ_ARRAY(struct test_struct, nested_obj_array, 5, nested_obj_array_len,
nested_descr, ARRAY_SIZE(nested_descr)),
// JSON_OBJ_DESCR_OBJECT(struct test_struct, nested_obj_array, nested_descr),
JSON_OBJ_DESCR_PRIM(struct test_struct, some_int, JSON_TOK_NUMBER),
};
struct test_struct test3;
char encoded3[] = "{\"nested_obj_array\":["
"{\"nested_int\":22,"
"\"nested_string\":[\"string11\",\"string12\",\"string13\",\"string14\"]},"
"{\"nested_int\":33,"
"\"nested_string\":[\"string21\",\"string22\",\"string23\",\"string24\"]}"
"],"
"\"some_int\":123"
"}";
LOG_DBG("encoded:%s", encoded3);
const struct test_struct expected3 = {
.nested_obj_array = {[0] = {.nested_int = 22, .nested_string = {"string11", "string12", "string13", "string14"}, .nested_string_len = 4},
[1] = {.nested_int = 33, .nested_string = {"string21", "string22", "string23", "string24"}, .nested_string_len = 4}
},
.some_int = 123,
.nested_obj_array_len = 2,
};
int ret;
ret = json_obj_parse(encoded3, sizeof(encoded3) - 1, test_descr,
ARRAY_SIZE(test_descr), &test3);
if (ret != (1 << ARRAY_SIZE(test_descr)) - 1) {
LOG_DBG("Not all fields decoded correctly! ret:%d != size:%d", ret, (1 << ARRAY_SIZE(test_descr)) - 1);
}
if (test3.some_int != expected3.some_int) {
LOG_DBG("some_int not decoded correctly.");
}
LOG_DBG("test3.some_int=%d", test3.some_int);
if (test3.nested_obj_array_len != expected3.nested_obj_array_len) {
LOG_DBG("Number of nested_obj_array_len fields not decoded correctly. decode:%d, expected:%d", test3.nested_obj_array_len, expected3.nested_obj_array_len);
}
LOG_DBG("test3.nested_obj_array_len=%d", test3.nested_obj_array_len);
for (size_t j = 0; j < expected3.nested_obj_array_len; j++) {
if (test3.nested_obj_array[j].nested_string_len != expected3.nested_obj_array[j].nested_string_len) {
LOG_DBG("Number of nested_obj_array[%d].nested_string_len fields not decoded correctly. decode:%d, expected:%d", j, test3.nested_obj_array[j].nested_string_len, expected3.nested_obj_array[j].nested_string_len);
}
LOG_DBG("test3.nested_obj_array[%d].nested_string_len=%d", j, test3.nested_obj_array[j].nested_string_len);
for (int i = 0; i < expected3.nested_obj_array[j].nested_string_len; i++) {
if (0 != strcmp(test3.nested_obj_array[j].nested_string[i], expected3.nested_obj_array[j].nested_string[i])) {
LOG_DBG("nested_obj_array[%d].nested_string[%d] not decoded correctly", j, i);
}
LOG_DBG("test3.nested_obj_array[%d].nested_string[%d]=%s", j, i, test3.nested_obj_array[j].nested_string[i]);
}
if (test3.nested_obj_array[j].nested_int != expected3.nested_obj_array[j].nested_int) {
LOG_DBG("nested_int not decoded correctly.");
}
LOG_DBG("test3.nested_obj_array[%d].nested_int=%d", j, test3.nested_obj_array[j].nested_int);
}
output:
[00:00:55.869,873] <dbg> encoded:{"nested_obj_array":[{"nested_int":22,"nested_string":["string11","string12","string13","string14"]},{"nested_int":33,"nested_string":["string21","string22","string23","string24"]}],"some_int":123}
[00:00:55.871,215] <dbg> test3.some_int=123
[00:00:55.871,765] <dbg> test3.nested_obj_array_len=2
[00:00:55.872,375] <dbg> Number of nested_obj_array[0].nested_string_len fields not decoded correctly. decode:33, expected:4
[00:00:55.873,168] <dbg> test3.nested_obj_array[0].nested_string_len=33
[00:00:55.873,840] <dbg> test3.nested_obj_array[0].nested_string[0]=string11
[00:00:55.874,542] <dbg> test3.nested_obj_array[0].nested_string[1]=string12
[00:00:55.875,213] <dbg> test3.nested_obj_array[0].nested_string[2]=string13
[00:00:55.875,915] <dbg> test3.nested_obj_array[0].nested_string[3]=string14
[00:00:55.876,586] <dbg> test3.nested_obj_array[0].nested_int=22
[00:00:55.877,227] <dbg> Number of nested_obj_array[1].nested_string_len fields not decoded correctly. decode:243463, expected:4
[00:00:55.878,051] <dbg> test3.nested_obj_array[1].nested_string_len=243463
[00:00:55.878,753] <dbg> nested_obj_array[1].nested_string[0] not decoded correctly
[00:00:55.879,425] <dbg> test3.nested_obj_array[1].nested_string[0]=string22
[00:00:55.880,126] <dbg> nested_obj_array[1].nested_string[1] not decoded correctly
[00:00:55.880,798] <dbg> test3.nested_obj_array[1].nested_string[1]=string23
[00:00:55.881,500] <dbg> nested_obj_array[1].nested_string[2] not decoded correctly
[00:00:55.882,171] <dbg> test3.nested_obj_array[1].nested_string[2]=string24
[00:00:55.882,873] <dbg> nested_obj_array[1].nested_string[3] not decoded correctly
[00:00:55.883,544] <dbg> test3.nested_obj_array[1].nested_string[3]=
[00:00:55.884,216] <dbg> nested_int not decoded correctly.
[00:00:55.884,796] <dbg> test3.nested_obj_array[1].nested_int=537041920
What am I doing wrong?
Can you tell me how I can do this?
The final objective is to be able to parse a JSON with the following format:
{
"nested_obj": [
{
"nested_int": 123,
"nested_int2": 45,
"nested_nested_obj": {
"nested_nested_array": [
"array1",
"array2",
"array3",
"..."
]
}
},
{
"nested_int": 678,
"nested_int2": 90,
"nested_nested_obj": {
"nested_nested_array": [
"array1",
"array2",
"array3",
"..."
]
}
}
],
"some_string": "string"
}
Thanks!
Regards,
Ricardo