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