as<char*>() and as<char>() (issue #1860)
If you try to call them, you'll now get the same error message as any unsupported type.
You could also add a custom converter for char* and char.JsonVariant::shallowCopy() (issue #1343)9.22337e+18 is outside the range of representable values of type 'long'JsonArray, JsonArrayConst, JsonObject, and JsonObjectConsttrue, false, and null (issue #1781)accept() functionsaddElement() to add()getElement(), getOrAddElement(), getMember(), and getOrAddMember()JsonDocument::data() and JsonDocument::memoryPool()JsonArrayIterator::internal() and JsonObjectIterator::internal()ARDUINOJSON_NAMESPACE to match the public nameschar (was deprecated since 6.18.0)BREAKING CHANGES
This release hides
JsonVariant's functions that were only intended for internal use. If you were using them in your programs, you must replace withoperator[]andto<JsonVariant>(), like so:// before JsonVariant a = variant.getElement(idx); JsonVariant b = variant.getOrAddElement(idx); JsonVariant c = variant.getMember(key); JsonVariant d = variant.getOrAddMember(key); // after JsonVariant a = variant[idx]; JsonVariant b = idx < variant.size() ? variant[idx] : variant[idx].to<JsonVariant>(); JsonVariant c = variant[key]; JsonVariant d = variant.containsKey(key) ? variant[key] : variant[key].to<JsonVariant>();
ElementProxy::memoryUsage()MemberProxy::memoryUsage() (issue #1730)JsonDocument to JsonVariantconst JsonDocument&call of overloaded 'String(const char*, int)' is ambiguousJsonString operator == and != for non-zero-terminated string-Wsign-conversion on GCC 8 (issue #1715)cannot convert 'pgm_p' to 'const void*' (issue #1707)JsonDocumentARDUINOJSON_EMBEDDED_MODE and assume we run on an embedded platform.ARDUINOJSON_DEFAULT_NESTING_LIMIT) must be set individually.ARDUINOJSON_USE_DOUBLE to 1ARDUINOJSON_USE_LONG_LONG to 1 on 32-bit platformsas<JsonString>() and is<JsonString>()JsonStringcopyArray()char[][] in copyArray()DeserializationError == bool and DeserializationError != boolisUndefined() to isUnbound()JsonVariant::memoryUsage() for raw stringscall of overloaded 'swap(BasicJsonDocument&, BasicJsonDocument&)' is ambiguous (issue #1678)BasicJsonDocument's copy and move constructorsBasicJsonDocument's copy and move assignmentsStaticJsonDocument::operator=BasicJsonDocument's copy assignment if capacity is the sameArduino.h when all its features are disabled (issue #1692, PR #1693 by @paulocsanz)PROGMEM is available as soon as ARDUINO is defined (consequence of #1693)ARDUINOJSON_EMBEDDED_MODE to 1 on Nios II (issue #1657)'dummy' may be used uninitialized on GCC 11expected unqualified-id before 'const' on GCC 11 (issue #1622)\u0000 (issue #1646)convertToJson() and Converter<T>::toJson() to voidas<std::string_view>() and is<std::string_view>()volatile float and volatile double (issue #1557)[Pe070]: incomplete type is not allowed on IAR (issue #1560)serializeJson(doc, String) when allocation fails (issue #1572)InvalidConversion<T1,T2> to easily identify invalid conversions (issue #1585)std::string_view (issue #1578, PR #1554 by @0xFEEDC0DE64)definition of implicit copy constructor for 'MsgPackDeserializer' is deprecated because it has a user-declared copy assignment operatorJsonArray::clear() (issue #1597)JsonVariant::as<unsigned>() (issue #1601)Printable (issue #1444)char values, see below (issue #1498)deserializeJson() leaves \uXXXX unchanged instead of returning NotSupporteddeserializeMsgPack() inserts null instead of returning NotSupportedDeserializationError::NotSupportedJsonVariant::is<JsonArrayConst/JsonObjectConst>() (issue #1412)JsonVariant::is<JsonVariant/JsonVariantConst>() (issue #1412)JsonVariantConst::is<JsonArray/JsonObject>() to return false (issue #1412)JsonVariant::as<T>() to always return T (see below).mbedignore (PR #1515 by @AGlass0fMilk)getMember() when array is emptyserializeMsgPack(doc, buffer, size) doesn't add null-terminator anymore (issue #1545)serializeJson(doc, buffer, size) adds null-terminator only if there is enough roombuild.libArchive to false (PR #1550 by @askreet)BREAKING CHANGES
Support for
charremovedWe cannot cast a
JsonVariantto acharanymore, so the following will break:char age = doc["age"]; // error: no matching function for call to 'variantAs(VariantData*&)'Instead, you must use another integral type, such as
int8_t:int8_t age = doc["age"]; // OKSimilarly, we cannot assign from a
charanymore, so the following will break:char age; doc["age"] = age; // error: no matching function for call to 'VariantRef::set(const char&)'Instead, you must use another integral type, such as
int8_t:int8_t age; doc["age"] = age; // OKA deprecation warning with the message "Support for
charis deprecated, useint8_toruint8_tinstead" was added to allow a smooth transition.
as<T>()always returnsTPreviously,
JsonVariant::as<T>()could return a type different fromT. The most common example isas<char*>()that returned aconst char*. While this feature simplified a few use cases, it was confusing and complicated the implementation of custom converters.Starting from this version,
as<T>doesn't try to auto-correct the return type and always returnT, which means that you cannot write this anymore:Serial.println(doc["sensor"].as<char*>()); // error: invalid conversion from 'const char*' to 'char*' [-fpermissive]Instead, you must write:
Serial.println(doc["sensor"].as<const char*>()); // OKA deprecation warning with the message "Replace
as<char*>()withas<const char*>()" was added to allow a smooth transition.
DeserializationError::NotSupportedremovedOn a different topic,
DeserializationError::NotSupportedhas been removed. Instead of returning this error:
deserializeJson()leaves\uXXXXunchanged (only whenARDUINOJSON_DECODE_UNICODEis0)deserializeMsgPack()replaces unsupported values withnullsConst-aware
is<T>()Lastly, a very minor change concerns
JsonVariantConst::is<T>(). It used to returntrueforJsonArrayandJsonOject, but now it returnsfalse. Instead, you must useJsonArrayConstandJsonObjectConst.
JsonDocument's destructor protected (issue #1480)client.stop() in JsonHttpClient.ino (issue #1485)expected ')' before 'char' when isdigit() is a macro (issue #1487)definition of implicit copy constructor is deprecated on Clang 10* (PR #1490 by @maxgerhardt)operator|(JsonVariant, char*) (issue #1432)ARDUINOJSON_ENABLE_PROGMEM (issue #1433).
It now checks that the pgm_read_XXX macros are defined before enabling PROGMEM.ambiguous overload for 'operator|' (issue #1411)operator|(MemberProxy, JsonObject) (issue #1415)JsonDocument::overflowed() which tells if the memory pool was too small (issue #1358)DeserializationError::EmptyInput which tells if the input was emptyDeserializationError::f_str() which returns a const __FlashStringHelper* (issue #846)operator|(JsonVariantConst, JsonVariantConst)JsonVariant::set((char*)0) which returned false instead of true (issue #1368)No such file or directory #include <WString.h> (issue #1381)deserializeJson() that stopped reading after {} (issue #1335)>, >=, ==, !=, <, and <=) between JsonVariantsJsonString::operator!=*) for filters (issue #1309)ARDUINOJSON_DECODE_UNICODE to 1 by defaultcopyArray() not working with String, ElementProxy, and MemberProxygetOrAddElement is not a member of ElementProxy (issue #1311)-Og (issues #1210 and #1314)Warning[Pa093]: implicit conversion from floating point to integer on IAR compiler (PR #1328 by @stawiski)/Zc:__cplusplus (issue #1250)JsonDocument to copyArray() (issue #1255)enums in as<T>() and is<T>() (issue #1256)JsonVariant as an input type for deserializeXxx()deserializeJson(doc2, doc1["payload"])DeserializationOption::Filter (issue #959)JsonFilterExample.inoMemberProxy::set(char[]) not duplicating the string (issue #1191)BasicJsonDocumentBasicJsonDocument::garbageCollect() (issue #1195)StaticJsonDocument::garbageCollect()BasicJsonDocument to preserve the capacity of the source.JsonDocument (issue #1189)BREAKING CHANGES
Copy-constructor of
BasicJsonDocumentIn previous versions, the copy constructor of
BasicJsonDocumentlooked at the source'smemoryUsage()to choose its capacity. Now, the copy constructor ofBasicJsonDocumentuses the same capacity as the source.Example:
DynamicJsonDocument doc1(64); doc1.set(String("example")); DynamicJsonDocument doc2 = doc1; Serial.print(doc2.capacity()); // 8 with ArduinoJson 6.14 // 64 with ArduinoJson 6.15I made this change to get consistent results between copy-constructor and move-constructor, and whether RVO applies or not.
If you use the copy-constructor to optimize your documents, you can use
garbageCollect()orshrinkToFit()instead.Copy-constructor of
JsonDocumentIn previous versions, it was possible to create a function that take a
JsonDocumentby value.void myFunction(JsonDocument doc) {}This function gives the wrong clues because it doesn't receive a copy of the
JsonDocument, only a sliced version. It worked because the copy constructor copied the internal pointers, but it was an accident.From now, if you need to pass a
JsonDocumentto a function, you must use a reference:void myFunction(JsonDocument& doc) {}
containsKey() on JsonVariantConstgetElement() and getMember() to JsonVariantConstBasicJsonDocument::shrinkToFit()uint8_t for serializeJson(), serializeJsonPretty(), and serializeMsgPack() (issue #1142)ARDUINOJSON_ENABLE_COMMENTS to enable support for comments (defaults to 0)std::string and std::stream on modern compilers (issue #1156)
(No need to define ARDUINOJSON_ENABLE_STD_STRING and ARDUINOJSON_ENABLE_STD_STREAM anymore)measureJson, measureJsonPretty, and measureMsgPack to keywords.txt
(This file is used for syntax highlighting in the Arduino IDE)variant.is<nullptr_t>()serializeJson(), serializeJsonPretty(), and serializeMsgPack() when writing to a StringserializeJson(), serializeJsonPretty(), and serializeMsgPack() when writing to a StringBREAKING CHANGES
Comments
Support for comments in input is now optional and disabled by default.
If you need support for comments, you must defined
ARDUINOJSON_ENABLE_COMMENTSto1; otherwise, you'll receiveInvalidInputerrors.#define ARDUINOJSON_ENABLE_COMMENTS 1 #include <ArduinoJson.h>
JsonArray and JsonObject to bool, to be consistent with JsonVariantdeserializeJson() when input contains duplicate keys (issue #1095)deserializeMsgPack() speed by reading several bytes at once0xFF (PR #1118 by @mikee47)MemberProxy and ElementProxy (issue #1120)JsonVariant::as<bool>() to return true for any non-null value (issue #1005)extras/ (issue #1011)strlen_P(), strncmp_P(), strcmp_P(), and memcpy_P() (issue #1073)measureJson() to the ArduinoJson namespace (PR #1069 by @nomis)basic_string<char, traits, allocator> (issue #1045)JsonConfigFile.ino for ESP8266Arduino.h if ARDUINO is defined (PR #1071 by @nomis)== and != for JsonDocument, ElementProxy, and MemberProxyJsonVariant when one contains a linked string and the other contains an owned string (issue #1051)JsonDocument to JsonVariant (issue #1023)serialized() not working with Flash strings (issue #1030)deserializeJson() silently accepting a Stream* (issue #978)operator| (issue #981)deserializeJson() more picky about trailing characters (issue #980)ARDUINOJSON_ENABLE_NAN (default=0) to enable NaN in JSON (issue #973)ARDUINOJSON_ENABLE_INFINITY (default=0) to enable Infinity in JSONJsonVariantnullptr (issue #998)BREAKING CHANGES
NaN and Infinity
The JSON specification allows neither NaN not Infinity, but previous versions of ArduinoJson supported it. Now, ArduinoJson behaves like most other libraries: a NaN or and Infinity in the
JsonDocument, becomes anullin the output JSON. Also,deserializeJson()returnsInvalidInputif the JSON document contains NaN or Infinity.This version still supports NaN and Infinity in JSON documents, but it's disabled by default to be compatible with other JSON parsers. If you need the old behavior back, define
ARDUINOJSON_ENABLE_NANandARDUINOJSON_ENABLE_INFINITYto1;:#define ARDUINOJSON_ENABLE_NAN 1 #define ARDUINOJSON_ENABLE_INFINITY 1 #include <ArduinoJson.h>The "or" operator
This version slightly changes the behavior of the | operator when the variant contains a float and the user requests an integer.
Older versions returned the floating point value truncated. Now, it returns the default value.
// suppose variant contains 1.2 int value = variant | 3; // old behavior: value == 1 // new behavior value == 3If you need the old behavior, you must add
if (variant.is<float>()).
deserializeJson() not being picky enough (issue #969)JsonVariant::as<T>() and JsonVariant::is<T>().
as<T>() returns 0 if the integer T overflowsis<T>() returns false if the integer T overflowsBasicJsonDocument to support custom allocator (issue #876)JsonDocument::containsKey() (issue #938)JsonVariant::containsKey()StaticJsonBuffer and DynamicJsonBufferJsonArray::copyFrom()/copyTo() to free functions copyArray()JsonArray::copyFrom() and JsonObject::copyFrom() to set()JsonArray::get() to getElement()JsonArray::add() (without arg) to addElement()JsonObject::get() to getMember()JsonObject::getOrCreate() to getOrAddMember()JsonVariant::isNull() not returning true after set((char*)0)variant.set(serialized((char*)0))IncompleteInput in false, true, and nullJsonDocument::size()JsonDocument::remove()JsonVariant::clear()JsonVariant::remove()DynamicJsonDocumentJsonArray::copyFrom() accepts JsonArrayConstJsonVariant::set() accepts JsonArrayConst and JsonObjectConstJsonDocument was missing in the ArduinoJson namespacememoryUsage() to JsonArray, JsonObject, and JsonVariantnesting() to JsonArray, JsonDocument, JsonObject, and JsonVariantJsonDocument::nestingLimit with an additional parameter
to deserializeJson() and deserializeMsgPack()JsonDocumentStaticJsonDocument copy constructor and copy assignmentDynamicJsonDocument chooses the capacity according to the memory usage of the source, not from the capacity of the source.StaticJsonDocument/DynamicJsonDocument from a JsonArray/JsonObject/JsonVariantJsonDocument::isNull()JsonDocument::operator[]ARDUINOJSON_TAB to configure the indentation characteradd(), createNestedArray() and createNestedObject() to JsonVariantJsonVariant automatically promotes to JsonObject or JsonArray on write.
Calling JsonVariant::to<T>() is not required anymore.JsonDocument now support the same operations as JsonVariant.
Calling JsonDocument::as<T>() is not required anymore.JsonHttpClient.inoJsonString as a key or a valueBREAKING CHANGES
DynamicJsonDocument's constructorThe parameter to the constructor of
DynamicJsonDocumentis now mandatoryOld code:
DynamicJsonDocument doc;New code:
DynamicJsonDocument doc(1024);Nesting limit
JsonDocument::nestingLimitwas replaced with a new parameter todeserializeJson()anddeserializeMsgPack().Old code:
doc.nestingLimit = 15; deserializeJson(doc, input);New code:
deserializeJson(doc, input, DeserializationOption::NestingLimit(15));
DynamicJsonDocument, it now has a fixed capacity.JsonKey to JsonStringJsonArray::is<T>(i) and JsonArray::set(i,v)JsonObject::is<T>(k) and JsonObject::set(k,v)T JsonArray::get<T>(i) with JsonVariant JsonArray::get(i)T JsonObject::get<T>(k) with JsonVariant JsonObject::get(k)JSON_STRING_SIZE()DeserializationError::code() to be used in switch statements (issue #846)JsonArray and JsonObject to JsonVariantJsonPair::key() now returns a JsonKeyDynamicJsonDocumentJsonVariant::is<String>() (closes #763)JsonArrayConst, JsonObjectConst, and JsonVariantConstJsonDocument (issue #827)JsonArray and JsonObject, instead of storing pointers (issue #780)JsonVariant::to<JsonArray>() and JsonVariant::to<JsonObject>()JsonVariantJsonPair's key and value with key() and value()serializeJson(obj[key], dst) (issue #794)BREAKING CHANGES
JsonVariant
JsonVariantnow has a semantic similar toJsonObjectandJsonArray. It's a reference to a value stored in theJsonDocument. As a consequence, aJsonVariantcannot be used as a standalone variable anymore.Old code:
JsonVariant myValue = 42;New code:
DynamicJsonDocument doc; JsonVariant myValue = doc.to<JsonVariant>(); myValue.set(42);JsonPair
Old code:
for(JsonPair p : myObject) { Serial.println(p.key); Serial.println(p.value.as<int>()); }New code:
for(JsonPair p : myObject) { Serial.println(p.key()); Serial.println(p.value().as<int>()); }CAUTION: the key is now read only!
invalid application of 'sizeof' to incomplete type '__FlashStringHelper' (issue #783)char[] not duplicated when passed to JsonVariant::operator[]JsonObject not inserting keys of type String (issue #782)JsonVariant::is<int>() that returned true for empty strings-fsingle-precision-constant is usedRawJson() to serialized()serializeMsgPack() now supports values marked with serialized()BREAKING CHANGES
Non quoted strings
Non quoted strings are now forbidden in values, but they are still allowed in keys. For example,
{key:"value"}is accepted, but{key:value}is not.Preformatted values
Old code:
object["values"] = RawJson("[1,2,3,4]");New code:
object["values"] = serialized("[1,2,3,4]");
JsonArray and JsonObject by value instead of reference (issue #309)success() with isNull()BREAKING CHANGES
Old code:
JsonObject& obj = doc.to<JsonObject>(); JsonArray& arr = obj.createNestedArray("key"); if (!arr.success()) { Serial.println("Not enough memory"); return; }New code:
JsonObject obj = doc.to<JsonObject>(); JsonArray arr = obj.createNestedArray("key"); if (arr.isNull()) { Serial.println("Not enough memory"); return; }
isnan() and isinf() macros (issue #752)DynamicJsonDocument and StaticJsonDocumentdeserializeJson()serializeJson() and serializeJsonPretty()measureJson() and measureJsonPretty()serializeMsgPack(), deserializeMsgPack() and measureMsgPack() (issue #358)MsgPackParser.ino (issue #358)JsonBuffer::parseArray(), parseObject() and parse()JsonBuffer::createArray() and createObject()printTo() and prettyPrintTo()measureLength() and measurePrettyLength()BREAKING CHANGES
Deserialization
Old code:
DynamicJsonBuffer jb; JsonObject& obj = jb.parseObject(json); if (obj.success()) { }New code:
DynamicJsonDocument doc; DeserializationError error = deserializeJson(doc, json); if (error) { } JsonObject& obj = doc.as<JsonObject>();Serialization
Old code:
DynamicJsonBuffer jb; JsonObject& obj = jb.createObject(); obj["key"] = "value"; obj.printTo(Serial);New code:
DynamicJsonDocument obj; JsonObject& obj = doc.to<JsonObject>(); obj["key"] = "value"; serializeJson(doc, Serial);