Why is the input modified?
The JSON parser works in two different modes, depending on whether the input is read-only or not.
Mode 1: read-only input
ArduinoJson uses the “read-only” mode when you pass one of the following types to deserializeJson()
:
const char*
std::string
std::istream
String
Stream
const __FlashStringHelper*
In this mode, the parser copies relevant pieces of the input in the JsonDocument
.
Examples:
const char* json = "{\"hello\":\"world\"}";
deserializeJson(doc, json);
String json = "{\"hello\":\"world\"}";
deserializeJson(doc, json);
Mode 2: zero-copy
ArduinoJson uses the “zero-copy” mode when you pass one of the following types to deserializeJson()
:
char*
char[]
In this mode, the JSON parser modifies the input in place. The following modifications are performed:
'\0'
are inserted at the end of each string- Escaped special characters (like
\n
) are unescaped
Example:
char[] json = "{\"hello\":\"world\"}";
deserializeJson(doc, json);
After executing the line above, the input
variable probably contains something like "hello\0world\0"
.
Calling deserializeJson()
twice
Because the input buffer is altered, if you call deserializeJson()
twice, the second call will return InvalidInput, as in the example below:
char[] json = "{\"hello\":\"world\"}";
deserializeJson(doc, json); // Ok
deserializeJson(doc, json); // InvalidInput
Switching to classic mode
Usually, the “zero-copy” mode is what you want because it reduces memory usage. However, if you need to switch back to the “classic” mode, you can cast the input pointer to const char*
, like so:
char[] json = "{\"hello\":\"world\"}";
deserializeJson(doc, (const char*)json); // cast to avoid "zero-copy" mode
See also
- Deserialization Tutorial
- Chapter “Inside ArduinoJson” of Mastering ArduinoJson