3

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?

2
  • That site reports to me different capacities for the two JSON documents. How exactly did you set the configuration? – Edgar Bonet Feb 1 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 Feb 1 at 13:11
5

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.

1
  • You helped me understanding how the things are calculated here, thank you!. Nevertheless, I found the actual problem, please check my answer. – Mohammed Noureldin Feb 2 at 9:13
2

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!

https://github.com/bblanchon/ArduinoJson/issues/1488

3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.