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():

  1. const char *
  2. std::string
  3. std::istream
  4. String
  5. Stream
  6. 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():

  1. char*
  2. char[]

In this mode, the JSON parser modifies the input in-place. The following modifications are performed:

  1. '\0' are inserted at the end of each string
  2. 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

The “zero-copy” mode is usually what you want, because it reduces the memory usage. However, if you need to switch back to the “classic” mode, you can cast the input pointer to const char* as in the example below:

char[] json = "{\"hello\":\"world\"}";
deserializeJson(doc, (const char*)json);  // classic mode