Remove StaticJsonDocument

This commit is contained in:
Benoit Blanchon
2023-03-15 14:54:55 +01:00
parent 5edd435fe9
commit 17a482a9b1
66 changed files with 477 additions and 1728 deletions

View File

@ -481,7 +481,7 @@ jobs:
g++ -x c++ - <<END g++ -x c++ - <<END
#include "${{ steps.amalgamate.outputs.filename }}" #include "${{ steps.amalgamate.outputs.filename }}"
int main() { int main() {
StaticJsonDocument<300> doc; DynamicJsonDocument doc(300);
deserializeJson(doc, "{}"); deserializeJson(doc, "{}");
} }
END END
@ -515,7 +515,7 @@ jobs:
g++ -x c++ - <<END g++ -x c++ - <<END
#include "${{ steps.amalgamate.outputs.filename }}" #include "${{ steps.amalgamate.outputs.filename }}"
int main() { int main() {
ArduinoJson::StaticJsonDocument<300> doc; ArduinoJson::DynamicJsonDocument doc(300);
deserializeJson(doc, "{}"); deserializeJson(doc, "{}");
} }
END END

View File

@ -1,832 +1,7 @@
ArduinoJson: change log ArduinoJson: change log
======================= =======================
v6.21.0 (2023-03-14) HEAD
------- ----
* Drop support for C++98/C++03. Minimum required is C++11. * Remove `StaticJsonDocument`
* Remove `ARDUINOJSON_NAMESPACE`; use `ArduinoJson` instead.
* Make string support generic (issue #1807)
v6.20.1 (2023-02-08)
-------
* Remove explicit exclusion of `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`.
v6.20.0 (2022-12-26)
-------
* Add `JsonVariant::shallowCopy()` (issue #1343)
* Fix `9.22337e+18 is outside the range of representable values of type 'long'`
* Fix comparison operators for `JsonArray`, `JsonArrayConst`, `JsonObject`, and `JsonObjectConst`
* Fix lax parsing of `true`, `false`, and `null` (issue #1781)
* Remove undocumented `accept()` functions
* Rename `addElement()` to `add()`
* Remove `getElement()`, `getOrAddElement()`, `getMember()`, and `getOrAddMember()`
* Remove undocumented `JsonDocument::data()` and `JsonDocument::memoryPool()`
* Remove undocumented `JsonArrayIterator::internal()` and `JsonObjectIterator::internal()`
* Rename things in `ARDUINOJSON_NAMESPACE` to match the public names
* Add documentation to most public symbols
* Remove support for naked `char` (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 with `operator[]` and `to<JsonVariant>()`, like so:
>
> ```c++
> // 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>();
> ```
v6.19.4 (2022-04-05)
-------
* Add `ElementProxy::memoryUsage()`
* Add `MemberProxy::memoryUsage()` (issue #1730)
* Add implicit conversion from `JsonDocument` to `JsonVariant`
* Fix comparisons operators with `const JsonDocument&`
v6.19.3 (2022-03-08)
-------
* Fix `call of overloaded 'String(const char*, int)' is ambiguous`
* Fix `JsonString` operator `==` and `!=` for non-zero-terminated string
* Fix `-Wsign-conversion` on GCC 8 (issue #1715)
* MessagePack: serialize round floats as integers (issue #1718)
v6.19.2 (2022-02-14)
-------
* Fix `cannot convert 'pgm_p' to 'const void*'` (issue #1707)
v6.19.1 (2022-01-14)
-------
* Fix crash when adding an object member in a too small `JsonDocument`
* Fix filter not working in zero-copy mode (issue #1697)
v6.19.0 (2022-01-08)
-------
* Remove `ARDUINOJSON_EMBEDDED_MODE` and assume we run on an embedded platform.
Dependent settings (like `ARDUINOJSON_DEFAULT_NESTING_LIMIT`) must be set individually.
* Change the default of `ARDUINOJSON_USE_DOUBLE` to `1`
* Change the default of `ARDUINOJSON_USE_LONG_LONG` to `1` on 32-bit platforms
* Add `as<JsonString>()` and `is<JsonString>()`
* Add safe bool idiom in `JsonString`
* Add support for NUL in string values (issue #1646)
* Add support for arbitrary array rank in `copyArray()`
* Add support for `char[][]` in `copyArray()`
* Remove `DeserializationError == bool` and `DeserializationError != bool`
* Renamed undocumented function `isUndefined()` to `isUnbound()`
* Fix `JsonVariant::memoryUsage()` for raw strings
* Fix `call of overloaded 'swap(BasicJsonDocument&, BasicJsonDocument&)' is ambiguous` (issue #1678)
* Fix inconsistent pool capacity between `BasicJsonDocument`'s copy and move constructors
* Fix inconsistent pool capacity between `BasicJsonDocument`'s copy and move assignments
* Fix return type of `StaticJsonDocument::operator=`
* Avoid pool reallocation in `BasicJsonDocument`'s copy assignment if capacity is the same
* Avoid including `Arduino.h` when all its features are disabled (issue #1692, PR #1693 by @paulocsanz)
* Assume `PROGMEM` is available as soon as `ARDUINO` is defined (consequence of #1693)
v6.18.5 (2021-09-28)
-------
* Set `ARDUINOJSON_EMBEDDED_MODE` to `1` on Nios II (issue #1657)
v6.18.4 (2021-09-06)
-------
* Fixed error `'dummy' may be used uninitialized` on GCC 11
* Fixed error `expected unqualified-id before 'const'` on GCC 11 (issue #1622)
* Filter: exact match takes precedence over wildcard (issue #1628)
* Fixed deserialization of `\u0000` (issue #1646)
v6.18.3 (2021-07-27)
-------
* Changed return type of `convertToJson()` and `Converter<T>::toJson()` to `void`
* Added `as<std::string_view>()` and `is<std::string_view>()`
v6.18.2 (2021-07-19)
-------
* Removed a symlink because the Arduino Library Specification forbids it
v6.18.1 (2021-07-03)
-------
* Fixed support for `volatile float` and `volatile double` (issue #1557)
* Fixed error `[Pe070]: incomplete type is not allowed` on IAR (issue #1560)
* Fixed `serializeJson(doc, String)` when allocation fails (issue #1572)
* Fixed clang-tidy warnings (issue #1574, PR #1577 by @armandas)
* Added fake class `InvalidConversion<T1,T2>` to easily identify invalid conversions (issue #1585)
* Added support for `std::string_view` (issue #1578, PR #1554 by @0xFEEDC0DE64)
* Fixed warning `definition of implicit copy constructor for 'MsgPackDeserializer' is deprecated because it has a user-declared copy assignment operator`
* Added `JsonArray::clear()` (issue #1597)
* Fixed `JsonVariant::as<unsigned>()` (issue #1601)
* Added support for ESP-IDF component build (PR #1562 by @qt1, PR #1599 by @andreaskuster)
v6.18.0 (2021-05-05)
-------
* Added support for custom converters (issue #687)
* Added support for `Printable` (issue #1444)
* Removed support for `char` values, see below (issue #1498)
* `deserializeJson()` leaves `\uXXXX` unchanged instead of returning `NotSupported`
* `deserializeMsgPack()` inserts `null` instead of returning `NotSupported`
* Removed `DeserializationError::NotSupported`
* Added `JsonVariant::is<JsonArrayConst/JsonObjectConst>()` (issue #1412)
* Added `JsonVariant::is<JsonVariant/JsonVariantConst>()` (issue #1412)
* Changed `JsonVariantConst::is<JsonArray/JsonObject>()` to return `false` (issue #1412)
* Simplified `JsonVariant::as<T>()` to always return `T` (see below)
* Updated folders list in `.mbedignore` (PR #1515 by @AGlass0fMilk)
* Fixed member-call-on-null-pointer in `getMember()` when array is empty
* `serializeMsgPack(doc, buffer, size)` doesn't add null-terminator anymore (issue #1545)
* `serializeJson(doc, buffer, size)` adds null-terminator only if there is enough room
* PlatformIO: set `build.libArchive` to `false` (PR #1550 by @askreet)
> ### BREAKING CHANGES
>
> #### Support for `char` removed
>
> We cannot cast a `JsonVariant` to a `char` anymore, so the following will break:
> ```c++
> char age = doc["age"]; // error: no matching function for call to 'variantAs(VariantData*&)'
> ```
> Instead, you must use another integral type, such as `int8_t`:
> ```c++
> int8_t age = doc["age"]; // OK
> ```
>
> Similarly, we cannot assign from a `char` anymore, so the following will break:
> ```c++
> 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`:
> ```c++
> int8_t age;
> doc["age"] = age; // OK
> ```
> A deprecation warning with the message "Support for `char` is deprecated, use `int8_t` or `uint8_t` instead" was added to allow a smooth transition.
>
> #### `as<T>()` always returns `T`
>
> Previously, `JsonVariant::as<T>()` could return a type different from `T`.
> The most common example is `as<char*>()` that returned a `const 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 return `T`,
> which means that you cannot write this anymore:
>
> ```c++
> Serial.println(doc["sensor"].as<char*>()); // error: invalid conversion from 'const char*' to 'char*' [-fpermissive]
> ```
>
> Instead, you must write:
>
> ```c++
> Serial.println(doc["sensor"].as<const char*>()); // OK
> ```
>
> A deprecation warning with the message "Replace `as<char*>()` with `as<const char*>()`" was added to allow a smooth transition.
>
> #### `DeserializationError::NotSupported` removed
>
> On a different topic, `DeserializationError::NotSupported` has been removed.
> Instead of returning this error:
>
> * `deserializeJson()` leaves `\uXXXX` unchanged (only when `ARDUINOJSON_DECODE_UNICODE` is `0`)
> * `deserializeMsgPack()` replaces unsupported values with `null`s
>
> #### Const-aware `is<T>()`
>
> Lastly, a very minor change concerns `JsonVariantConst::is<T>()`.
> It used to return `true` for `JsonArray` and `JsonOject`, but now it returns `false`.
> Instead, you must use `JsonArrayConst` and `JsonObjectConst`.
v6.17.3 (2021-02-15)
-------
* Made `JsonDocument`'s destructor protected (issue #1480)
* Added missing calls to `client.stop()` in `JsonHttpClient.ino` (issue #1485)
* Fixed error `expected ')' before 'char'` when `isdigit()` is a macro (issue #1487)
* Fixed error `definition of implicit copy constructor is deprecated` on Clang 10
* PlatformIO: set framework compatibility to `*` (PR #1490 by @maxgerhardt)
v6.17.2 (2020-11-14)
-------
* Fixed invalid conversion error in `operator|(JsonVariant, char*)` (issue #1432)
* Changed the default value of `ARDUINOJSON_ENABLE_PROGMEM` (issue #1433).
It now checks that the `pgm_read_XXX` macros are defined before enabling `PROGMEM`.
v6.17.1 (2020-11-07)
-------
* Fixed error `ambiguous overload for 'operator|'` (issue #1411)
* Fixed `operator|(MemberProxy, JsonObject)` (issue #1415)
* Allowed more than 32767 values in non-embedded mode (issue #1414)
v6.17.0 (2020-10-19)
-------
* Added a build failure when nullptr is defined as a macro (issue #1355)
* Added `JsonDocument::overflowed()` which tells if the memory pool was too small (issue #1358)
* Added `DeserializationError::EmptyInput` which tells if the input was empty
* Added `DeserializationError::f_str()` which returns a `const __FlashStringHelper*` (issue #846)
* Added `operator|(JsonVariantConst, JsonVariantConst)`
* Added filtering for MessagePack (issue #1298, PR #1394 by Luca Passarella)
* Moved float convertion tables to PROGMEM
* Fixed `JsonVariant::set((char*)0)` which returned false instead of true (issue #1368)
* Fixed error `No such file or directory #include <WString.h>` (issue #1381)
v6.16.1 (2020-08-04)
-------
* Fixed `deserializeJson()` that stopped reading after `{}` (issue #1335)
v6.16.0 (2020-08-01)
-------
* Added comparisons (`>`, `>=`, `==`, `!=`, `<`, and `<=`) between `JsonVariant`s
* Added string deduplication (issue #1303)
* Added `JsonString::operator!=`
* Added wildcard key (`*`) for filters (issue #1309)
* Set `ARDUINOJSON_DECODE_UNICODE` to `1` by default
* Fixed `copyArray()` not working with `String`, `ElementProxy`, and `MemberProxy`
* Fixed error `getOrAddElement is not a member of ElementProxy` (issue #1311)
* Fixed excessive stack usage when compiled with `-Og` (issues #1210 and #1314)
* Fixed `Warning[Pa093]: implicit conversion from floating point to integer` on IAR compiler (PR #1328 by @stawiski)
v6.15.2 (2020-05-15)
-------
* CMake: don't build tests when imported in another project
* CMake: made project arch-independent
* Visual Studio: fixed error C2766 with flag `/Zc:__cplusplus` (issue #1250)
* Added support for `JsonDocument` to `copyArray()` (issue #1255)
* Added support for `enum`s in `as<T>()` and `is<T>()` (issue #1256)
* Added `JsonVariant` as an input type for `deserializeXxx()`
For example, you can do: `deserializeJson(doc2, doc1["payload"])`
* Break the build if using 64-bit integers with ARDUINOJSON_USE_LONG_LONG==0
v6.15.1 (2020-04-08)
-------
* Fixed "maybe-uninitialized" warning (issue #1217)
* Fixed "statement is unreachable" warning on IAR (issue #1233)
* Fixed "pointless integer comparison" warning on IAR (issue #1233)
* Added CMake "install" target (issue #1209)
* Disabled alignment on AVR (issue #1231)
v6.15.0 (2020-03-22)
-------
* Added `DeserializationOption::Filter` (issue #959)
* Added example `JsonFilterExample.ino`
* Changed the array subscript operator to automatically add missing elements
* Fixed "deprecated-copy" warning on GCC 9 (fixes #1184)
* Fixed `MemberProxy::set(char[])` not duplicating the string (issue #1191)
* Fixed enums serialized as booleans (issue #1197)
* Fixed incorrect string comparison on some platforms (issue #1198)
* Added move-constructor and move-assignment to `BasicJsonDocument`
* Added `BasicJsonDocument::garbageCollect()` (issue #1195)
* Added `StaticJsonDocument::garbageCollect()`
* Changed copy-constructor of `BasicJsonDocument` to preserve the capacity of the source.
* Removed copy-constructor of `JsonDocument` (issue #1189)
> ### BREAKING CHANGES
>
> #### Copy-constructor of `BasicJsonDocument`
>
> In previous versions, the copy constructor of `BasicJsonDocument` looked at the source's `memoryUsage()` to choose its capacity.
> Now, the copy constructor of `BasicJsonDocument` uses the same capacity as the source.
>
> Example:
>
> ```c++
> DynamicJsonDocument doc1(64);
> doc1.set(String("example"));
>
> DynamicJsonDocument doc2 = doc1;
> Serial.print(doc2.capacity()); // 8 with ArduinoJson 6.14
> // 64 with ArduinoJson 6.15
> ```
>
> I 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()` or `shrinkToFit()` instead.
>
> #### Copy-constructor of `JsonDocument`
>
> In previous versions, it was possible to create a function that take a `JsonDocument` by value.
>
> ```c++
> 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 `JsonDocument` to a function, you must use a reference:
>
> ```c++
> void myFunction(JsonDocument& doc) {}
> ```
v6.14.1 (2020-01-27)
-------
* Fixed regression in UTF16 decoding (issue #1173)
* Fixed `containsKey()` on `JsonVariantConst`
* Added `getElement()` and `getMember()` to `JsonVariantConst`
v6.14.0 (2020-01-16)
-------
* Added `BasicJsonDocument::shrinkToFit()`
* Added support of `uint8_t` for `serializeJson()`, `serializeJsonPretty()`, and `serializeMsgPack()` (issue #1142)
* Added `ARDUINOJSON_ENABLE_COMMENTS` to enable support for comments (defaults to 0)
* Auto enable support for `std::string` and `std::stream` on modern compilers (issue #1156)
(No need to define `ARDUINOJSON_ENABLE_STD_STRING` and `ARDUINOJSON_ENABLE_STD_STREAM` anymore)
* Improved decoding of UTF-16 surrogate pairs (PR #1157 by @kaysievers)
(ArduinoJson now produces standard UTF-8 instead of CESU-8)
* Added `measureJson`, `measureJsonPretty`, and `measureMsgPack` to `keywords.txt`
(This file is used for syntax highlighting in the Arduino IDE)
* Fixed `variant.is<nullptr_t>()`
* Fixed value returned by `serializeJson()`, `serializeJsonPretty()`, and `serializeMsgPack()` when writing to a `String`
* Improved speed of `serializeJson()`, `serializeJsonPretty()`, and `serializeMsgPack()` when writing to a `String`
> ### BREAKING 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_COMMENTS` to `1`; otherwise, you'll receive `InvalidInput` errors.
>
> ```c++
> #define ARDUINOJSON_ENABLE_COMMENTS 1
> #include <ArduinoJson.h>
> ```
v6.13.0 (2019-11-01)
-------
* Added support for custom writer/reader classes (issue #1088)
* Added conversion from `JsonArray` and `JsonObject` to `bool`, to be consistent with `JsonVariant`
* Fixed `deserializeJson()` when input contains duplicate keys (issue #1095)
* Improved `deserializeMsgPack()` speed by reading several bytes at once
* Added detection of Atmel AVR8/GNU C Compiler (issue #1112)
* Fixed deserializer that stopped reading at the first `0xFF` (PR #1118 by @mikee47)
* Fixed dangling reference in copies of `MemberProxy` and `ElementProxy` (issue #1120)
v6.12.0 (2019-09-05)
-------
* Use absolute instead of relative includes (issue #1072)
* Changed `JsonVariant::as<bool>()` to return `true` for any non-null value (issue #1005)
* Moved ancillary files to `extras/` (issue #1011)
v6.11.5 (2019-08-23)
-------
* Added fallback implementations of `strlen_P()`, `strncmp_P()`, `strcmp_P()`, and `memcpy_P()` (issue #1073)
v6.11.4 (2019-08-12)
-------
* Added `measureJson()` to the `ArduinoJson` namespace (PR #1069 by @nomis)
* Added support for `basic_string<char, traits, allocator>` (issue #1045)
* Fixed example `JsonConfigFile.ino` for ESP8266
* Include `Arduino.h` if `ARDUINO` is defined (PR #1071 by @nomis)
v6.11.3 (2019-07-22)
-------
* Added operators `==` and `!=` for `JsonDocument`, `ElementProxy`, and `MemberProxy`
* Fixed comparison of `JsonVariant` when one contains a linked string and the other contains an owned string (issue #1051)
v6.11.2 (2019-07-08)
-------
* Fixed assignment of `JsonDocument` to `JsonVariant` (issue #1023)
* Fix invalid conversion error on Particle Argon (issue #1035)
v6.11.1 (2019-06-21)
-------
* Fixed `serialized()` not working with Flash strings (issue #1030)
v6.11.0 (2019-05-26)
-------
* Fixed `deserializeJson()` silently accepting a `Stream*` (issue #978)
* Fixed invalid result from `operator|` (issue #981)
* Made `deserializeJson()` more picky about trailing characters (issue #980)
* Added `ARDUINOJSON_ENABLE_NAN` (default=0) to enable NaN in JSON (issue #973)
* Added `ARDUINOJSON_ENABLE_INFINITY` (default=0) to enable Infinity in JSON
* Removed implicit conversion in comparison operators (issue #998)
* Added lexicographical comparison for `JsonVariant`
* Added support for `nullptr` (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
> a `null` in the output JSON. Also, `deserializeJson()` returns
> `InvalidInput` if 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_NAN` and
> `ARDUINOJSON_ENABLE_INFINITY` to `1`;:
>
> ```c++
> #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.
>
> ```c++
> // suppose variant contains 1.2
> int value = variant | 3;
>
> // old behavior:
> value == 1
>
> // new behavior
> value == 3
> ```
>
> If you need the old behavior, you must add `if (variant.is<float>())`.
v6.10.1 (2019-04-23)
-------
* Fixed error "attributes are not allowed on a function-definition"
* Fixed `deserializeJson()` not being picky enough (issue #969)
* Fixed error "no matching function for call to write(uint8_t)" (issue #972)
v6.10.0 (2019-03-22)
-------
* Fixed an integer overflow in the JSON deserializer
* Added overflow handling in `JsonVariant::as<T>()` and `JsonVariant::is<T>()`.
- `as<T>()` returns `0` if the integer `T` overflows
- `is<T>()` returns `false` if the integer `T` overflows
* Added `BasicJsonDocument` to support custom allocator (issue #876)
* Added `JsonDocument::containsKey()` (issue #938)
* Added `JsonVariant::containsKey()`
v6.9.1 (2019-03-01)
------
* Fixed warning "unused variable" with GCC 4.4 (issue #912)
* Fixed warning "cast increases required alignment" (issue #914)
* Fixed warning "conversion may alter value" (issue #914)
* Fixed naming conflict with "CAPACITY" (issue #839)
* Muted warning "will change in GCC 7.1" (issue #914)
* Added a clear error message for `StaticJsonBuffer` and `DynamicJsonBuffer`
* Marked ArduinoJson.h as a "system header"
v6.9.0 (2019-02-26)
------
* Decode escaped Unicode characters like \u00DE (issue #304, PR #791)
Many thanks to Daniel Schulte (aka @trilader) who implemented this feature.
* Added option ARDUINOJSON_DECODE_UNICODE to enable it
* Converted `JsonArray::copyFrom()/copyTo()` to free functions `copyArray()`
* Renamed `JsonArray::copyFrom()` and `JsonObject::copyFrom()` to `set()`
* Renamed `JsonArray::get()` to `getElement()`
* Renamed `JsonArray::add()` (without arg) to `addElement()`
* Renamed `JsonObject::get()` to `getMember()`
* Renamed `JsonObject::getOrCreate()` to `getOrAddMember()`
* Fixed `JsonVariant::isNull()` not returning `true` after `set((char*)0)`
* Fixed segfault after `variant.set(serialized((char*)0))`
* Detect `IncompleteInput` in `false`, `true`, and `null`
* Added `JsonDocument::size()`
* Added `JsonDocument::remove()`
* Added `JsonVariant::clear()`
* Added `JsonVariant::remove()`
v6.8.0-beta (2019-01-30)
-----------
* Import functions in the ArduinoJson namespace to get clearer errors
* Improved syntax highlighting in Arduino IDE
* Removed default capacity of `DynamicJsonDocument`
* `JsonArray::copyFrom()` accepts `JsonArrayConst`
* `JsonVariant::set()` accepts `JsonArrayConst` and `JsonObjectConst`
* `JsonDocument` was missing in the ArduinoJson namespace
* Added `memoryUsage()` to `JsonArray`, `JsonObject`, and `JsonVariant`
* Added `nesting()` to `JsonArray`, `JsonDocument`, `JsonObject`, and `JsonVariant`
* Replaced `JsonDocument::nestingLimit` with an additional parameter
to `deserializeJson()` and `deserializeMsgPack()`
* Fixed uninitialized variant in `JsonDocument`
* Fixed `StaticJsonDocument` copy constructor and copy assignment
* The copy constructor of `DynamicJsonDocument` chooses the capacity according to the memory usage of the source, not from the capacity of the source.
* Added the ability to create/assign a `StaticJsonDocument`/`DynamicJsonDocument` from a `JsonArray`/`JsonObject`/`JsonVariant`
* Added `JsonDocument::isNull()`
* Added `JsonDocument::operator[]`
* Added `ARDUINOJSON_TAB` to configure the indentation character
* Reduced the size of the pretty JSON serializer
* Added `add()`, `createNestedArray()` and `createNestedObject()` to `JsonVariant`
* `JsonVariant` 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.
* Fixed example `JsonHttpClient.ino`
* User can now use a `JsonString` as a key or a value
> ### BREAKING CHANGES
>
> #### `DynamicJsonDocument`'s constructor
>
> The parameter to the constructor of `DynamicJsonDocument` is now mandatory
>
> Old code:
>
> ```c++
> DynamicJsonDocument doc;
> ```
>
> New code:
>
> ```c++
> DynamicJsonDocument doc(1024);
> ```
>
> #### Nesting limit
>
> `JsonDocument::nestingLimit` was replaced with a new parameter to `deserializeJson()` and `deserializeMsgPack()`.
>
> Old code:
>
> ```c++
> doc.nestingLimit = 15;
> deserializeJson(doc, input);
> ```
>
> New code:
>
> ```c++
> deserializeJson(doc, input, DeserializationOption::NestingLimit(15));
> ```
v6.7.0-beta (2018-12-07)
-----------
* Removed the automatic expansion of `DynamicJsonDocument`, it now has a fixed capacity.
* Restored the monotonic allocator because the code was getting too big
* Reduced the memory usage
* Reduced the code size
* Renamed `JsonKey` to `JsonString`
* Removed spurious files in the Particle library
v6.6.0-beta (2018-11-13)
-----------
* Removed `JsonArray::is<T>(i)` and `JsonArray::set(i,v)`
* Removed `JsonObject::is<T>(k)` and `JsonObject::set(k,v)`
* Replaced `T JsonArray::get<T>(i)` with `JsonVariant JsonArray::get(i)`
* Replaced `T JsonObject::get<T>(k)` with `JsonVariant JsonObject::get(k)`
* Added `JSON_STRING_SIZE()`
* ~~Replacing or removing a value now releases the memory~~
* Added `DeserializationError::code()` to be used in switch statements (issue #846)
v6.5.0-beta (2018-10-13)
-----------
* Added implicit conversion from `JsonArray` and `JsonObject` to `JsonVariant`
* Allow mixed configuration in compilation units (issue #809)
* Fixed object keys not being duplicated
* `JsonPair::key()` now returns a `JsonKey`
* Increased the default capacity of `DynamicJsonDocument`
* Fixed `JsonVariant::is<String>()` (closes #763)
* Added `JsonArrayConst`, `JsonObjectConst`, and `JsonVariantConst`
* Added copy-constructor and copy-assignment-operator for `JsonDocument` (issue #827)
v6.4.0-beta (2018-09-11)
-----------
* Copy `JsonArray` and `JsonObject`, instead of storing pointers (issue #780)
* Added `JsonVariant::to<JsonArray>()` and `JsonVariant::to<JsonObject>()`
v6.3.0-beta (2018-08-31)
-----------
* Implemented reference semantics for `JsonVariant`
* Replaced `JsonPair`'s `key` and `value` with `key()` and `value()`
* Fixed `serializeJson(obj[key], dst)` (issue #794)
> ### BREAKING CHANGES
>
> #### JsonVariant
>
> `JsonVariant` now has a semantic similar to `JsonObject` and `JsonArray`.
> It's a reference to a value stored in the `JsonDocument`.
> As a consequence, a `JsonVariant` cannot be used as a standalone variable anymore.
>
> Old code:
>
> ```c++
> JsonVariant myValue = 42;
> ```
>
> New code:
>
> ```c++
> DynamicJsonDocument doc;
> JsonVariant myValue = doc.to<JsonVariant>();
> myValue.set(42);
> ```
>
> #### JsonPair
>
> Old code:
>
> ```c++
> for(JsonPair p : myObject) {
> Serial.println(p.key);
> Serial.println(p.value.as<int>());
> }
> ```
>
> New code:
>
> ```c++
> for(JsonPair p : myObject) {
> Serial.println(p.key());
> Serial.println(p.value().as<int>());
> }
> ```
>
> CAUTION: the key is now read only!
v6.2.3-beta (2018-07-19)
-----------
* Fixed exception when using Flash strings as object keys (issue #784)
v6.2.2-beta (2018-07-18)
-----------
* Fixed `invalid application of 'sizeof' to incomplete type '__FlashStringHelper'` (issue #783)
* Fixed `char[]` not duplicated when passed to `JsonVariant::operator[]`
v6.2.1-beta (2018-07-17)
-----------
* Fixed `JsonObject` not inserting keys of type `String` (issue #782)
v6.2.0-beta (2018-07-12)
-----------
* Disabled lazy number deserialization (issue #772)
* Fixed `JsonVariant::is<int>()` that returned true for empty strings
* Improved float serialization when `-fsingle-precision-constant` is used
* Renamed function `RawJson()` 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:
>
> ```c++
> object["values"] = RawJson("[1,2,3,4]");
> ```
>
> New code:
>
> ```c++
> object["values"] = serialized("[1,2,3,4]");
> ```
v6.1.0-beta (2018-07-02)
-----------
* Return `JsonArray` and `JsonObject` by value instead of reference (issue #309)
* Replaced `success()` with `isNull()`
> ### BREAKING CHANGES
>
> Old code:
>
> ```c++
> JsonObject& obj = doc.to<JsonObject>();
> JsonArray& arr = obj.createNestedArray("key");
> if (!arr.success()) {
> Serial.println("Not enough memory");
> return;
> }
> ```
>
> New code:
>
> ```c++
> JsonObject obj = doc.to<JsonObject>();
> JsonArray arr = obj.createNestedArray("key");
> if (arr.isNull()) {
> Serial.println("Not enough memory");
> return;
> }
> ```
v6.0.1-beta (2018-06-11)
-----------
* Fixed conflicts with `isnan()` and `isinf()` macros (issue #752)
v6.0.0-beta (2018-06-07)
-----------
* Added `DynamicJsonDocument` and `StaticJsonDocument`
* Added `deserializeJson()`
* Added `serializeJson()` and `serializeJsonPretty()`
* Added `measureJson()` and `measureJsonPretty()`
* Added `serializeMsgPack()`, `deserializeMsgPack()` and `measureMsgPack()` (issue #358)
* Added example `MsgPackParser.ino` (issue #358)
* Added support for non zero-terminated strings (issue #704)
* Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()`
* Removed `JsonBuffer::createArray()` and `createObject()`
* Removed `printTo()` and `prettyPrintTo()`
* Removed `measureLength()` and `measurePrettyLength()`
* Removed all deprecated features
> ### BREAKING CHANGES
>
> #### Deserialization
>
> Old code:
>
> ```c++
> DynamicJsonBuffer jb;
> JsonObject& obj = jb.parseObject(json);
> if (obj.success()) {
>
> }
> ```
>
> New code:
>
> ```c++
> DynamicJsonDocument doc;
> DeserializationError error = deserializeJson(doc, json);
> if (error) {
>
> }
> JsonObject& obj = doc.as<JsonObject>();
> ```
>
> #### Serialization
>
> Old code:
>
> ```c++
> DynamicJsonBuffer jb;
> JsonObject& obj = jb.createObject();
> obj["key"] = "value";
> obj.printTo(Serial);
> ```
>
> New code:
>
> ```c++
> DynamicJsonDocument obj;
> JsonObject& obj = doc.to<JsonObject>();
> obj["key"] = "value";
> serializeJson(doc, Serial);
> ```

View File

@ -35,7 +35,6 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
* [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/) * [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
* [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/) * [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
* [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/) * [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/)
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/)
* [Deduplicates strings](https://arduinojson.org/news/2020/08/01/version-6-16-0/) * [Deduplicates strings](https://arduinojson.org/news/2020/08/01/version-6-16-0/)
* Versatile * Versatile
* Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/) * Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/)

View File

@ -34,18 +34,18 @@ struct Config {
int port; int port;
}; };
const char *filename = "/config.txt"; // <- SD library uses 8.3 filenames const char* filename = "/config.txt"; // <- SD library uses 8.3 filenames
Config config; // <- global configuration object Config config; // <- global configuration object
// Loads the configuration from a file // Loads the configuration from a file
void loadConfiguration(const char *filename, Config &config) { void loadConfiguration(const char* filename, Config& config) {
// Open file for reading // Open file for reading
File file = SD.open(filename); File file = SD.open(filename);
// Allocate a temporary JsonDocument // Allocate a temporary JsonDocument
// Don't forget to change the capacity to match your requirements. // Don't forget to change the capacity to match your requirements.
// Use https://arduinojson.org/v6/assistant to compute the capacity. // Use https://arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<512> doc; DynamicJsonDocument doc(512);
// Deserialize the JSON document // Deserialize the JSON document
DeserializationError error = deserializeJson(doc, file); DeserializationError error = deserializeJson(doc, file);
@ -63,7 +63,7 @@ void loadConfiguration(const char *filename, Config &config) {
} }
// Saves the configuration to a file // Saves the configuration to a file
void saveConfiguration(const char *filename, const Config &config) { void saveConfiguration(const char* filename, const Config& config) {
// Delete existing file, otherwise the configuration is appended to the file // Delete existing file, otherwise the configuration is appended to the file
SD.remove(filename); SD.remove(filename);
@ -77,7 +77,7 @@ void saveConfiguration(const char *filename, const Config &config) {
// Allocate a temporary JsonDocument // Allocate a temporary JsonDocument
// Don't forget to change the capacity to match your requirements. // Don't forget to change the capacity to match your requirements.
// Use https://arduinojson.org/assistant to compute the capacity. // Use https://arduinojson.org/assistant to compute the capacity.
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
// Set the values in the document // Set the values in the document
doc["hostname"] = config.hostname; doc["hostname"] = config.hostname;
@ -93,7 +93,7 @@ void saveConfiguration(const char *filename, const Config &config) {
} }
// Prints the content of a file to the Serial // Prints the content of a file to the Serial
void printFile(const char *filename) { void printFile(const char* filename) {
// Open file for reading // Open file for reading
File file = SD.open(filename); File file = SD.open(filename);
if (!file) { if (!file) {
@ -114,7 +114,8 @@ void printFile(const char *filename) {
void setup() { void setup() {
// Initialize serial port // Initialize serial port
Serial.begin(9600); Serial.begin(9600);
while (!Serial) continue; while (!Serial)
continue;
// Initialize SD library // Initialize SD library
const int chipSelect = 4; const int chipSelect = 4;

View File

@ -11,7 +11,8 @@
void setup() { void setup() {
// Initialize serial port // Initialize serial port
Serial.begin(9600); Serial.begin(9600);
while (!Serial) continue; while (!Serial)
continue;
// The huge input: an extract from OpenWeatherMap response // The huge input: an extract from OpenWeatherMap response
const __FlashStringHelper* input_json = F( const __FlashStringHelper* input_json = F(
@ -33,12 +34,12 @@ void setup() {
"1000000,\"timezone\":0,\"sunrise\":1581492085,\"sunset\":1581527294}}"); "1000000,\"timezone\":0,\"sunrise\":1581492085,\"sunset\":1581527294}}");
// The filter: it contains "true" for each value we want to keep // The filter: it contains "true" for each value we want to keep
StaticJsonDocument<200> filter; DynamicJsonDocument filter(200);
filter["list"][0]["dt"] = true; filter["list"][0]["dt"] = true;
filter["list"][0]["main"]["temp"] = true; filter["list"][0]["main"]["temp"] = true;
// Deserialize the document // Deserialize the document
StaticJsonDocument<400> doc; DynamicJsonDocument doc(400);
deserializeJson(doc, input_json, DeserializationOption::Filter(filter)); deserializeJson(doc, input_json, DeserializationOption::Filter(filter));
// Print the result // Print the result

View File

@ -11,19 +11,15 @@
void setup() { void setup() {
// Initialize Serial port // Initialize Serial port
Serial.begin(9600); Serial.begin(9600);
while (!Serial) continue; while (!Serial)
continue;
// Allocate the JSON document // Allocate the JSON document
// //
// Inside the brackets, 200 is the RAM allocated to this document. // Inside the parentheses, 200 is the RAM allocated to this document.
// Don't forget to change this value to match your requirement. // Don't forget to change this value to match your requirement.
// Use https://arduinojson.org/v6/assistant to compute the capacity. // Use https://arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<200> doc; DynamicJsonDocument doc(200);
// StaticJsonObject allocates memory on the stack, it can be
// replaced by DynamicJsonDocument which allocates in the heap.
//
// DynamicJsonDocument doc(200);
// Add values in the document // Add values in the document
// //

View File

@ -11,19 +11,15 @@
void setup() { void setup() {
// Initialize serial port // Initialize serial port
Serial.begin(9600); Serial.begin(9600);
while (!Serial) continue; while (!Serial)
continue;
// Allocate the JSON document // Allocate the JSON document
// //
// Inside the brackets, 200 is the capacity of the memory pool in bytes. // Inside the parentheses, 200 is the capacity of the memory pool in bytes.
// Don't forget to change this value to match your JSON document. // Don't forget to change this value to match your JSON document.
// Use https://arduinojson.org/v6/assistant to compute the capacity. // Use https://arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<200> doc; DynamicJsonDocument doc(200);
// StaticJsonDocument<N> allocates memory on the stack, it can be
// replaced by DynamicJsonDocument which allocates in the heap.
//
// DynamicJsonDocument doc(200);
// JSON input string. // JSON input string.
// //

View File

@ -25,7 +25,8 @@ EthernetServer server(80);
void setup() { void setup() {
// Initialize serial port // Initialize serial port
Serial.begin(9600); Serial.begin(9600);
while (!Serial) continue; while (!Serial)
continue;
// Initialize Ethernet libary // Initialize Ethernet libary
if (!Ethernet.begin(mac)) { if (!Ethernet.begin(mac)) {
@ -52,11 +53,12 @@ void loop() {
Serial.println(F("New client")); Serial.println(F("New client"));
// Read the request (we ignore the content in this example) // Read the request (we ignore the content in this example)
while (client.available()) client.read(); while (client.available())
client.read();
// Allocate a temporary JsonDocument // Allocate a temporary JsonDocument
// Use https://arduinojson.org/v6/assistant to compute the capacity. // Use https://arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<500> doc; DynamicJsonDocument doc(500);
// Create the "analog" array // Create the "analog" array
JsonArray analogValues = doc.createNestedArray("analog"); JsonArray analogValues = doc.createNestedArray("analog");

View File

@ -32,7 +32,8 @@ EthernetUDP udp;
void setup() { void setup() {
// Initialize serial port // Initialize serial port
Serial.begin(9600); Serial.begin(9600);
while (!Serial) continue; while (!Serial)
continue;
// Initialize Ethernet libary // Initialize Ethernet libary
if (!Ethernet.begin(mac)) { if (!Ethernet.begin(mac)) {
@ -47,7 +48,7 @@ void setup() {
void loop() { void loop() {
// Allocate a temporary JsonDocument // Allocate a temporary JsonDocument
// Use https://arduinojson.org/v6/assistant to compute the capacity. // Use https://arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<500> doc; DynamicJsonDocument doc(500);
// Create the "analog" array // Create the "analog" array
JsonArray analogValues = doc.createNestedArray("analog"); JsonArray analogValues = doc.createNestedArray("analog");

View File

@ -12,19 +12,15 @@
void setup() { void setup() {
// Initialize serial port // Initialize serial port
Serial.begin(9600); Serial.begin(9600);
while (!Serial) continue; while (!Serial)
continue;
// Allocate the JSON document // Allocate the JSON document
// //
// Inside the brackets, 200 is the capacity of the memory pool in bytes. // Inside the parentheses, 200 is the capacity of the memory pool in bytes.
// Don't forget to change this value to match your JSON document. // Don't forget to change this value to match your JSON document.
// Use https://arduinojson.org/v6/assistant to compute the capacity. // Use https://arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<200> doc; DynamicJsonDocument doc(200);
// StaticJsonObject allocates memory on the stack, it can be
// replaced by DynamicJsonObject which allocates in the heap.
//
// DynamicJsonObject doc(200);
// MessagePack input string. // MessagePack input string.
// //

View File

@ -6,7 +6,7 @@
extern "C" void app_main() { extern "C" void app_main() {
char buffer[256]; char buffer[256];
StaticJsonDocument<200> doc; DynamicJsonDocument doc(200);
doc["hello"] = "world"; doc["hello"] = "world";
serializeJson(doc, buffer); serializeJson(doc, buffer);

View File

@ -10,20 +10,10 @@
int main() { int main() {
// Allocate the JSON document // Allocate the JSON document
// //
// Inside the brackets, 200 is the RAM allocated to this document. // Inside the parentheses, 200 is the RAM allocated to this document.
// Don't forget to change this value to match your requirement. // Don't forget to change this value to match your requirement.
// Use https://arduinojson.org/v6/assistant to compute the capacity. // Use https://arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<200> doc; DynamicJsonDocument doc(200);
// StaticJsonObject allocates memory on the stack, it can be
// replaced by DynamicJsonDocument which allocates in the heap.
//
// DynamicJsonDocument doc(200);
// StaticJsonObject allocates memory on the stack, it can be
// replaced by DynamicJsonDocument which allocates in the heap.
//
// DynamicJsonDocument doc(200);
// Add values in the document // Add values in the document
// //

View File

@ -10,15 +10,10 @@
int main() { int main() {
// Allocate the JSON document // Allocate the JSON document
// //
// Inside the brackets, 200 is the capacity of the memory pool in bytes. // Inside the parentheses, 200 is the capacity of the memory pool in bytes.
// Don't forget to change this value to match your JSON document. // Don't forget to change this value to match your JSON document.
// Use https://arduinojson.org/v6/assistant to compute the capacity. // Use https://arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<300> doc; DynamicJsonDocument doc(300);
// StaticJsonDocument<N> allocates memory on the stack, it can be
// replaced by DynamicJsonDocument which allocates in the heap.
//
// DynamicJsonDocument doc(200);
// JSON input string. // JSON input string.
// //

View File

@ -10,15 +10,10 @@
int main() { int main() {
// Allocate the JSON document // Allocate the JSON document
// //
// Inside the brackets, 300 is the size of the memory pool in bytes. // Inside the parentheses, 300 is the size of the memory pool in bytes.
// Don't forget to change this value to match your JSON document. // Don't forget to change this value to match your JSON document.
// Use https://arduinojson.org/assistant to compute the capacity. // Use https://arduinojson.org/assistant to compute the capacity.
StaticJsonDocument<300> doc; DynamicJsonDocument doc(300);
// StaticJsonObject allocates memory on the stack, it can be
// replaced by DynamicJsonObject which allocates in the heap.
//
// DynamicJsonObject doc(200);
// MessagePack input string. // MessagePack input string.
// //

View File

@ -8,7 +8,7 @@
#endif #endif
TEST_CASE("string_view") { TEST_CASE("string_view") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
JsonVariant variant = doc.to<JsonVariant>(); JsonVariant variant = doc.to<JsonVariant>();
SECTION("deserializeJson()") { SECTION("deserializeJson()") {

View File

@ -4,7 +4,7 @@
#include <string> #include <string>
TEST_CASE("C++20 smoke test") { TEST_CASE("C++20 smoke test") {
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
deserializeJson(doc, "{\"hello\":\"world\"}"); deserializeJson(doc, "{\"hello\":\"world\"}");
REQUIRE(doc["hello"] == "world"); REQUIRE(doc["hello"] == "world");

View File

@ -53,7 +53,7 @@ TEST_CASE("OpenWeatherMap") {
"]}"; "]}";
// clang-format on // clang-format on
StaticJsonDocument<512> filter; DynamicJsonDocument filter(512);
filter["list"][0]["dt"] = true; filter["list"][0]["dt"] = true;
filter["list"][0]["main"]["temp"] = true; filter["list"][0]["main"]["temp"] = true;
filter["list"][0]["weather"][0]["description"] = true; filter["list"][0]["weather"][0]["description"] = true;

View File

@ -14,7 +14,7 @@ TEST_CASE("JsonArray::clear()") {
} }
SECTION("Removes all elements") { SECTION("Removes all elements") {
StaticJsonDocument<64> doc; DynamicJsonDocument doc(64);
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
array.add(1); array.add(1);
array.add(2); array.add(2);

View File

@ -6,7 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("Compare JsonArray with JsonArray") { TEST_CASE("Compare JsonArray with JsonArray") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
SECTION("Compare with unbound") { SECTION("Compare with unbound") {
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
@ -82,7 +82,7 @@ TEST_CASE("Compare JsonArray with JsonArray") {
} }
TEST_CASE("Compare JsonArray with JsonVariant") { TEST_CASE("Compare JsonArray with JsonVariant") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
SECTION("Compare with self") { SECTION("Compare with self") {
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
@ -153,7 +153,7 @@ TEST_CASE("Compare JsonArray with JsonVariant") {
} }
TEST_CASE("Compare JsonArray with JsonVariantConst") { TEST_CASE("Compare JsonArray with JsonVariantConst") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
SECTION("Compare with unbound") { SECTION("Compare with unbound") {
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
@ -247,7 +247,7 @@ TEST_CASE("Compare JsonArray with JsonVariantConst") {
} }
TEST_CASE("Compare JsonArray with JsonArrayConst") { TEST_CASE("Compare JsonArray with JsonArrayConst") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
SECTION("Compare with unbound") { SECTION("Compare with unbound") {
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
@ -347,7 +347,7 @@ TEST_CASE("Compare JsonArray with JsonArrayConst") {
} }
TEST_CASE("Compare JsonArrayConst with JsonArrayConst") { TEST_CASE("Compare JsonArrayConst with JsonArrayConst") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
SECTION("Compare with unbound") { SECTION("Compare with unbound") {
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
@ -430,7 +430,7 @@ TEST_CASE("Compare JsonArrayConst with JsonArrayConst") {
} }
TEST_CASE("Compare JsonArrayConst with JsonVariant") { TEST_CASE("Compare JsonArrayConst with JsonVariant") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
SECTION("Compare with self") { SECTION("Compare with self") {
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();

View File

@ -108,7 +108,7 @@ TEST_CASE("copyArray()") {
SECTION("int[] -> JsonArray, but not enough memory") { SECTION("int[] -> JsonArray, but not enough memory") {
const size_t SIZE = JSON_ARRAY_SIZE(2); const size_t SIZE = JSON_ARRAY_SIZE(2);
StaticJsonDocument<SIZE> doc; DynamicJsonDocument doc(SIZE);
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
char json[32]; char json[32];
int source[] = {1, 2, 3}; int source[] = {1, 2, 3};
@ -160,7 +160,7 @@ TEST_CASE("copyArray()") {
SECTION("int[][] -> JsonArray, but not enough memory") { SECTION("int[][] -> JsonArray, but not enough memory") {
const size_t SIZE = const size_t SIZE =
JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2); JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2);
StaticJsonDocument<SIZE> doc; DynamicJsonDocument doc(SIZE);
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
char json[32] = ""; char json[32] = "";
int source[][3] = {{1, 2, 3}, {4, 5, 6}}; int source[][3] = {{1, 2, 3}, {4, 5, 6}};

View File

@ -7,7 +7,7 @@
template <typename TArray> template <typename TArray>
static void run_iterator_test() { static void run_iterator_test() {
StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc; DynamicJsonDocument doc(JSON_ARRAY_SIZE(2));
JsonArray tmp = doc.to<JsonArray>(); JsonArray tmp = doc.to<JsonArray>();
tmp.add(12); tmp.add(12);
tmp.add(34); tmp.add(34);

View File

@ -4,7 +4,6 @@
add_executable(JsonDeserializerTests add_executable(JsonDeserializerTests
array.cpp array.cpp
array_static.cpp
DeserializationError.cpp DeserializationError.cpp
filter.cpp filter.cpp
incomplete_input.cpp incomplete_input.cpp
@ -14,7 +13,6 @@ add_executable(JsonDeserializerTests
nestingLimit.cpp nestingLimit.cpp
number.cpp number.cpp
object.cpp object.cpp
object_static.cpp
string.cpp string.cpp
) )

View File

@ -251,3 +251,86 @@ TEST_CASE("deserialize JSON array") {
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0));
} }
} }
TEST_CASE("deserialize JSON array under memory constraints") {
SECTION("buffer of the right size for an empty array") {
DynamicJsonDocument doc(JSON_ARRAY_SIZE(0));
char input[] = "[]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("buffer too small for an array with one element") {
DynamicJsonDocument doc(JSON_ARRAY_SIZE(0));
char input[] = "[1]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("buffer of the right size for an array with one element") {
DynamicJsonDocument doc(JSON_ARRAY_SIZE(1));
char input[] = "[1]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("buffer too small for an array with a nested object") {
DynamicJsonDocument doc(JSON_ARRAY_SIZE(0) + JSON_OBJECT_SIZE(0));
char input[] = "[{}]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("buffer of the right size for an array with a nested object") {
DynamicJsonDocument doc(JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0));
char input[] = "[{}]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("don't store space characters") {
DynamicJsonDocument doc(100);
deserializeJson(doc, " [ \"1234567\" ] ");
REQUIRE(JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(7) == doc.memoryUsage());
// note: we use a string of 8 bytes to be sure that the MemoryPool
// will not insert bytes to enforce alignement
}
SECTION("Should clear the JsonArray") {
DynamicJsonDocument doc(JSON_ARRAY_SIZE(4));
char input[] = "[1,2,3,4]";
deserializeJson(doc, input);
deserializeJson(doc, "[]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(arr.size() == 0);
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0));
}
SECTION("buffer of the right size for an array with two element") {
DynamicJsonDocument doc(JSON_ARRAY_SIZE(2));
char input[] = "[1,2]";
DeserializationError err = deserializeJson(doc, input);
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonArray>());
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2));
REQUIRE(arr[0] == 1);
REQUIRE(arr[1] == 2);
}
}

View File

@ -1,89 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("deserialize JSON array with a StaticJsonDocument") {
SECTION("BufferOfTheRightSizeForEmptyArray") {
StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc;
char input[] = "[]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("TooSmallBufferForArrayWithOneValue") {
StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc;
char input[] = "[1]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("BufferOfTheRightSizeForArrayWithOneValue") {
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc;
char input[] = "[1]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("TooSmallBufferForArrayWithNestedObject") {
StaticJsonDocument<JSON_ARRAY_SIZE(0) + JSON_OBJECT_SIZE(0)> doc;
char input[] = "[{}]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("BufferOfTheRightSizeForArrayWithNestedObject") {
StaticJsonDocument<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)> doc;
char input[] = "[{}]";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("CopyStringNotSpaces") {
StaticJsonDocument<100> doc;
deserializeJson(doc, " [ \"1234567\" ] ");
REQUIRE(JSON_ARRAY_SIZE(1) + JSON_STRING_SIZE(7) == doc.memoryUsage());
// note: we use a string of 8 bytes to be sure that the StaticMemoryPool
// will not insert bytes to enforce alignement
}
SECTION("Should clear the JsonArray") {
StaticJsonDocument<JSON_ARRAY_SIZE(4)> doc;
char input[] = "[1,2,3,4]";
deserializeJson(doc, input);
deserializeJson(doc, "[]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(arr.size() == 0);
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0));
}
SECTION("Array") {
StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc;
char input[] = "[1,2]";
DeserializationError err = deserializeJson(doc, input);
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.is<JsonArray>());
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2));
REQUIRE(arr[0] == 1);
REQUIRE(arr[1] == 2);
}
}

View File

@ -706,10 +706,10 @@ TEST_CASE("Filtering") {
TEST_CASE("Zero-copy mode") { // issue #1697 TEST_CASE("Zero-copy mode") { // issue #1697
char input[] = "{\"include\":42,\"exclude\":666}"; char input[] = "{\"include\":42,\"exclude\":666}";
StaticJsonDocument<256> filter; DynamicJsonDocument filter(256);
filter["include"] = true; filter["include"] = true;
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
DeserializationError err = DeserializationError err =
deserializeJson(doc, input, DeserializationOption::Filter(filter)); deserializeJson(doc, input, DeserializationOption::Filter(filter));
@ -718,8 +718,8 @@ TEST_CASE("Zero-copy mode") { // issue #1697
} }
TEST_CASE("Overloads") { TEST_CASE("Overloads") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
StaticJsonDocument<256> filter; DynamicJsonDocument filter(256);
using namespace DeserializationOption; using namespace DeserializationOption;

View File

@ -10,7 +10,7 @@
#include "CustomReader.hpp" #include "CustomReader.hpp"
TEST_CASE("deserializeJson(char*)") { TEST_CASE("deserializeJson(char*)") {
StaticJsonDocument<1024> doc; DynamicJsonDocument doc(1024);
SECTION("should not duplicate strings") { SECTION("should not duplicate strings") {
char input[] = "{\"hello\":\"world\"}"; char input[] = "{\"hello\":\"world\"}";
@ -125,7 +125,7 @@ TEST_CASE("deserializeJson(VLA)") {
char vla[i]; char vla[i];
strcpy(vla, "{\"a\":42}"); strcpy(vla, "{\"a\":42}");
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(1));
DeserializationError err = deserializeJson(doc, vla); DeserializationError err = deserializeJson(doc, vla);
REQUIRE(err == DeserializationError::Ok); REQUIRE(err == DeserializationError::Ok);

View File

@ -313,3 +313,61 @@ TEST_CASE("deserialize JSON object") {
CHECK(doc.as<std::string>() == json); CHECK(doc.as<std::string>() == json);
} }
} }
TEST_CASE("deserialize JSON object under memory constraints") {
SECTION("buffer for the right size for an empty object") {
DynamicJsonDocument doc(JSON_OBJECT_SIZE(0));
char input[] = "{}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("buffer too small for an empty object") {
DynamicJsonDocument doc(JSON_OBJECT_SIZE(0));
char input[] = "{\"a\":1}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("buffer of the right size for an object with one member") {
DynamicJsonDocument doc(JSON_OBJECT_SIZE(1));
char input[] = "{\"a\":1}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("buffer too small for an object with a nested array") {
DynamicJsonDocument doc(JSON_OBJECT_SIZE(0) + JSON_ARRAY_SIZE(0));
char input[] = "{\"a\":[]}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("buffer of the right size for an object with a nested array") {
DynamicJsonDocument doc(JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0));
char input[] = "{\"a\":[]}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("Should clear the JsonObject") {
DynamicJsonDocument doc(JSON_OBJECT_SIZE(1));
char input[] = "{\"hello\":\"world\"}";
deserializeJson(doc, input);
deserializeJson(doc, "{}");
REQUIRE(doc.as<JsonObject>().size() == 0);
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0));
}
}

View File

@ -1,64 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("deserialize JSON object with StaticJsonDocument") {
SECTION("BufferOfTheRightSizeForEmptyObject") {
StaticJsonDocument<JSON_OBJECT_SIZE(0)> doc;
char input[] = "{}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("TooSmallBufferForObjectWithOneValue") {
StaticJsonDocument<JSON_OBJECT_SIZE(0)> doc;
char input[] = "{\"a\":1}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("BufferOfTheRightSizeForObjectWithOneValue") {
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
char input[] = "{\"a\":1}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("TooSmallBufferForObjectWithNestedObject") {
StaticJsonDocument<JSON_OBJECT_SIZE(0) + JSON_ARRAY_SIZE(0)> doc;
char input[] = "{\"a\":[]}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("BufferOfTheRightSizeForObjectWithNestedObject") {
StaticJsonDocument<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)> doc;
char input[] = "{\"a\":[]}";
DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok);
}
SECTION("Should clear the JsonObject") {
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc;
char input[] = "{\"hello\":\"world\"}";
deserializeJson(doc, input);
deserializeJson(doc, "{}");
REQUIRE(doc.as<JsonObject>().size() == 0);
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0));
}
}

View File

@ -47,7 +47,7 @@ TEST_CASE("Valid JSON strings value") {
} }
TEST_CASE("\\u0000") { TEST_CASE("\\u0000") {
StaticJsonDocument<200> doc; DynamicJsonDocument doc(200);
DeserializationError err = deserializeJson(doc, "\"wx\\u0000yz\""); DeserializationError err = deserializeJson(doc, "\"wx\\u0000yz\"");
REQUIRE(err == DeserializationError::Ok); REQUIRE(err == DeserializationError::Ok);

View File

@ -19,7 +19,6 @@ add_executable(JsonDocumentTests
remove.cpp remove.cpp
shrinkToFit.cpp shrinkToFit.cpp
size.cpp size.cpp
StaticJsonDocument.cpp
subscript.cpp subscript.cpp
swap.cpp swap.cpp
) )

View File

@ -94,18 +94,8 @@ TEST_CASE("DynamicJsonDocument constructor") {
REQUIRE(doc2.capacity() == doc1.capacity()); REQUIRE(doc2.capacity() == doc1.capacity());
} }
SECTION("Construct from StaticJsonDocument") {
StaticJsonDocument<200> doc1;
deserializeJson(doc1, "{\"hello\":\"world\"}");
DynamicJsonDocument doc2 = doc1;
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
REQUIRE(doc2.capacity() == doc1.capacity());
}
SECTION("Construct from JsonObject") { SECTION("Construct from JsonObject") {
StaticJsonDocument<200> doc1; DynamicJsonDocument doc1(200);
JsonObject obj = doc1.to<JsonObject>(); JsonObject obj = doc1.to<JsonObject>();
obj["hello"] = "world"; obj["hello"] = "world";
@ -116,7 +106,7 @@ TEST_CASE("DynamicJsonDocument constructor") {
} }
SECTION("Construct from JsonArray") { SECTION("Construct from JsonArray") {
StaticJsonDocument<200> doc1; DynamicJsonDocument doc1(200);
JsonArray arr = doc1.to<JsonArray>(); JsonArray arr = doc1.to<JsonArray>();
arr.add("hello"); arr.add("hello");
@ -127,7 +117,7 @@ TEST_CASE("DynamicJsonDocument constructor") {
} }
SECTION("Construct from JsonVariant") { SECTION("Construct from JsonVariant") {
StaticJsonDocument<200> doc1; DynamicJsonDocument doc1(200);
deserializeJson(doc1, "42"); deserializeJson(doc1, "42");
DynamicJsonDocument doc2 = doc1.as<JsonVariant>(); DynamicJsonDocument doc2 = doc1.as<JsonVariant>();
@ -160,19 +150,8 @@ TEST_CASE("DynamicJsonDocument assignment") {
REQUIRE(doc2.capacity() == doc1.capacity()); REQUIRE(doc2.capacity() == doc1.capacity());
} }
SECTION("Assign from StaticJsonDocument") {
StaticJsonDocument<200> doc1;
deserializeJson(doc1, "{\"hello\":\"world\"}");
DynamicJsonDocument doc2(4096);
doc2.to<JsonVariant>().set(666);
doc2 = doc1;
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Assign from JsonObject") { SECTION("Assign from JsonObject") {
StaticJsonDocument<200> doc1; DynamicJsonDocument doc1(200);
JsonObject obj = doc1.to<JsonObject>(); JsonObject obj = doc1.to<JsonObject>();
obj["hello"] = "world"; obj["hello"] = "world";
@ -184,7 +163,7 @@ TEST_CASE("DynamicJsonDocument assignment") {
} }
SECTION("Assign from JsonArray") { SECTION("Assign from JsonArray") {
StaticJsonDocument<200> doc1; DynamicJsonDocument doc1(200);
JsonArray arr = doc1.to<JsonArray>(); JsonArray arr = doc1.to<JsonArray>();
arr.add("hello"); arr.add("hello");
@ -196,7 +175,7 @@ TEST_CASE("DynamicJsonDocument assignment") {
} }
SECTION("Assign from JsonVariant") { SECTION("Assign from JsonVariant") {
StaticJsonDocument<200> doc1; DynamicJsonDocument doc1(200);
deserializeJson(doc1, "42"); deserializeJson(doc1, "42");
DynamicJsonDocument doc2(4096); DynamicJsonDocument doc2(4096);
@ -207,7 +186,7 @@ TEST_CASE("DynamicJsonDocument assignment") {
} }
SECTION("Assign from MemberProxy") { SECTION("Assign from MemberProxy") {
StaticJsonDocument<200> doc1; DynamicJsonDocument doc1(200);
doc1["value"] = 42; doc1["value"] = 42;
DynamicJsonDocument doc2(4096); DynamicJsonDocument doc2(4096);
@ -218,7 +197,7 @@ TEST_CASE("DynamicJsonDocument assignment") {
} }
SECTION("Assign from ElementProxy") { SECTION("Assign from ElementProxy") {
StaticJsonDocument<200> doc1; DynamicJsonDocument doc1(200);
doc1[0] = 42; doc1[0] = 42;
DynamicJsonDocument doc2(4096); DynamicJsonDocument doc2(4096);

View File

@ -247,7 +247,7 @@ TEST_CASE("ElementProxy cast to JsonVariant") {
} }
TEST_CASE("ElementProxy::shallowCopy()") { TEST_CASE("ElementProxy::shallowCopy()") {
StaticJsonDocument<1024> doc1, doc2; DynamicJsonDocument doc1(1024), doc2(1024);
doc2["hello"] = "world"; doc2["hello"] = "world";
doc1[0].shallowCopy(doc2); doc1[0].shallowCopy(doc2);

View File

@ -127,7 +127,7 @@ TEST_CASE("MemberProxy::operator|()") {
JsonObject object = doc.to<JsonObject>(); JsonObject object = doc.to<JsonObject>();
object["hello"] = "world"; object["hello"] = "world";
StaticJsonDocument<0> emptyDoc; DynamicJsonDocument emptyDoc(0);
JsonObject anotherObject = object["hello"] | emptyDoc.to<JsonObject>(); JsonObject anotherObject = object["hello"] | emptyDoc.to<JsonObject>();
REQUIRE(anotherObject.isNull() == false); REQUIRE(anotherObject.isNull() == false);
@ -288,7 +288,7 @@ TEST_CASE("MemberProxy cast to JsonVariant") {
} }
TEST_CASE("MemberProxy::createNestedArray()") { TEST_CASE("MemberProxy::createNestedArray()") {
StaticJsonDocument<1024> doc; DynamicJsonDocument doc(1024);
JsonArray arr = doc["items"].createNestedArray(); JsonArray arr = doc["items"].createNestedArray();
arr.add(42); arr.add(42);
@ -296,7 +296,7 @@ TEST_CASE("MemberProxy::createNestedArray()") {
} }
TEST_CASE("MemberProxy::createNestedArray(key)") { TEST_CASE("MemberProxy::createNestedArray(key)") {
StaticJsonDocument<1024> doc; DynamicJsonDocument doc(1024);
JsonArray arr = doc["weather"].createNestedArray("temp"); JsonArray arr = doc["weather"].createNestedArray("temp");
arr.add(42); arr.add(42);
@ -304,7 +304,7 @@ TEST_CASE("MemberProxy::createNestedArray(key)") {
} }
TEST_CASE("MemberProxy::createNestedObject()") { TEST_CASE("MemberProxy::createNestedObject()") {
StaticJsonDocument<1024> doc; DynamicJsonDocument doc(1024);
JsonObject obj = doc["items"].createNestedObject(); JsonObject obj = doc["items"].createNestedObject();
obj["value"] = 42; obj["value"] = 42;
@ -312,7 +312,7 @@ TEST_CASE("MemberProxy::createNestedObject()") {
} }
TEST_CASE("MemberProxy::createNestedObject(key)") { TEST_CASE("MemberProxy::createNestedObject(key)") {
StaticJsonDocument<1024> doc; DynamicJsonDocument doc(1024);
JsonObject obj = doc["status"].createNestedObject("weather"); JsonObject obj = doc["status"].createNestedObject("weather");
obj["temp"] = 42; obj["temp"] = 42;
@ -320,7 +320,7 @@ TEST_CASE("MemberProxy::createNestedObject(key)") {
} }
TEST_CASE("MemberProxy::shallowCopy()") { TEST_CASE("MemberProxy::shallowCopy()") {
StaticJsonDocument<1024> doc1, doc2; DynamicJsonDocument doc1(1024), doc2(1024);
doc2["hello"] = "world"; doc2["hello"] = "world";
doc1["obj"].shallowCopy(doc2); doc1["obj"].shallowCopy(doc2);

View File

@ -1,224 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
static void REQUIRE_JSON(JsonDocument& doc, const std::string& expected) {
std::string json;
serializeJson(doc, json);
REQUIRE(json == expected);
}
TEST_CASE("StaticJsonDocument") {
SECTION("capacity()") {
SECTION("matches template argument") {
StaticJsonDocument<256> doc;
REQUIRE(doc.capacity() == 256);
}
SECTION("rounds up template argument") {
StaticJsonDocument<253> doc;
REQUIRE(doc.capacity() == 256);
}
}
SECTION("serializeJson()") {
StaticJsonDocument<200> doc;
JsonObject obj = doc.to<JsonObject>();
obj["hello"] = "world";
std::string json;
serializeJson(doc, json);
REQUIRE(json == "{\"hello\":\"world\"}");
}
SECTION("Copy assignment") {
StaticJsonDocument<200> doc1, doc2;
doc1.to<JsonVariant>().set(666);
deserializeJson(doc2, "{\"hello\":\"world\"}");
doc1 = doc2;
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Contructor") {
SECTION("Copy constructor") {
StaticJsonDocument<200> doc1;
deserializeJson(doc1, "{\"hello\":\"world\"}");
StaticJsonDocument<200> doc2 = doc1;
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Construct from StaticJsonDocument of different size") {
StaticJsonDocument<300> doc1;
deserializeJson(doc1, "{\"hello\":\"world\"}");
StaticJsonDocument<200> doc2 = doc1;
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Construct from DynamicJsonDocument") {
DynamicJsonDocument doc1(4096);
deserializeJson(doc1, "{\"hello\":\"world\"}");
StaticJsonDocument<200> doc2 = doc1;
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Construct from JsonObject") {
DynamicJsonDocument doc1(4096);
deserializeJson(doc1, "{\"hello\":\"world\"}");
StaticJsonDocument<200> doc2 = doc1.as<JsonObject>();
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Construct from JsonArray") {
DynamicJsonDocument doc1(4096);
deserializeJson(doc1, "[\"hello\",\"world\"]");
StaticJsonDocument<200> doc2 = doc1.as<JsonArray>();
deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]");
REQUIRE_JSON(doc2, "[\"hello\",\"world\"]");
}
SECTION("Construct from JsonVariant") {
DynamicJsonDocument doc1(4096);
deserializeJson(doc1, "42");
StaticJsonDocument<200> doc2 = doc1.as<JsonVariant>();
REQUIRE_JSON(doc2, "42");
}
}
SECTION("Assignment") {
SECTION("Copy assignment") {
StaticJsonDocument<200> doc1, doc2;
doc1.to<JsonVariant>().set(666);
deserializeJson(doc1, "{\"hello\":\"world\"}");
doc2 = doc1;
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Assign from StaticJsonDocument of different capacity") {
StaticJsonDocument<200> doc1;
StaticJsonDocument<300> doc2;
doc1.to<JsonVariant>().set(666);
deserializeJson(doc1, "{\"hello\":\"world\"}");
doc2 = doc1;
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Assign from DynamicJsonDocument") {
StaticJsonDocument<200> doc1;
DynamicJsonDocument doc2(4096);
doc1.to<JsonVariant>().set(666);
deserializeJson(doc1, "{\"hello\":\"world\"}");
doc2 = doc1;
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Assign from JsonArray") {
StaticJsonDocument<200> doc1;
DynamicJsonDocument doc2(4096);
doc1.to<JsonVariant>().set(666);
deserializeJson(doc1, "[\"hello\",\"world\"]");
doc2 = doc1.as<JsonArray>();
deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]");
REQUIRE_JSON(doc2, "[\"hello\",\"world\"]");
}
SECTION("Assign from JsonArrayConst") {
StaticJsonDocument<200> doc1;
DynamicJsonDocument doc2(4096);
doc1.to<JsonVariant>().set(666);
deserializeJson(doc1, "[\"hello\",\"world\"]");
doc2 = doc1.as<JsonArrayConst>();
deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]");
REQUIRE_JSON(doc2, "[\"hello\",\"world\"]");
}
SECTION("Assign from JsonObject") {
StaticJsonDocument<200> doc1;
DynamicJsonDocument doc2(4096);
doc1.to<JsonVariant>().set(666);
deserializeJson(doc1, "{\"hello\":\"world\"}");
doc2 = doc1.as<JsonObject>();
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Assign from JsonObjectConst") {
StaticJsonDocument<200> doc1;
DynamicJsonDocument doc2(4096);
doc1.to<JsonVariant>().set(666);
deserializeJson(doc1, "{\"hello\":\"world\"}");
doc2 = doc1.as<JsonObjectConst>();
deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}");
REQUIRE_JSON(doc2, "{\"hello\":\"world\"}");
}
SECTION("Assign from JsonVariant") {
DynamicJsonDocument doc1(4096);
doc1.to<JsonVariant>().set(666);
deserializeJson(doc1, "42");
StaticJsonDocument<200> doc2;
doc2 = doc1.as<JsonVariant>();
REQUIRE_JSON(doc2, "42");
}
SECTION("Assign from JsonVariantConst") {
DynamicJsonDocument doc1(4096);
doc1.to<JsonVariant>().set(666);
deserializeJson(doc1, "42");
StaticJsonDocument<200> doc2;
doc2 = doc1.as<JsonVariantConst>();
REQUIRE_JSON(doc2, "42");
}
}
SECTION("garbageCollect()") {
StaticJsonDocument<256> doc;
doc[std::string("example")] = std::string("jukebox");
doc.remove("example");
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(1) + 16);
doc.garbageCollect();
REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0));
REQUIRE_JSON(doc, "{}");
}
}

View File

@ -8,7 +8,7 @@
#include <string> #include <string>
TEST_CASE("Implicit cast to JsonVariant") { TEST_CASE("Implicit cast to JsonVariant") {
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
doc["hello"] = "world"; doc["hello"] = "world";

View File

@ -28,57 +28,9 @@ TEST_CASE("DynamicJsonDocument::operator==(const DynamicJsonDocument&)") {
} }
} }
TEST_CASE("DynamicJsonDocument::operator==(const StaticJsonDocument&)") {
DynamicJsonDocument doc1(4096);
StaticJsonDocument<256> doc2;
SECTION("Empty") {
REQUIRE(doc1 == doc2);
REQUIRE_FALSE(doc1 != doc2);
}
SECTION("With same object") {
doc1["hello"] = "world";
doc2["hello"] = "world";
REQUIRE(doc1 == doc2);
REQUIRE_FALSE(doc1 != doc2);
}
SECTION("With different object") {
doc1["hello"] = "world";
doc2["world"] = "hello";
REQUIRE_FALSE(doc1 == doc2);
REQUIRE(doc1 != doc2);
}
}
TEST_CASE("StaticJsonDocument::operator==(const DynamicJsonDocument&)") {
StaticJsonDocument<256> doc1;
DynamicJsonDocument doc2(4096);
SECTION("Empty") {
REQUIRE(doc1 == doc2);
REQUIRE_FALSE(doc1 != doc2);
}
SECTION("With same object") {
doc1["hello"] = "world";
doc2["hello"] = "world";
REQUIRE(doc1 == doc2);
REQUIRE_FALSE(doc1 != doc2);
}
SECTION("With different object") {
doc1["hello"] = "world";
doc2["world"] = "hello";
REQUIRE_FALSE(doc1 == doc2);
REQUIRE(doc1 != doc2);
}
}
TEST_CASE("JsonDocument::operator==(const JsonDocument&)") { TEST_CASE("JsonDocument::operator==(const JsonDocument&)") {
StaticJsonDocument<256> doc1; DynamicJsonDocument doc1(256);
StaticJsonDocument<256> doc2; DynamicJsonDocument doc2(256);
const JsonDocument& ref1 = doc1; const JsonDocument& ref1 = doc1;
const JsonDocument& ref2 = doc2; const JsonDocument& ref2 = doc2;

View File

@ -3,7 +3,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("Issue #1120") { TEST_CASE("Issue #1120") {
StaticJsonDocument<500> doc; DynamicJsonDocument doc(500);
constexpr char str[] = constexpr char str[] =
"{\"contents\":[{\"module\":\"Packet\"},{\"module\":\"Analog\"}]}"; "{\"contents\":[{\"module\":\"Packet\"},{\"module\":\"Analog\"}]}";
deserializeJson(doc, str); deserializeJson(doc, str);

View File

@ -7,54 +7,54 @@
TEST_CASE("JsonDocument::overflowed()") { TEST_CASE("JsonDocument::overflowed()") {
SECTION("returns false on a fresh object") { SECTION("returns false on a fresh object") {
StaticJsonDocument<0> doc; DynamicJsonDocument doc(0);
CHECK(doc.overflowed() == false); CHECK(doc.overflowed() == false);
} }
SECTION("returns true after a failed insertion") { SECTION("returns true after a failed insertion") {
StaticJsonDocument<0> doc; DynamicJsonDocument doc(0);
doc.add(0); doc.add(0);
CHECK(doc.overflowed() == true); CHECK(doc.overflowed() == true);
} }
SECTION("returns false after successful insertion") { SECTION("returns false after successful insertion") {
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc; DynamicJsonDocument doc(JSON_ARRAY_SIZE(1));
doc.add(0); doc.add(0);
CHECK(doc.overflowed() == false); CHECK(doc.overflowed() == false);
} }
SECTION("returns true after a failed string copy") { SECTION("returns true after a failed string copy") {
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc; DynamicJsonDocument doc(JSON_ARRAY_SIZE(1));
doc.add(std::string("example")); doc.add(std::string("example"));
CHECK(doc.overflowed() == true); CHECK(doc.overflowed() == true);
} }
SECTION("returns false after a successful string copy") { SECTION("returns false after a successful string copy") {
StaticJsonDocument<JSON_ARRAY_SIZE(1) + 8> doc; DynamicJsonDocument doc(JSON_ARRAY_SIZE(1) + 8);
doc.add(std::string("example")); doc.add(std::string("example"));
CHECK(doc.overflowed() == false); CHECK(doc.overflowed() == false);
} }
SECTION("returns true after a failed member add") { SECTION("returns true after a failed member add") {
StaticJsonDocument<1> doc; DynamicJsonDocument doc(1);
doc["example"] = true; doc["example"] = true;
CHECK(doc.overflowed() == true); CHECK(doc.overflowed() == true);
} }
SECTION("returns true after a failed deserialization") { SECTION("returns true after a failed deserialization") {
StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc; DynamicJsonDocument doc(JSON_ARRAY_SIZE(1));
deserializeJson(doc, "[\"example\"]"); deserializeJson(doc, "[\"example\"]");
CHECK(doc.overflowed() == true); CHECK(doc.overflowed() == true);
} }
SECTION("returns false after a successful deserialization") { SECTION("returns false after a successful deserialization") {
StaticJsonDocument<JSON_ARRAY_SIZE(1) + 8> doc; DynamicJsonDocument doc(JSON_ARRAY_SIZE(1) + 8);
deserializeJson(doc, "[\"example\"]"); deserializeJson(doc, "[\"example\"]");
CHECK(doc.overflowed() == false); CHECK(doc.overflowed() == false);
} }
SECTION("returns false after clear()") { SECTION("returns false after clear()") {
StaticJsonDocument<0> doc; DynamicJsonDocument doc(0);
doc.add(0); doc.add(0);
doc.clear(); doc.clear();
CHECK(doc.overflowed() == false); CHECK(doc.overflowed() == false);

View File

@ -14,7 +14,7 @@ TEST_CASE("JsonObject::clear()") {
} }
SECTION("Removes all elements") { SECTION("Removes all elements") {
StaticJsonDocument<64> doc; DynamicJsonDocument doc(64);
JsonObject obj = doc.to<JsonObject>(); JsonObject obj = doc.to<JsonObject>();
obj["hello"] = 1; obj["hello"] = 1;
obj["world"] = 2; obj["world"] = 2;

View File

@ -6,7 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("Compare JsonObject with JsonObject") { TEST_CASE("Compare JsonObject with JsonObject") {
StaticJsonDocument<512> doc; DynamicJsonDocument doc(512);
SECTION("Compare with unbound") { SECTION("Compare with unbound") {
JsonObject object = doc.to<JsonObject>(); JsonObject object = doc.to<JsonObject>();
@ -82,7 +82,7 @@ TEST_CASE("Compare JsonObject with JsonObject") {
} }
TEST_CASE("Compare JsonObject with JsonVariant") { TEST_CASE("Compare JsonObject with JsonVariant") {
StaticJsonDocument<512> doc; DynamicJsonDocument doc(512);
SECTION("Compare with self") { SECTION("Compare with self") {
JsonObject object = doc.to<JsonObject>(); JsonObject object = doc.to<JsonObject>();
@ -153,7 +153,7 @@ TEST_CASE("Compare JsonObject with JsonVariant") {
} }
TEST_CASE("Compare JsonObject with JsonVariantConst") { TEST_CASE("Compare JsonObject with JsonVariantConst") {
StaticJsonDocument<512> doc; DynamicJsonDocument doc(512);
SECTION("Compare with unbound") { SECTION("Compare with unbound") {
JsonObject object = doc.to<JsonObject>(); JsonObject object = doc.to<JsonObject>();
@ -247,7 +247,7 @@ TEST_CASE("Compare JsonObject with JsonVariantConst") {
} }
TEST_CASE("Compare JsonObject with JsonObjectConst") { TEST_CASE("Compare JsonObject with JsonObjectConst") {
StaticJsonDocument<512> doc; DynamicJsonDocument doc(512);
SECTION("Compare with unbound") { SECTION("Compare with unbound") {
JsonObject object = doc.to<JsonObject>(); JsonObject object = doc.to<JsonObject>();
@ -347,7 +347,7 @@ TEST_CASE("Compare JsonObject with JsonObjectConst") {
} }
TEST_CASE("Compare JsonObjectConst with JsonObjectConst") { TEST_CASE("Compare JsonObjectConst with JsonObjectConst") {
StaticJsonDocument<512> doc; DynamicJsonDocument doc(512);
SECTION("Compare with unbound") { SECTION("Compare with unbound") {
JsonObject object = doc.to<JsonObject>(); JsonObject object = doc.to<JsonObject>();
@ -430,7 +430,7 @@ TEST_CASE("Compare JsonObjectConst with JsonObjectConst") {
} }
TEST_CASE("Compare JsonObjectConst with JsonVariant") { TEST_CASE("Compare JsonObjectConst with JsonVariant") {
StaticJsonDocument<512> doc; DynamicJsonDocument doc(512);
SECTION("Compare with self") { SECTION("Compare with self") {
JsonObject object = doc.to<JsonObject>(); JsonObject object = doc.to<JsonObject>();

View File

@ -72,7 +72,7 @@ TEST_CASE("JsonObject::set()") {
} }
SECTION("destination too small to store the key") { SECTION("destination too small to store the key") {
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc3; DynamicJsonDocument doc3(JSON_OBJECT_SIZE(1));
JsonObject obj3 = doc3.to<JsonObject>(); JsonObject obj3 = doc3.to<JsonObject>();
obj1[std::string("hello")] = "world"; obj1[std::string("hello")] = "world";
@ -84,7 +84,7 @@ TEST_CASE("JsonObject::set()") {
} }
SECTION("destination too small to store the value") { SECTION("destination too small to store the value") {
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc3; DynamicJsonDocument doc3(JSON_OBJECT_SIZE(1));
JsonObject obj3 = doc3.to<JsonObject>(); JsonObject obj3 = doc3.to<JsonObject>();
obj1["hello"] = std::string("world"); obj1["hello"] = std::string("world");

View File

@ -8,7 +8,7 @@
using namespace Catch::Matchers; using namespace Catch::Matchers;
TEST_CASE("JsonObject::begin()/end()") { TEST_CASE("JsonObject::begin()/end()") {
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(2));
JsonObject obj = doc.to<JsonObject>(); JsonObject obj = doc.to<JsonObject>();
obj["ab"] = 12; obj["ab"] = 12;
obj["cd"] = 34; obj["cd"] = 34;
@ -38,7 +38,7 @@ TEST_CASE("JsonObject::begin()/end()") {
} }
TEST_CASE("JsonObjectConst::begin()/end()") { TEST_CASE("JsonObjectConst::begin()/end()") {
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(2));
JsonObject obj = doc.to<JsonObject>(); JsonObject obj = doc.to<JsonObject>();
obj["ab"] = 12; obj["ab"] = 12;
obj["cd"] = 34; obj["cd"] = 34;

View File

@ -15,7 +15,7 @@ static void check(JsonArray array, std::string expected) {
} }
TEST_CASE("serializeJson(JsonArray)") { TEST_CASE("serializeJson(JsonArray)") {
StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc; DynamicJsonDocument doc(JSON_ARRAY_SIZE(2));
JsonArray array = doc.to<JsonArray>(); JsonArray array = doc.to<JsonArray>();
SECTION("Empty") { SECTION("Empty") {

View File

@ -47,7 +47,7 @@ TEST_CASE("serialize JsonObject to std::string") {
} }
TEST_CASE("serialize an std::string containing a NUL") { TEST_CASE("serialize an std::string containing a NUL") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
doc.set(std::string("hello\0world", 11)); doc.set(std::string("hello\0world", 11));
CHECK(doc.memoryUsage() == 12); CHECK(doc.memoryUsage() == 12);

View File

@ -9,7 +9,7 @@
// Here, we're just filling the holes // Here, we're just filling the holes
TEST_CASE("Compare JsonVariant with value") { TEST_CASE("Compare JsonVariant with value") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
JsonVariant a = doc.add(); JsonVariant a = doc.add();
SECTION("null vs (char*)0") { SECTION("null vs (char*)0") {
@ -37,7 +37,7 @@ TEST_CASE("Compare JsonVariant with value") {
} }
TEST_CASE("Compare JsonVariant with JsonVariant") { TEST_CASE("Compare JsonVariant with JsonVariant") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
JsonVariant a = doc.add(); JsonVariant a = doc.add();
JsonVariant b = doc.add(); JsonVariant b = doc.add();

View File

@ -71,13 +71,13 @@ TEST_CASE("JsonVariant::isNull()") {
} }
SECTION("returns true for a shallow null copy") { SECTION("returns true for a shallow null copy") {
StaticJsonDocument<128> doc2; DynamicJsonDocument doc2(128);
variant.shallowCopy(doc2); variant.shallowCopy(doc2);
CHECK(variant.isNull() == true); CHECK(variant.isNull() == true);
} }
SECTION("returns false for a shallow array copy") { SECTION("returns false for a shallow array copy") {
StaticJsonDocument<128> doc2; DynamicJsonDocument doc2(128);
doc2[0] = 42; doc2[0] = 42;
variant.shallowCopy(doc2); variant.shallowCopy(doc2);
CHECK(variant.isNull() == false); CHECK(variant.isNull() == false);

View File

@ -7,7 +7,7 @@
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
void shouldBeOk(TIn value) { void shouldBeOk(TIn value) {
StaticJsonDocument<1> doc; DynamicJsonDocument doc(1);
JsonVariant var = doc.to<JsonVariant>(); JsonVariant var = doc.to<JsonVariant>();
var.set(value); var.set(value);
REQUIRE(var.as<TOut>() == TOut(value)); REQUIRE(var.as<TOut>() == TOut(value));
@ -15,7 +15,7 @@ void shouldBeOk(TIn value) {
template <typename TOut, typename TIn> template <typename TOut, typename TIn>
void shouldOverflow(TIn value) { void shouldOverflow(TIn value) {
StaticJsonDocument<1> doc; DynamicJsonDocument doc(1);
JsonVariant var = doc.to<JsonVariant>(); JsonVariant var = doc.to<JsonVariant>();
var.set(value); var.set(value);
REQUIRE(var.as<TOut>() == 0); REQUIRE(var.as<TOut>() == 0);

View File

@ -128,7 +128,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
} }
TEST_CASE("JsonVariant::set() with not enough memory") { TEST_CASE("JsonVariant::set() with not enough memory") {
StaticJsonDocument<1> doc; DynamicJsonDocument doc(1);
JsonVariant v = doc.to<JsonVariant>(); JsonVariant v = doc.to<JsonVariant>();

View File

@ -6,7 +6,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("JsonVariant::shallowCopy()") { TEST_CASE("JsonVariant::shallowCopy()") {
StaticJsonDocument<1024> doc1, doc2; DynamicJsonDocument doc1(1024), doc2(1024);
JsonVariant variant = doc1.to<JsonVariant>(); JsonVariant variant = doc1.to<JsonVariant>();
SECTION("JsonVariant::shallowCopy(JsonDocument&)") { SECTION("JsonVariant::shallowCopy(JsonDocument&)") {

View File

@ -69,13 +69,13 @@ TEST_CASE("vector<int>") {
SECTION("toJson") { SECTION("toJson") {
std::vector<int> v = {1, 2}; std::vector<int> v = {1, 2};
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
doc.set(v); doc.set(v);
REQUIRE(doc.as<std::string>() == "[1,2]"); REQUIRE(doc.as<std::string>() == "[1,2]");
} }
SECTION("fromJson") { SECTION("fromJson") {
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
doc.add(1); doc.add(1);
doc.add(2); doc.add(2);
@ -86,7 +86,7 @@ TEST_CASE("vector<int>") {
} }
SECTION("checkJson") { SECTION("checkJson") {
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
CHECK(doc.is<std::vector<int>>() == false); CHECK(doc.is<std::vector<int>>() == false);
doc.add(1); doc.add(1);
@ -106,13 +106,13 @@ TEST_CASE("array<int, 2>") {
v[0] = 1; v[0] = 1;
v[1] = 2; v[1] = 2;
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
doc.set(v); doc.set(v);
REQUIRE(doc.as<std::string>() == "[1,2]"); REQUIRE(doc.as<std::string>() == "[1,2]");
} }
SECTION("fromJson") { SECTION("fromJson") {
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
doc.add(1); doc.add(1);
doc.add(2); doc.add(2);
@ -123,7 +123,7 @@ TEST_CASE("array<int, 2>") {
} }
SECTION("checkJson") { SECTION("checkJson") {
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
CHECK(doc.is<array_type>() == false); CHECK(doc.is<array_type>() == false);
doc.add(1); doc.add(1);

View File

@ -136,7 +136,7 @@ TEST_CASE("Writer<custom_string>") {
} }
TEST_CASE("serializeJson(doc, String)") { TEST_CASE("serializeJson(doc, String)") {
StaticJsonDocument<1024> doc; DynamicJsonDocument doc(1024);
doc["hello"] = "world"; doc["hello"] = "world";
::String output; ::String output;

View File

@ -194,8 +194,6 @@ TEST_CASE("Polyfills/type_traits") {
JsonVariantConst>::value == true); JsonVariantConst>::value == true);
CHECK(is_convertible<JsonObjectConst, JsonVariantConst>::value == true); CHECK(is_convertible<JsonObjectConst, JsonVariantConst>::value == true);
CHECK(is_convertible<DynamicJsonDocument, JsonVariantConst>::value == true); CHECK(is_convertible<DynamicJsonDocument, JsonVariantConst>::value == true);
CHECK(is_convertible<StaticJsonDocument<10>, JsonVariantConst>::value ==
true);
} }
SECTION("is_class") { SECTION("is_class") {

View File

@ -48,7 +48,7 @@ struct PrintableString : public Printable {
TEST_CASE("Printable") { TEST_CASE("Printable") {
SECTION("Doesn't overflow") { SECTION("Doesn't overflow") {
StaticJsonDocument<8> doc; DynamicJsonDocument doc(8);
const char* value = "example"; // == 7 chars const char* value = "example"; // == 7 chars
doc.set(666); // to make sure we override the value doc.set(666); // to make sure we override the value
@ -75,7 +75,7 @@ TEST_CASE("Printable") {
} }
SECTION("Overflows early") { SECTION("Overflows early") {
StaticJsonDocument<8> doc; DynamicJsonDocument doc(8);
const char* value = "hello world"; // > 8 chars const char* value = "hello world"; // > 8 chars
doc.set(666); // to make sure we override the value doc.set(666); // to make sure we override the value
@ -100,7 +100,7 @@ TEST_CASE("Printable") {
} }
SECTION("Overflows adding terminator") { SECTION("Overflows adding terminator") {
StaticJsonDocument<8> doc; DynamicJsonDocument doc(8);
const char* value = "overflow"; // == 8 chars const char* value = "overflow"; // == 8 chars
doc.set(666); // to make sure we override the value doc.set(666); // to make sure we override the value
@ -133,7 +133,7 @@ TEST_CASE("Printable") {
} }
SECTION("String deduplication") { SECTION("String deduplication") {
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
doc.add(PrintableString<PrintOneCharacterAtATime>("Hello World!")); doc.add(PrintableString<PrintOneCharacterAtATime>("Hello World!"));
doc.add(PrintableString<PrintAllAtOnce>("Hello World!")); doc.add(PrintableString<PrintAllAtOnce>("Hello World!"));
REQUIRE(doc.size() == 2); REQUIRE(doc.size() == 2);

View File

@ -13,7 +13,7 @@ TEST_CASE("unsigned char[]") {
SECTION("deserializeJson()") { SECTION("deserializeJson()") {
unsigned char input[] = "{\"a\":42}"; unsigned char input[] = "{\"a\":42}";
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(1));
DeserializationError err = deserializeJson(doc, input); DeserializationError err = deserializeJson(doc, input);
REQUIRE(err == DeserializationError::Ok); REQUIRE(err == DeserializationError::Ok);
@ -22,7 +22,7 @@ TEST_CASE("unsigned char[]") {
SECTION("deserializeMsgPack()") { SECTION("deserializeMsgPack()") {
unsigned char input[] = "\xDE\x00\x01\xA5Hello\xA5world"; unsigned char input[] = "\xDE\x00\x01\xA5Hello\xA5world";
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(2));
DeserializationError err = deserializeMsgPack(doc, input); DeserializationError err = deserializeMsgPack(doc, input);
REQUIRE(err == DeserializationError::Ok); REQUIRE(err == DeserializationError::Ok);
@ -30,7 +30,7 @@ TEST_CASE("unsigned char[]") {
SECTION("serializeMsgPack(unsigned char[])") { SECTION("serializeMsgPack(unsigned char[])") {
unsigned char buffer[32]; unsigned char buffer[32];
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(2));
doc["hello"] = "world"; doc["hello"] = "world";
size_t n = serializeMsgPack(doc, buffer); size_t n = serializeMsgPack(doc, buffer);
@ -41,7 +41,7 @@ TEST_CASE("unsigned char[]") {
SECTION("serializeMsgPack(unsigned char*)") { SECTION("serializeMsgPack(unsigned char*)") {
unsigned char buffer[32]; unsigned char buffer[32];
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(2));
doc["hello"] = "world"; doc["hello"] = "world";
size_t n = serializeMsgPack(doc, buffer, sizeof(buffer)); size_t n = serializeMsgPack(doc, buffer, sizeof(buffer));
@ -52,7 +52,7 @@ TEST_CASE("unsigned char[]") {
SECTION("serializeJson(unsigned char[])") { SECTION("serializeJson(unsigned char[])") {
unsigned char buffer[32]; unsigned char buffer[32];
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(2));
doc["hello"] = "world"; doc["hello"] = "world";
size_t n = serializeJson(doc, buffer); size_t n = serializeJson(doc, buffer);
@ -63,7 +63,7 @@ TEST_CASE("unsigned char[]") {
SECTION("serializeJson(unsigned char*)") { SECTION("serializeJson(unsigned char*)") {
unsigned char buffer[32]; unsigned char buffer[32];
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(2));
doc["hello"] = "world"; doc["hello"] = "world";
size_t n = serializeJson(doc, buffer, sizeof(buffer)); size_t n = serializeJson(doc, buffer, sizeof(buffer));
@ -74,7 +74,7 @@ TEST_CASE("unsigned char[]") {
SECTION("serializeJsonPretty(unsigned char[])") { SECTION("serializeJsonPretty(unsigned char[])") {
unsigned char buffer[32]; unsigned char buffer[32];
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(2));
doc["hello"] = "world"; doc["hello"] = "world";
size_t n = serializeJsonPretty(doc, buffer); size_t n = serializeJsonPretty(doc, buffer);
@ -84,7 +84,7 @@ TEST_CASE("unsigned char[]") {
SECTION("serializeJsonPretty(unsigned char*)") { SECTION("serializeJsonPretty(unsigned char*)") {
unsigned char buffer[32]; unsigned char buffer[32];
StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(2));
doc["hello"] = "world"; doc["hello"] = "world";
size_t n = serializeJsonPretty(doc, buffer, sizeof(buffer)); size_t n = serializeJsonPretty(doc, buffer, sizeof(buffer));

View File

@ -12,7 +12,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 0") { TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 0") {
StaticJsonDocument<1024> doc; DynamicJsonDocument doc(1024);
SECTION("deserializeJson()") { SECTION("deserializeJson()") {
SECTION("Deduplicate values") { SECTION("Deduplicate values") {

View File

@ -12,7 +12,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 1") { TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 1") {
StaticJsonDocument<1024> doc; DynamicJsonDocument doc(1024);
SECTION("deserializeJson()") { SECTION("deserializeJson()") {
SECTION("Deduplicate values") { SECTION("Deduplicate values") {

View File

@ -12,7 +12,7 @@
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("Issue1707") { TEST_CASE("Issue1707") {
StaticJsonDocument<128> doc; DynamicJsonDocument doc(128);
DeserializationError err = deserializeJson(doc, F("{\"hello\":12}")); DeserializationError err = deserializeJson(doc, F("{\"hello\":12}"));
REQUIRE(err == DeserializationError::Ok); REQUIRE(err == DeserializationError::Ok);

View File

@ -5,7 +5,6 @@
add_executable(MsgPackDeserializerTests add_executable(MsgPackDeserializerTests
deserializeArray.cpp deserializeArray.cpp
deserializeObject.cpp deserializeObject.cpp
deserializeStaticVariant.cpp
deserializeVariant.cpp deserializeVariant.cpp
doubleToFloat.cpp doubleToFloat.cpp
filter.cpp filter.cpp

View File

@ -1,152 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
template <size_t Capacity>
static void check(const char* input, DeserializationError expected) {
StaticJsonDocument<Capacity> doc;
DeserializationError error = deserializeMsgPack(doc, input);
CAPTURE(input);
REQUIRE(error == expected);
}
template <size_t Size>
static void checkString(const char* input, DeserializationError expected) {
check<Size>(input, expected);
}
TEST_CASE("deserializeMsgPack(StaticJsonDocument&)") {
SECTION("single values always fit") {
check<0>("\xc0", DeserializationError::Ok); // nil
check<0>("\xc2", DeserializationError::Ok); // false
check<0>("\xc3", DeserializationError::Ok); // true
check<0>("\xcc\x00", DeserializationError::Ok); // uint 8
check<0>("\xcd\x30\x39", DeserializationError::Ok); // uint 16
check<0>("\xCE\x12\x34\x56\x78", DeserializationError::Ok); // uint 32
}
SECTION("fixstr") {
checkString<8>("\xA0", DeserializationError::Ok);
checkString<8>("\xA7ZZZZZZZ", DeserializationError::Ok);
checkString<8>("\xA8ZZZZZZZZ", DeserializationError::NoMemory);
checkString<16>("\xAFZZZZZZZZZZZZZZZ", DeserializationError::Ok);
checkString<16>("\xB0ZZZZZZZZZZZZZZZZ", DeserializationError::NoMemory);
}
SECTION("str 8") {
checkString<8>("\xD9\x00", DeserializationError::Ok);
checkString<8>("\xD9\x07ZZZZZZZ", DeserializationError::Ok);
checkString<8>("\xD9\x08ZZZZZZZZ", DeserializationError::NoMemory);
checkString<16>("\xD9\x0FZZZZZZZZZZZZZZZ", DeserializationError::Ok);
checkString<16>("\xD9\x10ZZZZZZZZZZZZZZZZ", DeserializationError::NoMemory);
}
SECTION("str 16") {
checkString<8>("\xDA\x00\x00", DeserializationError::Ok);
checkString<8>("\xDA\x00\x07ZZZZZZZ", DeserializationError::Ok);
checkString<8>("\xDA\x00\x08ZZZZZZZZ", DeserializationError::NoMemory);
checkString<16>("\xDA\x00\x0FZZZZZZZZZZZZZZZ", DeserializationError::Ok);
checkString<16>("\xDA\x00\x10ZZZZZZZZZZZZZZZZ",
DeserializationError::NoMemory);
}
SECTION("str 32") {
checkString<8>("\xDB\x00\x00\x00\x00", DeserializationError::Ok);
checkString<8>("\xDB\x00\x00\x00\x07ZZZZZZZ", DeserializationError::Ok);
checkString<8>("\xDB\x00\x00\x00\x08ZZZZZZZZ",
DeserializationError::NoMemory);
checkString<16>("\xDB\x00\x00\x00\x0FZZZZZZZZZZZZZZZ",
DeserializationError::Ok);
checkString<16>("\xDB\x00\x00\x00\x10ZZZZZZZZZZZZZZZZ",
DeserializationError::NoMemory);
}
SECTION("fixarray") {
check<JSON_ARRAY_SIZE(0)>("\x90", DeserializationError::Ok); // []
check<JSON_ARRAY_SIZE(0)>("\x91\x01",
DeserializationError::NoMemory); // [1]
check<JSON_ARRAY_SIZE(1)>("\x91\x01", DeserializationError::Ok); // [1]
check<JSON_ARRAY_SIZE(1)>("\x92\x01\x02",
DeserializationError::NoMemory); // [1,2]
}
SECTION("array 16") {
check<JSON_ARRAY_SIZE(0)>("\xDC\x00\x00", DeserializationError::Ok);
check<JSON_ARRAY_SIZE(0)>("\xDC\x00\x01\x01",
DeserializationError::NoMemory);
check<JSON_ARRAY_SIZE(1)>("\xDC\x00\x01\x01", DeserializationError::Ok);
check<JSON_ARRAY_SIZE(1)>("\xDC\x00\x02\x01\x02",
DeserializationError::NoMemory);
}
SECTION("array 32") {
check<JSON_ARRAY_SIZE(0)>("\xDD\x00\x00\x00\x00", DeserializationError::Ok);
check<JSON_ARRAY_SIZE(0)>("\xDD\x00\x00\x00\x01\x01",
DeserializationError::NoMemory);
check<JSON_ARRAY_SIZE(1)>("\xDD\x00\x00\x00\x01\x01",
DeserializationError::Ok);
check<JSON_ARRAY_SIZE(1)>("\xDD\x00\x00\x00\x02\x01\x02",
DeserializationError::NoMemory);
}
SECTION("fixmap") {
SECTION("{}") {
check<JSON_OBJECT_SIZE(0)>("\x80", DeserializationError::Ok);
}
SECTION("{H:1}") {
check<JSON_OBJECT_SIZE(0)>("\x81\xA1H\x01",
DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2)>(
"\x81\xA1H\x01", DeserializationError::Ok);
}
SECTION("{H:1,W:2}") {
check<JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2)>(
"\x82\xA1H\x01\xA1W\x02", DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(2) + 2 * JSON_STRING_SIZE(2)>(
"\x82\xA1H\x01\xA1W\x02", DeserializationError::Ok);
}
}
SECTION("map 16") {
SECTION("{}") {
check<JSON_OBJECT_SIZE(0)>("\xDE\x00\x00", DeserializationError::Ok);
}
SECTION("{H:1}") {
check<JSON_OBJECT_SIZE(0)>("\xDE\x00\x01\xA1H\x01",
DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2)>(
"\xDE\x00\x01\xA1H\x01", DeserializationError::Ok);
}
SECTION("{H:1,W:2}") {
check<JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2)>(
"\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(2) + 2 * JSON_OBJECT_SIZE(1)>(
"\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok);
}
}
SECTION("map 32") {
SECTION("{}") {
check<JSON_OBJECT_SIZE(0)>("\xDF\x00\x00\x00\x00",
DeserializationError::Ok);
}
SECTION("{H:1}") {
check<JSON_OBJECT_SIZE(0)>("\xDF\x00\x00\x00\x01\xA1H\x01",
DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2)>(
"\xDF\x00\x00\x00\x01\xA1H\x01", DeserializationError::Ok);
}
SECTION("{H:1,W:2}") {
check<JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2)>(
"\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
DeserializationError::NoMemory);
check<JSON_OBJECT_SIZE(2) + 2 * JSON_OBJECT_SIZE(1)>(
"\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok);
}
}
}

View File

@ -5,8 +5,8 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>
template <typename T, typename U> template <typename T>
static void check(const char* input, U expected) { static void checkValue(const char* input, T expected) {
DynamicJsonDocument doc(4096); DynamicJsonDocument doc(4096);
DeserializationError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
@ -16,132 +16,260 @@ static void check(const char* input, U expected) {
REQUIRE(doc.as<T>() == expected); REQUIRE(doc.as<T>() == expected);
} }
#if ARDUINOJSON_USE_LONG_LONG == 0 static void checkError(size_t capacity, const char* input,
static void checkNotSupported(const char* input) { DeserializationError expected) {
DynamicJsonDocument doc(4096); DynamicJsonDocument doc(capacity);
DeserializationError error = deserializeMsgPack(doc, input);
REQUIRE(error == DeserializationError::Ok);
REQUIRE(doc.isNull());
}
#endif
static void checkIsNull(const char* input) {
DynamicJsonDocument doc(4096);
DeserializationError error = deserializeMsgPack(doc, input); DeserializationError error = deserializeMsgPack(doc, input);
REQUIRE(error == DeserializationError::Ok); CAPTURE(input);
REQUIRE(doc.as<JsonVariant>().isNull()); REQUIRE(error == expected);
} }
TEST_CASE("deserialize MsgPack value") { TEST_CASE("deserialize MsgPack value") {
SECTION("nil") { SECTION("nil") {
checkIsNull("\xc0"); checkValue("\xc0", nullptr);
} }
SECTION("bool") { SECTION("bool") {
check<bool>("\xc2", false); checkValue<bool>("\xc2", false);
check<bool>("\xc3", true); checkValue<bool>("\xc3", true);
} }
SECTION("positive fixint") { SECTION("positive fixint") {
check<int>("\x00", 0); checkValue<int>("\x00", 0);
check<int>("\x7F", 127); checkValue<int>("\x7F", 127);
} }
SECTION("negative fixint") { SECTION("negative fixint") {
check<int>("\xe0", -32); checkValue<int>("\xe0", -32);
check<int>("\xff", -1); checkValue<int>("\xff", -1);
} }
SECTION("uint 8") { SECTION("uint 8") {
check<int>("\xcc\x00", 0); checkValue<int>("\xcc\x00", 0);
check<int>("\xcc\xff", 255); checkValue<int>("\xcc\xff", 255);
} }
SECTION("uint 16") { SECTION("uint 16") {
check<int>("\xcd\x00\x00", 0); checkValue<int>("\xcd\x00\x00", 0);
check<int>("\xcd\xFF\xFF", 65535); checkValue<int>("\xcd\xFF\xFF", 65535);
check<int>("\xcd\x30\x39", 12345); checkValue<int>("\xcd\x30\x39", 12345);
} }
SECTION("uint 32") { SECTION("uint 32") {
check<uint32_t>("\xCE\x00\x00\x00\x00", 0x00000000U); checkValue<uint32_t>("\xCE\x00\x00\x00\x00", 0x00000000U);
check<uint32_t>("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU); checkValue<uint32_t>("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU);
check<uint32_t>("\xCE\x12\x34\x56\x78", 0x12345678U); checkValue<uint32_t>("\xCE\x12\x34\x56\x78", 0x12345678U);
} }
SECTION("uint 64") { SECTION("uint 64") {
#if ARDUINOJSON_USE_LONG_LONG #if ARDUINOJSON_USE_LONG_LONG
check<uint64_t>("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U); checkValue<uint64_t>("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U);
check<uint64_t>("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", checkValue<uint64_t>("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
0xFFFFFFFFFFFFFFFFU); 0xFFFFFFFFFFFFFFFFU);
check<uint64_t>("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", checkValue<uint64_t>("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
0x123456789ABCDEF0U); 0x123456789ABCDEF0U);
#else #else
checkNotSupported("\xCF\x00\x00\x00\x00\x00\x00\x00\x00"); checkValue("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", nullptr);
checkNotSupported("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); checkValue("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr);
checkNotSupported("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0"); checkValue("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr);
#endif #endif
} }
SECTION("int 8") { SECTION("int 8") {
check<int>("\xd0\x00", 0); checkValue<int>("\xd0\x00", 0);
check<int>("\xd0\xff", -1); checkValue<int>("\xd0\xff", -1);
} }
SECTION("int 16") { SECTION("int 16") {
check<int>("\xD1\x00\x00", 0); checkValue<int>("\xD1\x00\x00", 0);
check<int>("\xD1\xFF\xFF", -1); checkValue<int>("\xD1\xFF\xFF", -1);
check<int>("\xD1\xCF\xC7", -12345); checkValue<int>("\xD1\xCF\xC7", -12345);
} }
SECTION("int 32") { SECTION("int 32") {
check<int>("\xD2\x00\x00\x00\x00", 0); checkValue<int>("\xD2\x00\x00\x00\x00", 0);
check<int>("\xD2\xFF\xFF\xFF\xFF", -1); checkValue<int>("\xD2\xFF\xFF\xFF\xFF", -1);
check<int>("\xD2\xB6\x69\xFD\x2E", -1234567890); checkValue<int>("\xD2\xB6\x69\xFD\x2E", -1234567890);
} }
SECTION("int 64") { SECTION("int 64") {
#if ARDUINOJSON_USE_LONG_LONG #if ARDUINOJSON_USE_LONG_LONG
check<int64_t>("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", int64_t(0U)); checkValue<int64_t>("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", int64_t(0U));
check<int64_t>("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", checkValue<int64_t>("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
int64_t(0xFFFFFFFFFFFFFFFFU)); int64_t(0xFFFFFFFFFFFFFFFFU));
check<int64_t>("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", checkValue<int64_t>("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
int64_t(0x123456789ABCDEF0)); int64_t(0x123456789ABCDEF0));
#else #else
checkNotSupported("\xD3\x00\x00\x00\x00\x00\x00\x00\x00"); checkValue("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", nullptr);
checkNotSupported("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); checkValue("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr);
checkNotSupported("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0"); checkValue("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr);
#endif #endif
} }
SECTION("float 32") { SECTION("float 32") {
check<double>("\xCA\x00\x00\x00\x00", 0.0f); checkValue<double>("\xCA\x00\x00\x00\x00", 0.0f);
check<double>("\xCA\x40\x48\xF5\xC3", 3.14f); checkValue<double>("\xCA\x40\x48\xF5\xC3", 3.14f);
} }
SECTION("float 64") { SECTION("float 64") {
check<double>("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0); checkValue<double>("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0);
check<double>("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415); checkValue<double>("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415);
} }
SECTION("fixstr") { SECTION("fixstr") {
check<const char*>("\xA0", std::string("")); checkValue<std::string>("\xA0", std::string(""));
check<const char*>("\xABhello world", std::string("hello world")); checkValue<std::string>("\xABhello world", std::string("hello world"));
check<const char*>("\xBFhello world hello world hello !", checkValue<std::string>("\xBFhello world hello world hello !",
std::string("hello world hello world hello !")); std::string("hello world hello world hello !"));
} }
SECTION("str 8") { SECTION("str 8") {
check<const char*>("\xd9\x05hello", std::string("hello")); checkValue<std::string>("\xd9\x05hello", std::string("hello"));
} }
SECTION("str 16") { SECTION("str 16") {
check<const char*>("\xda\x00\x05hello", std::string("hello")); checkValue<std::string>("\xda\x00\x05hello", std::string("hello"));
} }
SECTION("str 32") { SECTION("str 32") {
check<const char*>("\xdb\x00\x00\x00\x05hello", std::string("hello")); checkValue<std::string>("\xdb\x00\x00\x00\x05hello", std::string("hello"));
}
}
TEST_CASE("deserializeMsgPack() under memory constaints") {
SECTION("single values always fit") {
checkError(0, "\xc0", DeserializationError::Ok); // nil
checkError(0, "\xc2", DeserializationError::Ok); // false
checkError(0, "\xc3", DeserializationError::Ok); // true
checkError(0, "\xcc\x00", DeserializationError::Ok); // uint 8
checkError(0, "\xcd\x30\x39", DeserializationError::Ok); // uint 16
checkError(0, "\xCE\x12\x34\x56\x78", DeserializationError::Ok); // uint 32
}
SECTION("fixstr") {
checkError(8, "\xA0", DeserializationError::Ok);
checkError(8, "\xA7ZZZZZZZ", DeserializationError::Ok);
checkError(8, "\xA8ZZZZZZZZ", DeserializationError::NoMemory);
checkError(16, "\xAFZZZZZZZZZZZZZZZ", DeserializationError::Ok);
checkError(16, "\xB0ZZZZZZZZZZZZZZZZ", DeserializationError::NoMemory);
}
SECTION("str 8") {
checkError(8, "\xD9\x00", DeserializationError::Ok);
checkError(8, "\xD9\x07ZZZZZZZ", DeserializationError::Ok);
checkError(8, "\xD9\x08ZZZZZZZZ", DeserializationError::NoMemory);
checkError(16, "\xD9\x0FZZZZZZZZZZZZZZZ", DeserializationError::Ok);
checkError(16, "\xD9\x10ZZZZZZZZZZZZZZZZ", DeserializationError::NoMemory);
}
SECTION("str 16") {
checkError(8, "\xDA\x00\x00", DeserializationError::Ok);
checkError(8, "\xDA\x00\x07ZZZZZZZ", DeserializationError::Ok);
checkError(8, "\xDA\x00\x08ZZZZZZZZ", DeserializationError::NoMemory);
checkError(16, "\xDA\x00\x0FZZZZZZZZZZZZZZZ", DeserializationError::Ok);
checkError(16, "\xDA\x00\x10ZZZZZZZZZZZZZZZZ",
DeserializationError::NoMemory);
}
SECTION("str 32") {
checkError(8, "\xDB\x00\x00\x00\x00", DeserializationError::Ok);
checkError(8, "\xDB\x00\x00\x00\x07ZZZZZZZ", DeserializationError::Ok);
checkError(8, "\xDB\x00\x00\x00\x08ZZZZZZZZ",
DeserializationError::NoMemory);
checkError(16, "\xDB\x00\x00\x00\x0FZZZZZZZZZZZZZZZ",
DeserializationError::Ok);
checkError(16, "\xDB\x00\x00\x00\x10ZZZZZZZZZZZZZZZZ",
DeserializationError::NoMemory);
}
SECTION("fixarray") {
checkError(JSON_ARRAY_SIZE(0), "\x90", DeserializationError::Ok); // []
checkError(JSON_ARRAY_SIZE(0), "\x91\x01",
DeserializationError::NoMemory); // [1]
checkError(JSON_ARRAY_SIZE(1), "\x91\x01",
DeserializationError::Ok); // [1]
checkError(JSON_ARRAY_SIZE(1), "\x92\x01\x02",
DeserializationError::NoMemory); // [1,2]
}
SECTION("array 16") {
checkError(JSON_ARRAY_SIZE(0), "\xDC\x00\x00", DeserializationError::Ok);
checkError(JSON_ARRAY_SIZE(0), "\xDC\x00\x01\x01",
DeserializationError::NoMemory);
checkError(JSON_ARRAY_SIZE(1), "\xDC\x00\x01\x01",
DeserializationError::Ok);
checkError(JSON_ARRAY_SIZE(1), "\xDC\x00\x02\x01\x02",
DeserializationError::NoMemory);
}
SECTION("array 32") {
checkError(JSON_ARRAY_SIZE(0), "\xDD\x00\x00\x00\x00",
DeserializationError::Ok);
checkError(JSON_ARRAY_SIZE(0), "\xDD\x00\x00\x00\x01\x01",
DeserializationError::NoMemory);
checkError(JSON_ARRAY_SIZE(1), "\xDD\x00\x00\x00\x01\x01",
DeserializationError::Ok);
checkError(JSON_ARRAY_SIZE(1), "\xDD\x00\x00\x00\x02\x01\x02",
DeserializationError::NoMemory);
}
SECTION("fixmap") {
SECTION("{}") {
checkError(JSON_OBJECT_SIZE(0), "\x80", DeserializationError::Ok);
}
SECTION("{H:1}") {
checkError(JSON_OBJECT_SIZE(0), "\x81\xA1H\x01",
DeserializationError::NoMemory);
checkError(JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2), "\x81\xA1H\x01",
DeserializationError::Ok);
}
SECTION("{H:1,W:2}") {
checkError(JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2),
"\x82\xA1H\x01\xA1W\x02", DeserializationError::NoMemory);
checkError(JSON_OBJECT_SIZE(2) + 2 * JSON_STRING_SIZE(2),
"\x82\xA1H\x01\xA1W\x02", DeserializationError::Ok);
}
}
SECTION("map 16") {
SECTION("{}") {
checkError(JSON_OBJECT_SIZE(0), "\xDE\x00\x00", DeserializationError::Ok);
}
SECTION("{H:1}") {
checkError(JSON_OBJECT_SIZE(0), "\xDE\x00\x01\xA1H\x01",
DeserializationError::NoMemory);
checkError(JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2),
"\xDE\x00\x01\xA1H\x01", DeserializationError::Ok);
}
SECTION("{H:1,W:2}") {
checkError(JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2),
"\xDE\x00\x02\xA1H\x01\xA1W\x02",
DeserializationError::NoMemory);
checkError(JSON_OBJECT_SIZE(2) + 2 * JSON_OBJECT_SIZE(1),
"\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok);
}
}
SECTION("map 32") {
SECTION("{}") {
checkError(JSON_OBJECT_SIZE(0), "\xDF\x00\x00\x00\x00",
DeserializationError::Ok);
}
SECTION("{H:1}") {
checkError(JSON_OBJECT_SIZE(0), "\xDF\x00\x00\x00\x01\xA1H\x01",
DeserializationError::NoMemory);
checkError(JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2),
"\xDF\x00\x00\x00\x01\xA1H\x01", DeserializationError::Ok);
}
SECTION("{H:1,W:2}") {
checkError(JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(2),
"\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
DeserializationError::NoMemory);
checkError(JSON_OBJECT_SIZE(2) + 2 * JSON_OBJECT_SIZE(1),
"\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
DeserializationError::Ok);
}
} }
} }

View File

@ -10,10 +10,10 @@
using namespace ArduinoJson::detail; using namespace ArduinoJson::detail;
TEST_CASE("deserializeMsgPack() filter") { TEST_CASE("deserializeMsgPack() filter") {
StaticJsonDocument<4096> doc; DynamicJsonDocument doc(4096);
DeserializationError error; DeserializationError error;
StaticJsonDocument<200> filter; DynamicJsonDocument filter(200);
DeserializationOption::Filter filterOpt(filter); DeserializationOption::Filter filterOpt(filter);
SECTION("root is fixmap") { SECTION("root is fixmap") {
@ -1032,10 +1032,10 @@ TEST_CASE("deserializeMsgPack() filter") {
TEST_CASE("Zero-copy mode") { // issue #1697 TEST_CASE("Zero-copy mode") { // issue #1697
char input[] = "\x82\xA7include\x01\xA6ignore\x02"; char input[] = "\x82\xA7include\x01\xA6ignore\x02";
StaticJsonDocument<256> filter; DynamicJsonDocument filter(256);
filter["include"] = true; filter["include"] = true;
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
DeserializationError err = DeserializationError err =
deserializeMsgPack(doc, input, 18, DeserializationOption::Filter(filter)); deserializeMsgPack(doc, input, 18, DeserializationOption::Filter(filter));
@ -1044,8 +1044,8 @@ TEST_CASE("Zero-copy mode") { // issue #1697
} }
TEST_CASE("Overloads") { TEST_CASE("Overloads") {
StaticJsonDocument<256> doc; DynamicJsonDocument doc(256);
StaticJsonDocument<256> filter; DynamicJsonDocument filter(256);
using namespace DeserializationOption; using namespace DeserializationOption;

View File

@ -76,7 +76,7 @@ TEST_CASE("deserializeMsgPack(VLA)") {
char vla[i]; char vla[i];
memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15); memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15);
StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; DynamicJsonDocument doc(JSON_OBJECT_SIZE(1));
DeserializationError err = deserializeMsgPack(doc, vla); DeserializationError err = deserializeMsgPack(doc, vla);
REQUIRE(err == DeserializationError::Ok); REQUIRE(err == DeserializationError::Ok);

View File

@ -8,7 +8,7 @@
#include <sstream> #include <sstream>
TEST_CASE("deserializeMsgPack() returns EmptyInput") { TEST_CASE("deserializeMsgPack() returns EmptyInput") {
StaticJsonDocument<100> doc; DynamicJsonDocument doc(100);
SECTION("from sized buffer") { SECTION("from sized buffer") {
DeserializationError err = deserializeMsgPack(doc, "", 0); DeserializationError err = deserializeMsgPack(doc, "", 0);

View File

@ -37,4 +37,3 @@ JsonString KEYWORD1 DATA_TYPE
JsonUInt KEYWORD1 DATA_TYPE JsonUInt KEYWORD1 DATA_TYPE
JsonVariant KEYWORD1 DATA_TYPE JsonVariant KEYWORD1 DATA_TYPE
JsonVariantConst KEYWORD1 DATA_TYPE JsonVariantConst KEYWORD1 DATA_TYPE
StaticJsonDocument KEYWORD1 DATA_TYPE

View File

@ -30,7 +30,6 @@
#include "ArduinoJson/Variant/JsonVariantConst.hpp" #include "ArduinoJson/Variant/JsonVariantConst.hpp"
#include "ArduinoJson/Document/DynamicJsonDocument.hpp" #include "ArduinoJson/Document/DynamicJsonDocument.hpp"
#include "ArduinoJson/Document/StaticJsonDocument.hpp"
#include "ArduinoJson/Array/ElementProxy.hpp" #include "ArduinoJson/Array/ElementProxy.hpp"
#include "ArduinoJson/Array/JsonArrayImpl.hpp" #include "ArduinoJson/Array/JsonArrayImpl.hpp"

View File

@ -1,61 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#pragma once
#include <ArduinoJson/Document/JsonDocument.hpp>
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
// A JsonDocument with a memory pool on the stack.
template <size_t desiredCapacity>
class StaticJsonDocument : public JsonDocument {
static const size_t _capacity =
detail::AddPadding<detail::Max<1, desiredCapacity>::value>::value;
public:
StaticJsonDocument() : JsonDocument(_buffer, _capacity) {}
StaticJsonDocument(const StaticJsonDocument& src)
: JsonDocument(_buffer, _capacity) {
set(src);
}
template <typename T>
StaticJsonDocument(
const T& src,
typename detail::enable_if<
detail::is_convertible<T, JsonVariantConst>::value>::type* = 0)
: JsonDocument(_buffer, _capacity) {
set(src);
}
// disambiguate
StaticJsonDocument(JsonVariant src) : JsonDocument(_buffer, _capacity) {
set(src);
}
StaticJsonDocument& operator=(const StaticJsonDocument& src) {
set(src);
return *this;
}
template <typename T>
StaticJsonDocument& operator=(const T& src) {
set(src);
return *this;
}
// Reclaims the memory leaked when removing and replacing values.
// https://arduinojson.org/v6/api/jsondocument/garbagecollect/
void garbageCollect() {
StaticJsonDocument tmp(*this);
set(tmp);
}
private:
char _buffer[_capacity];
};
ARDUINOJSON_END_PUBLIC_NAMESPACE