I am trying to figure out how ArduinoJson
capacity can be calculated, therefore I came by the Assistant web application developed by the developer of the library https://arduinojson.org/v6/assistant/
Here what I do not understand is, why when I use either of the following two JSON strings, the helper shows me the same capacity? I would expect that the longer JSON values will result in a bigger capacity, but this does not seem to be the case.
{
"wifi": {
"ssid": "S",
"password": "P",
"hostname": "H"
},
"administration": {
"username": "U",
"password": "P"
}
}
{
"wifi": {
"ssid": "SSSSSSSSSSSSSSSSSSSSSSSSSSS",
"password": "PPPPPPPPPPPPPPPPPPPPPPPPPP",
"hostname": "HHHHHHHHHHHHHHHHHHHHHHHHHHHH"
},
"administration": {
"username": "UUUUUUUUUUUUUUUUUUUUUUUUUUUUUU",
"password": "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPP"
}
}
I am trying to calculate the capacity using the assistant using the following configuration:
ESP8266 / Deserialize / char*
Could you anyone explain this to me? Apparently I understand the "reason" behind the capacity wrong?
-
That site reports to me different capacities for the two JSON documents. How exactly did you set the configuration?Edgar Bonet– Edgar Bonet2021年02月01日 13:08:00 +00:00Commented Feb 1, 2021 at 13:08
-
@EdgarBonet, well sorry I have just realized that the I should have mentioned how I was trying to calculate the capacity. ESP8266/Deserialize/char *Mohammed Noureldin– Mohammed Noureldin2021年02月01日 13:11:03 +00:00Commented Feb 1, 2021 at 13:11
2 Answers 2
If you look at the details of the numbers reported, you should see:
Data structures 112
Strings 0
Total (minimum) 112
Total (recommended) 128
As you see, there are exactly zero bytes allocated for the strings. This means that the library does not copy the strings, and instead references them from the character array you provide as an input.
If you instead configure the library for Stream
input, it will have to
store the strings, and the capacity is then very different for these two
documents.
-
You helped me understanding how the things are calculated here, thank you!. Nevertheless, I found the actual problem, please check my answer.Mohammed Noureldin– Mohammed Noureldin2021年02月02日 09:13:22 +00:00Commented Feb 2, 2021 at 9:13
I found what the real problem is. In the assistant tool, when choosing const char *
as the input type, it shows that the size of the string is 0, which is wrong according to the documentation of the library.
https://arduinojson.org/v6/api/json/deserializejson/
// writable input => zero-copy
DeserializationError deserializeJson(JsonDocument& doc, char* input);
// read-only input => duplication
DeserializationError deserializeJson(JsonDocument& doc, const char* input);
The assistant, if I see correctly, does not distinguish between these two cases, and thus gives the wrong capacity for this const
case.
Accordingly, in const char *
it is not enough to only take the size of the structure, but also we need to consider the data stored in it.
According to the documentation, the reason why const char *
cannot be a zero-copy is:
3.9.2 Duplication is required As we saw in the previous section, in the zero-copy mode, ArduinoJson stores pointers pointing inside the input buffer. We saw that it has to replace some characters of the input with null-terminators. With a read-only input, ArduinoJson cannot do that anymore, so it needs to make copies of "hip" and "hop". Where do you think the copies would go? In the JsonDocument, of course!
UPDATE
After reporting this bug (see the link below), it has been quickly fixed!
-
1Good catch! Did you consider sending a bug report?Edgar Bonet– Edgar Bonet2021年02月02日 16:11:21 +00:00Commented Feb 2, 2021 at 16:11
-
2@EdgarBonet Thanks! I already did it github.com/bblanchon/ArduinoJson/issues/1488Mohammed Noureldin– Mohammed Noureldin2021年02月02日 17:35:03 +00:00Commented Feb 2, 2021 at 17:35
-
Well, they fixed it now.Mohammed Noureldin– Mohammed Noureldin2021年02月02日 20:19:07 +00:00Commented Feb 2, 2021 at 20:19