From 17a482a9b184d712269ad858496ac199aba2735d Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Wed, 15 Mar 2023 14:54:55 +0100 Subject: [PATCH] Remove `StaticJsonDocument` --- .github/workflows/ci.yml | 4 +- CHANGELOG.md | 831 +----------------- README.md | 1 - examples/JsonConfigFile/JsonConfigFile.ino | 15 +- .../JsonFilterExample/JsonFilterExample.ino | 7 +- .../JsonGeneratorExample.ino | 12 +- .../JsonParserExample/JsonParserExample.ino | 12 +- examples/JsonServer/JsonServer.ino | 8 +- examples/JsonUdpBeacon/JsonUdpBeacon.ino | 5 +- examples/MsgPackParser/MsgPackParser.ino | 12 +- extras/ci/espidf/main/main.cpp | 2 +- .../scripts/wandbox/JsonGeneratorExample.cpp | 14 +- extras/scripts/wandbox/JsonParserExample.cpp | 9 +- .../scripts/wandbox/MsgPackParserExample.cpp | 9 +- extras/tests/Cpp17/string_view.cpp | 2 +- extras/tests/Cpp20/smoke_test.cpp | 2 +- .../tests/IntegrationTests/openweathermap.cpp | 2 +- extras/tests/JsonArray/clear.cpp | 2 +- extras/tests/JsonArray/compare.cpp | 12 +- extras/tests/JsonArray/copyArray.cpp | 4 +- extras/tests/JsonArray/iterator.cpp | 2 +- extras/tests/JsonDeserializer/CMakeLists.txt | 2 - extras/tests/JsonDeserializer/array.cpp | 83 ++ .../tests/JsonDeserializer/array_static.cpp | 89 -- extras/tests/JsonDeserializer/filter.cpp | 8 +- extras/tests/JsonDeserializer/input_types.cpp | 4 +- extras/tests/JsonDeserializer/object.cpp | 58 ++ .../tests/JsonDeserializer/object_static.cpp | 64 -- extras/tests/JsonDeserializer/string.cpp | 2 +- extras/tests/JsonDocument/CMakeLists.txt | 1 - .../JsonDocument/DynamicJsonDocument.cpp | 37 +- extras/tests/JsonDocument/ElementProxy.cpp | 2 +- extras/tests/JsonDocument/MemberProxy.cpp | 12 +- .../tests/JsonDocument/StaticJsonDocument.cpp | 224 ----- extras/tests/JsonDocument/cast.cpp | 2 +- extras/tests/JsonDocument/compare.cpp | 52 +- extras/tests/JsonDocument/issue1120.cpp | 2 +- extras/tests/JsonDocument/overflowed.cpp | 18 +- extras/tests/JsonObject/clear.cpp | 2 +- extras/tests/JsonObject/compare.cpp | 12 +- extras/tests/JsonObject/copy.cpp | 4 +- extras/tests/JsonObject/iterator.cpp | 4 +- extras/tests/JsonSerializer/JsonArray.cpp | 2 +- extras/tests/JsonSerializer/std_string.cpp | 2 +- extras/tests/JsonVariant/compare.cpp | 4 +- extras/tests/JsonVariant/isnull.cpp | 4 +- extras/tests/JsonVariant/overflow.cpp | 4 +- extras/tests/JsonVariant/set.cpp | 2 +- extras/tests/JsonVariant/shallowCopy.cpp | 2 +- extras/tests/JsonVariant/stl_containers.cpp | 12 +- extras/tests/Misc/StringWriter.cpp | 2 +- extras/tests/Misc/TypeTraits.cpp | 2 - extras/tests/Misc/printable.cpp | 8 +- extras/tests/Misc/unsigned_char.cpp | 16 +- .../enable_string_deduplication_0.cpp | 2 +- .../enable_string_deduplication_1.cpp | 2 +- extras/tests/MixedConfiguration/issue1707.cpp | 2 +- .../tests/MsgPackDeserializer/CMakeLists.txt | 1 - .../deserializeStaticVariant.cpp | 152 ---- .../deserializeVariant.cpp | 258 ++++-- extras/tests/MsgPackDeserializer/filter.cpp | 12 +- .../tests/MsgPackDeserializer/input_types.cpp | 2 +- extras/tests/MsgPackDeserializer/misc.cpp | 2 +- keywords.txt | 1 - src/ArduinoJson.hpp | 1 - .../Document/StaticJsonDocument.hpp | 61 -- 66 files changed, 477 insertions(+), 1728 deletions(-) delete mode 100644 extras/tests/JsonDeserializer/array_static.cpp delete mode 100644 extras/tests/JsonDeserializer/object_static.cpp delete mode 100644 extras/tests/JsonDocument/StaticJsonDocument.cpp delete mode 100644 extras/tests/MsgPackDeserializer/deserializeStaticVariant.cpp delete mode 100644 src/ArduinoJson/Document/StaticJsonDocument.hpp diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30b27b34..41aa2281 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -481,7 +481,7 @@ jobs: g++ -x c++ - < doc; + DynamicJsonDocument doc(300); deserializeJson(doc, "{}"); } END @@ -515,7 +515,7 @@ jobs: g++ -x c++ - < doc; + ArduinoJson::DynamicJsonDocument doc(300); deserializeJson(doc, "{}"); } END diff --git a/CHANGELOG.md b/CHANGELOG.md index bee74347..54ca19b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,832 +1,7 @@ ArduinoJson: change log ======================= -v6.21.0 (2023-03-14) -------- +HEAD +---- -* Drop support for C++98/C++03. Minimum required is C++11. -* Remove `ARDUINOJSON_NAMESPACE`; use `ArduinoJson` instead. -* Make string support generic (issue #1807) - -v6.20.1 (2023-02-08) -------- - -* Remove explicit exclusion of `as()` and `as()` (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()`, 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 c = variant[key]; -> JsonVariant d = variant.containsKey(key) ? variant[key] : variant[key].to(); -> ``` - -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()` and `is()` -* 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::toJson()` to `void` -* Added `as()` and `is()` - -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` 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()` (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()` (issue #1412) -* Added `JsonVariant::is()` (issue #1412) -* Changed `JsonVariantConst::is()` to return `false` (issue #1412) -* Simplified `JsonVariant::as()` 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()` always returns `T` -> -> Previously, `JsonVariant::as()` could return a type different from `T`. -> The most common example is `as()` 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` 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()); // error: invalid conversion from 'const char*' to 'char*' [-fpermissive] -> ``` -> -> Instead, you must write: -> -> ```c++ -> Serial.println(doc["sensor"].as()); // OK -> ``` -> -> A deprecation warning with the message "Replace `as()` with `as()`" 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()` -> -> Lastly, a very minor change concerns `JsonVariantConst::is()`. -> 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 ` (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()` and `is()` (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()` -* 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 -> ``` - -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()` 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` (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 -> ``` -> -> #### 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())`. - -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()` and `JsonVariant::is()`. - - `as()` returns `0` if the integer `T` overflows - - `is()` 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()` is not required anymore. -* `JsonDocument` now support the same operations as `JsonVariant`. - Calling `JsonDocument::as()` 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(i)` and `JsonArray::set(i,v)` -* Removed `JsonObject::is(k)` and `JsonObject::set(k,v)` -* Replaced `T JsonArray::get(i)` with `JsonVariant JsonArray::get(i)` -* Replaced `T JsonObject::get(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()` (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()` and `JsonVariant::to()` - -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(); -> myValue.set(42); -> ``` -> -> #### JsonPair -> -> Old code: -> -> ```c++ -> for(JsonPair p : myObject) { -> Serial.println(p.key); -> Serial.println(p.value.as()); -> } -> ``` -> -> New code: -> -> ```c++ -> for(JsonPair p : myObject) { -> Serial.println(p.key()); -> Serial.println(p.value().as()); -> } -> ``` -> -> 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()` 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(); -> JsonArray& arr = obj.createNestedArray("key"); -> if (!arr.success()) { -> Serial.println("Not enough memory"); -> return; -> } -> ``` -> -> New code: -> -> ```c++ -> JsonObject obj = doc.to(); -> 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(); -> ``` -> -> #### 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(); -> obj["key"] = "value"; -> serializeJson(doc, Serial); -> ``` +* Remove `StaticJsonDocument` diff --git a/README.md b/README.md index fdb3f886..cc23b811 100644 --- a/README.md +++ b/README.md @@ -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/) * [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/) - * [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/) * Versatile * Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/) diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index b2819d55..7ca88c64 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -34,18 +34,18 @@ struct Config { 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 // Loads the configuration from a file -void loadConfiguration(const char *filename, Config &config) { +void loadConfiguration(const char* filename, Config& config) { // Open file for reading File file = SD.open(filename); // Allocate a temporary JsonDocument // Don't forget to change the capacity to match your requirements. // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<512> doc; + DynamicJsonDocument doc(512); // Deserialize the JSON document DeserializationError error = deserializeJson(doc, file); @@ -63,7 +63,7 @@ void loadConfiguration(const char *filename, Config &config) { } // 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 SD.remove(filename); @@ -77,7 +77,7 @@ void saveConfiguration(const char *filename, const Config &config) { // Allocate a temporary JsonDocument // Don't forget to change the capacity to match your requirements. // Use https://arduinojson.org/assistant to compute the capacity. - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); // Set the values in the document 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 -void printFile(const char *filename) { +void printFile(const char* filename) { // Open file for reading File file = SD.open(filename); if (!file) { @@ -114,7 +114,8 @@ void printFile(const char *filename) { void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Initialize SD library const int chipSelect = 4; diff --git a/examples/JsonFilterExample/JsonFilterExample.ino b/examples/JsonFilterExample/JsonFilterExample.ino index fc980aab..2373857d 100644 --- a/examples/JsonFilterExample/JsonFilterExample.ino +++ b/examples/JsonFilterExample/JsonFilterExample.ino @@ -11,7 +11,8 @@ void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // The huge input: an extract from OpenWeatherMap response const __FlashStringHelper* input_json = F( @@ -33,12 +34,12 @@ void setup() { "1000000,\"timezone\":0,\"sunrise\":1581492085,\"sunset\":1581527294}}"); // 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]["main"]["temp"] = true; // Deserialize the document - StaticJsonDocument<400> doc; + DynamicJsonDocument doc(400); deserializeJson(doc, input_json, DeserializationOption::Filter(filter)); // Print the result diff --git a/examples/JsonGeneratorExample/JsonGeneratorExample.ino b/examples/JsonGeneratorExample/JsonGeneratorExample.ino index cf4ab0d9..ba665f0d 100644 --- a/examples/JsonGeneratorExample/JsonGeneratorExample.ino +++ b/examples/JsonGeneratorExample/JsonGeneratorExample.ino @@ -11,19 +11,15 @@ void setup() { // Initialize Serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // 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. // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<200> doc; - - // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonDocument which allocates in the heap. - // - // DynamicJsonDocument doc(200); + DynamicJsonDocument doc(200); // Add values in the document // diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index a9d8b6d7..3383dda4 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -11,19 +11,15 @@ void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // 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. // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<200> doc; - - // StaticJsonDocument allocates memory on the stack, it can be - // replaced by DynamicJsonDocument which allocates in the heap. - // - // DynamicJsonDocument doc(200); + DynamicJsonDocument doc(200); // JSON input string. // diff --git a/examples/JsonServer/JsonServer.ino b/examples/JsonServer/JsonServer.ino index a897fce6..711fb1da 100644 --- a/examples/JsonServer/JsonServer.ino +++ b/examples/JsonServer/JsonServer.ino @@ -25,7 +25,8 @@ EthernetServer server(80); void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Initialize Ethernet libary if (!Ethernet.begin(mac)) { @@ -52,11 +53,12 @@ void loop() { Serial.println(F("New client")); // Read the request (we ignore the content in this example) - while (client.available()) client.read(); + while (client.available()) + client.read(); // Allocate a temporary JsonDocument // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<500> doc; + DynamicJsonDocument doc(500); // Create the "analog" array JsonArray analogValues = doc.createNestedArray("analog"); diff --git a/examples/JsonUdpBeacon/JsonUdpBeacon.ino b/examples/JsonUdpBeacon/JsonUdpBeacon.ino index 6c369faa..0c3b91a6 100644 --- a/examples/JsonUdpBeacon/JsonUdpBeacon.ino +++ b/examples/JsonUdpBeacon/JsonUdpBeacon.ino @@ -32,7 +32,8 @@ EthernetUDP udp; void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // Initialize Ethernet libary if (!Ethernet.begin(mac)) { @@ -47,7 +48,7 @@ void setup() { void loop() { // Allocate a temporary JsonDocument // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<500> doc; + DynamicJsonDocument doc(500); // Create the "analog" array JsonArray analogValues = doc.createNestedArray("analog"); diff --git a/examples/MsgPackParser/MsgPackParser.ino b/examples/MsgPackParser/MsgPackParser.ino index 1a54c3b3..d04446d0 100644 --- a/examples/MsgPackParser/MsgPackParser.ino +++ b/examples/MsgPackParser/MsgPackParser.ino @@ -12,19 +12,15 @@ void setup() { // Initialize serial port Serial.begin(9600); - while (!Serial) continue; + while (!Serial) + continue; // 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. // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<200> doc; - - // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonObject which allocates in the heap. - // - // DynamicJsonObject doc(200); + DynamicJsonDocument doc(200); // MessagePack input string. // diff --git a/extras/ci/espidf/main/main.cpp b/extras/ci/espidf/main/main.cpp index 4818a679..176e2d3b 100644 --- a/extras/ci/espidf/main/main.cpp +++ b/extras/ci/espidf/main/main.cpp @@ -6,7 +6,7 @@ extern "C" void app_main() { char buffer[256]; - StaticJsonDocument<200> doc; + DynamicJsonDocument doc(200); doc["hello"] = "world"; serializeJson(doc, buffer); diff --git a/extras/scripts/wandbox/JsonGeneratorExample.cpp b/extras/scripts/wandbox/JsonGeneratorExample.cpp index b35d1856..32dfae30 100644 --- a/extras/scripts/wandbox/JsonGeneratorExample.cpp +++ b/extras/scripts/wandbox/JsonGeneratorExample.cpp @@ -10,20 +10,10 @@ int main() { // 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. // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<200> doc; - - // 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); + DynamicJsonDocument doc(200); // Add values in the document // diff --git a/extras/scripts/wandbox/JsonParserExample.cpp b/extras/scripts/wandbox/JsonParserExample.cpp index 396f98cb..c3f2f62e 100644 --- a/extras/scripts/wandbox/JsonParserExample.cpp +++ b/extras/scripts/wandbox/JsonParserExample.cpp @@ -10,15 +10,10 @@ int main() { // 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. // Use https://arduinojson.org/v6/assistant to compute the capacity. - StaticJsonDocument<300> doc; - - // StaticJsonDocument allocates memory on the stack, it can be - // replaced by DynamicJsonDocument which allocates in the heap. - // - // DynamicJsonDocument doc(200); + DynamicJsonDocument doc(300); // JSON input string. // diff --git a/extras/scripts/wandbox/MsgPackParserExample.cpp b/extras/scripts/wandbox/MsgPackParserExample.cpp index 763de84e..33fce9b2 100644 --- a/extras/scripts/wandbox/MsgPackParserExample.cpp +++ b/extras/scripts/wandbox/MsgPackParserExample.cpp @@ -10,15 +10,10 @@ int main() { // 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. // Use https://arduinojson.org/assistant to compute the capacity. - StaticJsonDocument<300> doc; - - // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonObject which allocates in the heap. - // - // DynamicJsonObject doc(200); + DynamicJsonDocument doc(300); // MessagePack input string. // diff --git a/extras/tests/Cpp17/string_view.cpp b/extras/tests/Cpp17/string_view.cpp index 6a51ce2d..16d7cd33 100644 --- a/extras/tests/Cpp17/string_view.cpp +++ b/extras/tests/Cpp17/string_view.cpp @@ -8,7 +8,7 @@ #endif TEST_CASE("string_view") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); JsonVariant variant = doc.to(); SECTION("deserializeJson()") { diff --git a/extras/tests/Cpp20/smoke_test.cpp b/extras/tests/Cpp20/smoke_test.cpp index dc41e875..e8852c05 100644 --- a/extras/tests/Cpp20/smoke_test.cpp +++ b/extras/tests/Cpp20/smoke_test.cpp @@ -4,7 +4,7 @@ #include TEST_CASE("C++20 smoke test") { - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); deserializeJson(doc, "{\"hello\":\"world\"}"); REQUIRE(doc["hello"] == "world"); diff --git a/extras/tests/IntegrationTests/openweathermap.cpp b/extras/tests/IntegrationTests/openweathermap.cpp index e91ac0a8..37cdadef 100644 --- a/extras/tests/IntegrationTests/openweathermap.cpp +++ b/extras/tests/IntegrationTests/openweathermap.cpp @@ -53,7 +53,7 @@ TEST_CASE("OpenWeatherMap") { "]}"; // clang-format on - StaticJsonDocument<512> filter; + DynamicJsonDocument filter(512); filter["list"][0]["dt"] = true; filter["list"][0]["main"]["temp"] = true; filter["list"][0]["weather"][0]["description"] = true; diff --git a/extras/tests/JsonArray/clear.cpp b/extras/tests/JsonArray/clear.cpp index 3a593c5a..3d3a592b 100644 --- a/extras/tests/JsonArray/clear.cpp +++ b/extras/tests/JsonArray/clear.cpp @@ -14,7 +14,7 @@ TEST_CASE("JsonArray::clear()") { } SECTION("Removes all elements") { - StaticJsonDocument<64> doc; + DynamicJsonDocument doc(64); JsonArray array = doc.to(); array.add(1); array.add(2); diff --git a/extras/tests/JsonArray/compare.cpp b/extras/tests/JsonArray/compare.cpp index 1e64e166..f587b13c 100644 --- a/extras/tests/JsonArray/compare.cpp +++ b/extras/tests/JsonArray/compare.cpp @@ -6,7 +6,7 @@ #include TEST_CASE("Compare JsonArray with JsonArray") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); SECTION("Compare with unbound") { JsonArray array = doc.to(); @@ -82,7 +82,7 @@ TEST_CASE("Compare JsonArray with JsonArray") { } TEST_CASE("Compare JsonArray with JsonVariant") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); SECTION("Compare with self") { JsonArray array = doc.to(); @@ -153,7 +153,7 @@ TEST_CASE("Compare JsonArray with JsonVariant") { } TEST_CASE("Compare JsonArray with JsonVariantConst") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); SECTION("Compare with unbound") { JsonArray array = doc.to(); @@ -247,7 +247,7 @@ TEST_CASE("Compare JsonArray with JsonVariantConst") { } TEST_CASE("Compare JsonArray with JsonArrayConst") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); SECTION("Compare with unbound") { JsonArray array = doc.to(); @@ -347,7 +347,7 @@ TEST_CASE("Compare JsonArray with JsonArrayConst") { } TEST_CASE("Compare JsonArrayConst with JsonArrayConst") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); SECTION("Compare with unbound") { JsonArray array = doc.to(); @@ -430,7 +430,7 @@ TEST_CASE("Compare JsonArrayConst with JsonArrayConst") { } TEST_CASE("Compare JsonArrayConst with JsonVariant") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); SECTION("Compare with self") { JsonArray array = doc.to(); diff --git a/extras/tests/JsonArray/copyArray.cpp b/extras/tests/JsonArray/copyArray.cpp index 7973c375..cf347ae5 100644 --- a/extras/tests/JsonArray/copyArray.cpp +++ b/extras/tests/JsonArray/copyArray.cpp @@ -108,7 +108,7 @@ TEST_CASE("copyArray()") { SECTION("int[] -> JsonArray, but not enough memory") { const size_t SIZE = JSON_ARRAY_SIZE(2); - StaticJsonDocument doc; + DynamicJsonDocument doc(SIZE); JsonArray array = doc.to(); char json[32]; int source[] = {1, 2, 3}; @@ -160,7 +160,7 @@ TEST_CASE("copyArray()") { SECTION("int[][] -> JsonArray, but not enough memory") { const size_t SIZE = JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2); - StaticJsonDocument doc; + DynamicJsonDocument doc(SIZE); JsonArray array = doc.to(); char json[32] = ""; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; diff --git a/extras/tests/JsonArray/iterator.cpp b/extras/tests/JsonArray/iterator.cpp index 50eb2763..c05a1f4a 100644 --- a/extras/tests/JsonArray/iterator.cpp +++ b/extras/tests/JsonArray/iterator.cpp @@ -7,7 +7,7 @@ template static void run_iterator_test() { - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_ARRAY_SIZE(2)); JsonArray tmp = doc.to(); tmp.add(12); tmp.add(34); diff --git a/extras/tests/JsonDeserializer/CMakeLists.txt b/extras/tests/JsonDeserializer/CMakeLists.txt index f60ad416..0bc39054 100644 --- a/extras/tests/JsonDeserializer/CMakeLists.txt +++ b/extras/tests/JsonDeserializer/CMakeLists.txt @@ -4,7 +4,6 @@ add_executable(JsonDeserializerTests array.cpp - array_static.cpp DeserializationError.cpp filter.cpp incomplete_input.cpp @@ -14,7 +13,6 @@ add_executable(JsonDeserializerTests nestingLimit.cpp number.cpp object.cpp - object_static.cpp string.cpp ) diff --git a/extras/tests/JsonDeserializer/array.cpp b/extras/tests/JsonDeserializer/array.cpp index b30269c1..e520a047 100644 --- a/extras/tests/JsonDeserializer/array.cpp +++ b/extras/tests/JsonDeserializer/array.cpp @@ -251,3 +251,86 @@ TEST_CASE("deserialize JSON array") { 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(); + 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(); + + REQUIRE(err == DeserializationError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2)); + REQUIRE(arr[0] == 1); + REQUIRE(arr[1] == 2); + } +} diff --git a/extras/tests/JsonDeserializer/array_static.cpp b/extras/tests/JsonDeserializer/array_static.cpp deleted file mode 100644 index 2d1f538d..00000000 --- a/extras/tests/JsonDeserializer/array_static.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON -// MIT License - -#include -#include - -TEST_CASE("deserialize JSON array with a StaticJsonDocument") { - SECTION("BufferOfTheRightSizeForEmptyArray") { - StaticJsonDocument doc; - char input[] = "[]"; - - DeserializationError err = deserializeJson(doc, input); - - REQUIRE(err == DeserializationError::Ok); - } - - SECTION("TooSmallBufferForArrayWithOneValue") { - StaticJsonDocument doc; - char input[] = "[1]"; - - DeserializationError err = deserializeJson(doc, input); - - REQUIRE(err == DeserializationError::NoMemory); - } - - SECTION("BufferOfTheRightSizeForArrayWithOneValue") { - StaticJsonDocument doc; - char input[] = "[1]"; - - DeserializationError err = deserializeJson(doc, input); - - REQUIRE(err == DeserializationError::Ok); - } - - SECTION("TooSmallBufferForArrayWithNestedObject") { - StaticJsonDocument doc; - char input[] = "[{}]"; - - DeserializationError err = deserializeJson(doc, input); - - REQUIRE(err == DeserializationError::NoMemory); - } - - SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { - StaticJsonDocument 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 doc; - char input[] = "[1,2,3,4]"; - - deserializeJson(doc, input); - deserializeJson(doc, "[]"); - - JsonArray arr = doc.as(); - REQUIRE(arr.size() == 0); - REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); - } - - SECTION("Array") { - StaticJsonDocument doc; - char input[] = "[1,2]"; - - DeserializationError err = deserializeJson(doc, input); - JsonArray arr = doc.as(); - - REQUIRE(err == DeserializationError::Ok); - REQUIRE(doc.is()); - REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2)); - REQUIRE(arr[0] == 1); - REQUIRE(arr[1] == 2); - } -} diff --git a/extras/tests/JsonDeserializer/filter.cpp b/extras/tests/JsonDeserializer/filter.cpp index f1c6e2e4..1f3d3b2e 100644 --- a/extras/tests/JsonDeserializer/filter.cpp +++ b/extras/tests/JsonDeserializer/filter.cpp @@ -706,10 +706,10 @@ TEST_CASE("Filtering") { TEST_CASE("Zero-copy mode") { // issue #1697 char input[] = "{\"include\":42,\"exclude\":666}"; - StaticJsonDocument<256> filter; + DynamicJsonDocument filter(256); filter["include"] = true; - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); DeserializationError err = deserializeJson(doc, input, DeserializationOption::Filter(filter)); @@ -718,8 +718,8 @@ TEST_CASE("Zero-copy mode") { // issue #1697 } TEST_CASE("Overloads") { - StaticJsonDocument<256> doc; - StaticJsonDocument<256> filter; + DynamicJsonDocument doc(256); + DynamicJsonDocument filter(256); using namespace DeserializationOption; diff --git a/extras/tests/JsonDeserializer/input_types.cpp b/extras/tests/JsonDeserializer/input_types.cpp index 6c21c6f1..d49c9c99 100644 --- a/extras/tests/JsonDeserializer/input_types.cpp +++ b/extras/tests/JsonDeserializer/input_types.cpp @@ -10,7 +10,7 @@ #include "CustomReader.hpp" TEST_CASE("deserializeJson(char*)") { - StaticJsonDocument<1024> doc; + DynamicJsonDocument doc(1024); SECTION("should not duplicate strings") { char input[] = "{\"hello\":\"world\"}"; @@ -125,7 +125,7 @@ TEST_CASE("deserializeJson(VLA)") { char vla[i]; strcpy(vla, "{\"a\":42}"); - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(1)); DeserializationError err = deserializeJson(doc, vla); REQUIRE(err == DeserializationError::Ok); diff --git a/extras/tests/JsonDeserializer/object.cpp b/extras/tests/JsonDeserializer/object.cpp index 814258ec..e31c1f24 100644 --- a/extras/tests/JsonDeserializer/object.cpp +++ b/extras/tests/JsonDeserializer/object.cpp @@ -313,3 +313,61 @@ TEST_CASE("deserialize JSON object") { CHECK(doc.as() == 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().size() == 0); + REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + } +} diff --git a/extras/tests/JsonDeserializer/object_static.cpp b/extras/tests/JsonDeserializer/object_static.cpp deleted file mode 100644 index b198ea74..00000000 --- a/extras/tests/JsonDeserializer/object_static.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON -// MIT License - -#include -#include - -TEST_CASE("deserialize JSON object with StaticJsonDocument") { - SECTION("BufferOfTheRightSizeForEmptyObject") { - StaticJsonDocument doc; - char input[] = "{}"; - - DeserializationError err = deserializeJson(doc, input); - - REQUIRE(err == DeserializationError::Ok); - } - - SECTION("TooSmallBufferForObjectWithOneValue") { - StaticJsonDocument doc; - char input[] = "{\"a\":1}"; - - DeserializationError err = deserializeJson(doc, input); - - REQUIRE(err == DeserializationError::NoMemory); - } - - SECTION("BufferOfTheRightSizeForObjectWithOneValue") { - StaticJsonDocument doc; - char input[] = "{\"a\":1}"; - - DeserializationError err = deserializeJson(doc, input); - - REQUIRE(err == DeserializationError::Ok); - } - - SECTION("TooSmallBufferForObjectWithNestedObject") { - StaticJsonDocument doc; - char input[] = "{\"a\":[]}"; - - DeserializationError err = deserializeJson(doc, input); - - REQUIRE(err == DeserializationError::NoMemory); - } - - SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { - StaticJsonDocument doc; - char input[] = "{\"a\":[]}"; - - DeserializationError err = deserializeJson(doc, input); - - REQUIRE(err == DeserializationError::Ok); - } - - SECTION("Should clear the JsonObject") { - StaticJsonDocument doc; - char input[] = "{\"hello\":\"world\"}"; - - deserializeJson(doc, input); - deserializeJson(doc, "{}"); - - REQUIRE(doc.as().size() == 0); - REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); - } -} diff --git a/extras/tests/JsonDeserializer/string.cpp b/extras/tests/JsonDeserializer/string.cpp index 2379d455..a49e1746 100644 --- a/extras/tests/JsonDeserializer/string.cpp +++ b/extras/tests/JsonDeserializer/string.cpp @@ -47,7 +47,7 @@ TEST_CASE("Valid JSON strings value") { } TEST_CASE("\\u0000") { - StaticJsonDocument<200> doc; + DynamicJsonDocument doc(200); DeserializationError err = deserializeJson(doc, "\"wx\\u0000yz\""); REQUIRE(err == DeserializationError::Ok); diff --git a/extras/tests/JsonDocument/CMakeLists.txt b/extras/tests/JsonDocument/CMakeLists.txt index 3e9b4683..a4f6db44 100644 --- a/extras/tests/JsonDocument/CMakeLists.txt +++ b/extras/tests/JsonDocument/CMakeLists.txt @@ -19,7 +19,6 @@ add_executable(JsonDocumentTests remove.cpp shrinkToFit.cpp size.cpp - StaticJsonDocument.cpp subscript.cpp swap.cpp ) diff --git a/extras/tests/JsonDocument/DynamicJsonDocument.cpp b/extras/tests/JsonDocument/DynamicJsonDocument.cpp index 397f8c5d..96250e42 100644 --- a/extras/tests/JsonDocument/DynamicJsonDocument.cpp +++ b/extras/tests/JsonDocument/DynamicJsonDocument.cpp @@ -94,18 +94,8 @@ TEST_CASE("DynamicJsonDocument constructor") { 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") { - StaticJsonDocument<200> doc1; + DynamicJsonDocument doc1(200); JsonObject obj = doc1.to(); obj["hello"] = "world"; @@ -116,7 +106,7 @@ TEST_CASE("DynamicJsonDocument constructor") { } SECTION("Construct from JsonArray") { - StaticJsonDocument<200> doc1; + DynamicJsonDocument doc1(200); JsonArray arr = doc1.to(); arr.add("hello"); @@ -127,7 +117,7 @@ TEST_CASE("DynamicJsonDocument constructor") { } SECTION("Construct from JsonVariant") { - StaticJsonDocument<200> doc1; + DynamicJsonDocument doc1(200); deserializeJson(doc1, "42"); DynamicJsonDocument doc2 = doc1.as(); @@ -160,19 +150,8 @@ TEST_CASE("DynamicJsonDocument assignment") { REQUIRE(doc2.capacity() == doc1.capacity()); } - SECTION("Assign from StaticJsonDocument") { - StaticJsonDocument<200> doc1; - deserializeJson(doc1, "{\"hello\":\"world\"}"); - DynamicJsonDocument doc2(4096); - doc2.to().set(666); - - doc2 = doc1; - - REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); - } - SECTION("Assign from JsonObject") { - StaticJsonDocument<200> doc1; + DynamicJsonDocument doc1(200); JsonObject obj = doc1.to(); obj["hello"] = "world"; @@ -184,7 +163,7 @@ TEST_CASE("DynamicJsonDocument assignment") { } SECTION("Assign from JsonArray") { - StaticJsonDocument<200> doc1; + DynamicJsonDocument doc1(200); JsonArray arr = doc1.to(); arr.add("hello"); @@ -196,7 +175,7 @@ TEST_CASE("DynamicJsonDocument assignment") { } SECTION("Assign from JsonVariant") { - StaticJsonDocument<200> doc1; + DynamicJsonDocument doc1(200); deserializeJson(doc1, "42"); DynamicJsonDocument doc2(4096); @@ -207,7 +186,7 @@ TEST_CASE("DynamicJsonDocument assignment") { } SECTION("Assign from MemberProxy") { - StaticJsonDocument<200> doc1; + DynamicJsonDocument doc1(200); doc1["value"] = 42; DynamicJsonDocument doc2(4096); @@ -218,7 +197,7 @@ TEST_CASE("DynamicJsonDocument assignment") { } SECTION("Assign from ElementProxy") { - StaticJsonDocument<200> doc1; + DynamicJsonDocument doc1(200); doc1[0] = 42; DynamicJsonDocument doc2(4096); diff --git a/extras/tests/JsonDocument/ElementProxy.cpp b/extras/tests/JsonDocument/ElementProxy.cpp index 00fcdda2..e824d998 100644 --- a/extras/tests/JsonDocument/ElementProxy.cpp +++ b/extras/tests/JsonDocument/ElementProxy.cpp @@ -247,7 +247,7 @@ TEST_CASE("ElementProxy cast to JsonVariant") { } TEST_CASE("ElementProxy::shallowCopy()") { - StaticJsonDocument<1024> doc1, doc2; + DynamicJsonDocument doc1(1024), doc2(1024); doc2["hello"] = "world"; doc1[0].shallowCopy(doc2); diff --git a/extras/tests/JsonDocument/MemberProxy.cpp b/extras/tests/JsonDocument/MemberProxy.cpp index a3707b03..6a32cd2c 100644 --- a/extras/tests/JsonDocument/MemberProxy.cpp +++ b/extras/tests/JsonDocument/MemberProxy.cpp @@ -127,7 +127,7 @@ TEST_CASE("MemberProxy::operator|()") { JsonObject object = doc.to(); object["hello"] = "world"; - StaticJsonDocument<0> emptyDoc; + DynamicJsonDocument emptyDoc(0); JsonObject anotherObject = object["hello"] | emptyDoc.to(); REQUIRE(anotherObject.isNull() == false); @@ -288,7 +288,7 @@ TEST_CASE("MemberProxy cast to JsonVariant") { } TEST_CASE("MemberProxy::createNestedArray()") { - StaticJsonDocument<1024> doc; + DynamicJsonDocument doc(1024); JsonArray arr = doc["items"].createNestedArray(); arr.add(42); @@ -296,7 +296,7 @@ TEST_CASE("MemberProxy::createNestedArray()") { } TEST_CASE("MemberProxy::createNestedArray(key)") { - StaticJsonDocument<1024> doc; + DynamicJsonDocument doc(1024); JsonArray arr = doc["weather"].createNestedArray("temp"); arr.add(42); @@ -304,7 +304,7 @@ TEST_CASE("MemberProxy::createNestedArray(key)") { } TEST_CASE("MemberProxy::createNestedObject()") { - StaticJsonDocument<1024> doc; + DynamicJsonDocument doc(1024); JsonObject obj = doc["items"].createNestedObject(); obj["value"] = 42; @@ -312,7 +312,7 @@ TEST_CASE("MemberProxy::createNestedObject()") { } TEST_CASE("MemberProxy::createNestedObject(key)") { - StaticJsonDocument<1024> doc; + DynamicJsonDocument doc(1024); JsonObject obj = doc["status"].createNestedObject("weather"); obj["temp"] = 42; @@ -320,7 +320,7 @@ TEST_CASE("MemberProxy::createNestedObject(key)") { } TEST_CASE("MemberProxy::shallowCopy()") { - StaticJsonDocument<1024> doc1, doc2; + DynamicJsonDocument doc1(1024), doc2(1024); doc2["hello"] = "world"; doc1["obj"].shallowCopy(doc2); diff --git a/extras/tests/JsonDocument/StaticJsonDocument.cpp b/extras/tests/JsonDocument/StaticJsonDocument.cpp deleted file mode 100644 index 0d4089bc..00000000 --- a/extras/tests/JsonDocument/StaticJsonDocument.cpp +++ /dev/null @@ -1,224 +0,0 @@ -// ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON -// MIT License - -#include -#include - -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(); - obj["hello"] = "world"; - - std::string json; - serializeJson(doc, json); - - REQUIRE(json == "{\"hello\":\"world\"}"); - } - - SECTION("Copy assignment") { - StaticJsonDocument<200> doc1, doc2; - doc1.to().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(); - - 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(); - - deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]"); - REQUIRE_JSON(doc2, "[\"hello\",\"world\"]"); - } - - SECTION("Construct from JsonVariant") { - DynamicJsonDocument doc1(4096); - deserializeJson(doc1, "42"); - - StaticJsonDocument<200> doc2 = doc1.as(); - - REQUIRE_JSON(doc2, "42"); - } - } - - SECTION("Assignment") { - SECTION("Copy assignment") { - StaticJsonDocument<200> doc1, doc2; - doc1.to().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().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().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().set(666); - deserializeJson(doc1, "[\"hello\",\"world\"]"); - - doc2 = doc1.as(); - - deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]"); - REQUIRE_JSON(doc2, "[\"hello\",\"world\"]"); - } - - SECTION("Assign from JsonArrayConst") { - StaticJsonDocument<200> doc1; - DynamicJsonDocument doc2(4096); - doc1.to().set(666); - deserializeJson(doc1, "[\"hello\",\"world\"]"); - - doc2 = doc1.as(); - - deserializeJson(doc1, "[\"HELLO\",\"WORLD\"]"); - REQUIRE_JSON(doc2, "[\"hello\",\"world\"]"); - } - - SECTION("Assign from JsonObject") { - StaticJsonDocument<200> doc1; - DynamicJsonDocument doc2(4096); - doc1.to().set(666); - deserializeJson(doc1, "{\"hello\":\"world\"}"); - - doc2 = doc1.as(); - - deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}"); - REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); - } - - SECTION("Assign from JsonObjectConst") { - StaticJsonDocument<200> doc1; - DynamicJsonDocument doc2(4096); - doc1.to().set(666); - deserializeJson(doc1, "{\"hello\":\"world\"}"); - - doc2 = doc1.as(); - - deserializeJson(doc1, "{\"HELLO\":\"WORLD\"}"); - REQUIRE_JSON(doc2, "{\"hello\":\"world\"}"); - } - - SECTION("Assign from JsonVariant") { - DynamicJsonDocument doc1(4096); - doc1.to().set(666); - deserializeJson(doc1, "42"); - - StaticJsonDocument<200> doc2; - doc2 = doc1.as(); - - REQUIRE_JSON(doc2, "42"); - } - - SECTION("Assign from JsonVariantConst") { - DynamicJsonDocument doc1(4096); - doc1.to().set(666); - deserializeJson(doc1, "42"); - - StaticJsonDocument<200> doc2; - doc2 = doc1.as(); - - 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, "{}"); - } -} diff --git a/extras/tests/JsonDocument/cast.cpp b/extras/tests/JsonDocument/cast.cpp index 253e1fc7..3b8905eb 100644 --- a/extras/tests/JsonDocument/cast.cpp +++ b/extras/tests/JsonDocument/cast.cpp @@ -8,7 +8,7 @@ #include TEST_CASE("Implicit cast to JsonVariant") { - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); doc["hello"] = "world"; diff --git a/extras/tests/JsonDocument/compare.cpp b/extras/tests/JsonDocument/compare.cpp index d834b226..1d3f2e2a 100644 --- a/extras/tests/JsonDocument/compare.cpp +++ b/extras/tests/JsonDocument/compare.cpp @@ -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&)") { - StaticJsonDocument<256> doc1; - StaticJsonDocument<256> doc2; + DynamicJsonDocument doc1(256); + DynamicJsonDocument doc2(256); const JsonDocument& ref1 = doc1; const JsonDocument& ref2 = doc2; diff --git a/extras/tests/JsonDocument/issue1120.cpp b/extras/tests/JsonDocument/issue1120.cpp index fbee4778..05c1e991 100644 --- a/extras/tests/JsonDocument/issue1120.cpp +++ b/extras/tests/JsonDocument/issue1120.cpp @@ -3,7 +3,7 @@ #include TEST_CASE("Issue #1120") { - StaticJsonDocument<500> doc; + DynamicJsonDocument doc(500); constexpr char str[] = "{\"contents\":[{\"module\":\"Packet\"},{\"module\":\"Analog\"}]}"; deserializeJson(doc, str); diff --git a/extras/tests/JsonDocument/overflowed.cpp b/extras/tests/JsonDocument/overflowed.cpp index e46d21b0..6f1e1994 100644 --- a/extras/tests/JsonDocument/overflowed.cpp +++ b/extras/tests/JsonDocument/overflowed.cpp @@ -7,54 +7,54 @@ TEST_CASE("JsonDocument::overflowed()") { SECTION("returns false on a fresh object") { - StaticJsonDocument<0> doc; + DynamicJsonDocument doc(0); CHECK(doc.overflowed() == false); } SECTION("returns true after a failed insertion") { - StaticJsonDocument<0> doc; + DynamicJsonDocument doc(0); doc.add(0); CHECK(doc.overflowed() == true); } SECTION("returns false after successful insertion") { - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_ARRAY_SIZE(1)); doc.add(0); CHECK(doc.overflowed() == false); } SECTION("returns true after a failed string copy") { - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_ARRAY_SIZE(1)); doc.add(std::string("example")); CHECK(doc.overflowed() == true); } SECTION("returns false after a successful string copy") { - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_ARRAY_SIZE(1) + 8); doc.add(std::string("example")); CHECK(doc.overflowed() == false); } SECTION("returns true after a failed member add") { - StaticJsonDocument<1> doc; + DynamicJsonDocument doc(1); doc["example"] = true; CHECK(doc.overflowed() == true); } SECTION("returns true after a failed deserialization") { - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_ARRAY_SIZE(1)); deserializeJson(doc, "[\"example\"]"); CHECK(doc.overflowed() == true); } SECTION("returns false after a successful deserialization") { - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_ARRAY_SIZE(1) + 8); deserializeJson(doc, "[\"example\"]"); CHECK(doc.overflowed() == false); } SECTION("returns false after clear()") { - StaticJsonDocument<0> doc; + DynamicJsonDocument doc(0); doc.add(0); doc.clear(); CHECK(doc.overflowed() == false); diff --git a/extras/tests/JsonObject/clear.cpp b/extras/tests/JsonObject/clear.cpp index e112a8dc..7a738ef7 100644 --- a/extras/tests/JsonObject/clear.cpp +++ b/extras/tests/JsonObject/clear.cpp @@ -14,7 +14,7 @@ TEST_CASE("JsonObject::clear()") { } SECTION("Removes all elements") { - StaticJsonDocument<64> doc; + DynamicJsonDocument doc(64); JsonObject obj = doc.to(); obj["hello"] = 1; obj["world"] = 2; diff --git a/extras/tests/JsonObject/compare.cpp b/extras/tests/JsonObject/compare.cpp index 9b747e3b..84c09771 100644 --- a/extras/tests/JsonObject/compare.cpp +++ b/extras/tests/JsonObject/compare.cpp @@ -6,7 +6,7 @@ #include TEST_CASE("Compare JsonObject with JsonObject") { - StaticJsonDocument<512> doc; + DynamicJsonDocument doc(512); SECTION("Compare with unbound") { JsonObject object = doc.to(); @@ -82,7 +82,7 @@ TEST_CASE("Compare JsonObject with JsonObject") { } TEST_CASE("Compare JsonObject with JsonVariant") { - StaticJsonDocument<512> doc; + DynamicJsonDocument doc(512); SECTION("Compare with self") { JsonObject object = doc.to(); @@ -153,7 +153,7 @@ TEST_CASE("Compare JsonObject with JsonVariant") { } TEST_CASE("Compare JsonObject with JsonVariantConst") { - StaticJsonDocument<512> doc; + DynamicJsonDocument doc(512); SECTION("Compare with unbound") { JsonObject object = doc.to(); @@ -247,7 +247,7 @@ TEST_CASE("Compare JsonObject with JsonVariantConst") { } TEST_CASE("Compare JsonObject with JsonObjectConst") { - StaticJsonDocument<512> doc; + DynamicJsonDocument doc(512); SECTION("Compare with unbound") { JsonObject object = doc.to(); @@ -347,7 +347,7 @@ TEST_CASE("Compare JsonObject with JsonObjectConst") { } TEST_CASE("Compare JsonObjectConst with JsonObjectConst") { - StaticJsonDocument<512> doc; + DynamicJsonDocument doc(512); SECTION("Compare with unbound") { JsonObject object = doc.to(); @@ -430,7 +430,7 @@ TEST_CASE("Compare JsonObjectConst with JsonObjectConst") { } TEST_CASE("Compare JsonObjectConst with JsonVariant") { - StaticJsonDocument<512> doc; + DynamicJsonDocument doc(512); SECTION("Compare with self") { JsonObject object = doc.to(); diff --git a/extras/tests/JsonObject/copy.cpp b/extras/tests/JsonObject/copy.cpp index a4d5b5fa..77dee20d 100644 --- a/extras/tests/JsonObject/copy.cpp +++ b/extras/tests/JsonObject/copy.cpp @@ -72,7 +72,7 @@ TEST_CASE("JsonObject::set()") { } SECTION("destination too small to store the key") { - StaticJsonDocument doc3; + DynamicJsonDocument doc3(JSON_OBJECT_SIZE(1)); JsonObject obj3 = doc3.to(); obj1[std::string("hello")] = "world"; @@ -84,7 +84,7 @@ TEST_CASE("JsonObject::set()") { } SECTION("destination too small to store the value") { - StaticJsonDocument doc3; + DynamicJsonDocument doc3(JSON_OBJECT_SIZE(1)); JsonObject obj3 = doc3.to(); obj1["hello"] = std::string("world"); diff --git a/extras/tests/JsonObject/iterator.cpp b/extras/tests/JsonObject/iterator.cpp index c48de5f6..dc34b9c0 100644 --- a/extras/tests/JsonObject/iterator.cpp +++ b/extras/tests/JsonObject/iterator.cpp @@ -8,7 +8,7 @@ using namespace Catch::Matchers; TEST_CASE("JsonObject::begin()/end()") { - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)); JsonObject obj = doc.to(); obj["ab"] = 12; obj["cd"] = 34; @@ -38,7 +38,7 @@ TEST_CASE("JsonObject::begin()/end()") { } TEST_CASE("JsonObjectConst::begin()/end()") { - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)); JsonObject obj = doc.to(); obj["ab"] = 12; obj["cd"] = 34; diff --git a/extras/tests/JsonSerializer/JsonArray.cpp b/extras/tests/JsonSerializer/JsonArray.cpp index 1fad69dd..7ea6a086 100644 --- a/extras/tests/JsonSerializer/JsonArray.cpp +++ b/extras/tests/JsonSerializer/JsonArray.cpp @@ -15,7 +15,7 @@ static void check(JsonArray array, std::string expected) { } TEST_CASE("serializeJson(JsonArray)") { - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_ARRAY_SIZE(2)); JsonArray array = doc.to(); SECTION("Empty") { diff --git a/extras/tests/JsonSerializer/std_string.cpp b/extras/tests/JsonSerializer/std_string.cpp index af0d8096..559c327d 100644 --- a/extras/tests/JsonSerializer/std_string.cpp +++ b/extras/tests/JsonSerializer/std_string.cpp @@ -47,7 +47,7 @@ TEST_CASE("serialize JsonObject to std::string") { } TEST_CASE("serialize an std::string containing a NUL") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); doc.set(std::string("hello\0world", 11)); CHECK(doc.memoryUsage() == 12); diff --git a/extras/tests/JsonVariant/compare.cpp b/extras/tests/JsonVariant/compare.cpp index 1922df03..fe371a77 100644 --- a/extras/tests/JsonVariant/compare.cpp +++ b/extras/tests/JsonVariant/compare.cpp @@ -9,7 +9,7 @@ // Here, we're just filling the holes TEST_CASE("Compare JsonVariant with value") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); JsonVariant a = doc.add(); SECTION("null vs (char*)0") { @@ -37,7 +37,7 @@ TEST_CASE("Compare JsonVariant with value") { } TEST_CASE("Compare JsonVariant with JsonVariant") { - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); JsonVariant a = doc.add(); JsonVariant b = doc.add(); diff --git a/extras/tests/JsonVariant/isnull.cpp b/extras/tests/JsonVariant/isnull.cpp index bb9de714..fadf0d3b 100644 --- a/extras/tests/JsonVariant/isnull.cpp +++ b/extras/tests/JsonVariant/isnull.cpp @@ -71,13 +71,13 @@ TEST_CASE("JsonVariant::isNull()") { } SECTION("returns true for a shallow null copy") { - StaticJsonDocument<128> doc2; + DynamicJsonDocument doc2(128); variant.shallowCopy(doc2); CHECK(variant.isNull() == true); } SECTION("returns false for a shallow array copy") { - StaticJsonDocument<128> doc2; + DynamicJsonDocument doc2(128); doc2[0] = 42; variant.shallowCopy(doc2); CHECK(variant.isNull() == false); diff --git a/extras/tests/JsonVariant/overflow.cpp b/extras/tests/JsonVariant/overflow.cpp index 1123e98b..1bbdf4f7 100644 --- a/extras/tests/JsonVariant/overflow.cpp +++ b/extras/tests/JsonVariant/overflow.cpp @@ -7,7 +7,7 @@ template void shouldBeOk(TIn value) { - StaticJsonDocument<1> doc; + DynamicJsonDocument doc(1); JsonVariant var = doc.to(); var.set(value); REQUIRE(var.as() == TOut(value)); @@ -15,7 +15,7 @@ void shouldBeOk(TIn value) { template void shouldOverflow(TIn value) { - StaticJsonDocument<1> doc; + DynamicJsonDocument doc(1); JsonVariant var = doc.to(); var.set(value); REQUIRE(var.as() == 0); diff --git a/extras/tests/JsonVariant/set.cpp b/extras/tests/JsonVariant/set.cpp index 4743afb9..0fcfcb84 100644 --- a/extras/tests/JsonVariant/set.cpp +++ b/extras/tests/JsonVariant/set.cpp @@ -128,7 +128,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") { } TEST_CASE("JsonVariant::set() with not enough memory") { - StaticJsonDocument<1> doc; + DynamicJsonDocument doc(1); JsonVariant v = doc.to(); diff --git a/extras/tests/JsonVariant/shallowCopy.cpp b/extras/tests/JsonVariant/shallowCopy.cpp index 28aa38c6..a39b20be 100644 --- a/extras/tests/JsonVariant/shallowCopy.cpp +++ b/extras/tests/JsonVariant/shallowCopy.cpp @@ -6,7 +6,7 @@ #include TEST_CASE("JsonVariant::shallowCopy()") { - StaticJsonDocument<1024> doc1, doc2; + DynamicJsonDocument doc1(1024), doc2(1024); JsonVariant variant = doc1.to(); SECTION("JsonVariant::shallowCopy(JsonDocument&)") { diff --git a/extras/tests/JsonVariant/stl_containers.cpp b/extras/tests/JsonVariant/stl_containers.cpp index d6b9b60b..c103ba24 100644 --- a/extras/tests/JsonVariant/stl_containers.cpp +++ b/extras/tests/JsonVariant/stl_containers.cpp @@ -69,13 +69,13 @@ TEST_CASE("vector") { SECTION("toJson") { std::vector v = {1, 2}; - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); doc.set(v); REQUIRE(doc.as() == "[1,2]"); } SECTION("fromJson") { - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); doc.add(1); doc.add(2); @@ -86,7 +86,7 @@ TEST_CASE("vector") { } SECTION("checkJson") { - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); CHECK(doc.is>() == false); doc.add(1); @@ -106,13 +106,13 @@ TEST_CASE("array") { v[0] = 1; v[1] = 2; - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); doc.set(v); REQUIRE(doc.as() == "[1,2]"); } SECTION("fromJson") { - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); doc.add(1); doc.add(2); @@ -123,7 +123,7 @@ TEST_CASE("array") { } SECTION("checkJson") { - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); CHECK(doc.is() == false); doc.add(1); diff --git a/extras/tests/Misc/StringWriter.cpp b/extras/tests/Misc/StringWriter.cpp index 3cc1333f..25958582 100644 --- a/extras/tests/Misc/StringWriter.cpp +++ b/extras/tests/Misc/StringWriter.cpp @@ -136,7 +136,7 @@ TEST_CASE("Writer") { } TEST_CASE("serializeJson(doc, String)") { - StaticJsonDocument<1024> doc; + DynamicJsonDocument doc(1024); doc["hello"] = "world"; ::String output; diff --git a/extras/tests/Misc/TypeTraits.cpp b/extras/tests/Misc/TypeTraits.cpp index 10b6168b..4d93c595 100644 --- a/extras/tests/Misc/TypeTraits.cpp +++ b/extras/tests/Misc/TypeTraits.cpp @@ -194,8 +194,6 @@ TEST_CASE("Polyfills/type_traits") { JsonVariantConst>::value == true); CHECK(is_convertible::value == true); CHECK(is_convertible::value == true); - CHECK(is_convertible, JsonVariantConst>::value == - true); } SECTION("is_class") { diff --git a/extras/tests/Misc/printable.cpp b/extras/tests/Misc/printable.cpp index 0c6e8e19..d79eebf7 100644 --- a/extras/tests/Misc/printable.cpp +++ b/extras/tests/Misc/printable.cpp @@ -48,7 +48,7 @@ struct PrintableString : public Printable { TEST_CASE("Printable") { SECTION("Doesn't overflow") { - StaticJsonDocument<8> doc; + DynamicJsonDocument doc(8); const char* value = "example"; // == 7 chars doc.set(666); // to make sure we override the value @@ -75,7 +75,7 @@ TEST_CASE("Printable") { } SECTION("Overflows early") { - StaticJsonDocument<8> doc; + DynamicJsonDocument doc(8); const char* value = "hello world"; // > 8 chars doc.set(666); // to make sure we override the value @@ -100,7 +100,7 @@ TEST_CASE("Printable") { } SECTION("Overflows adding terminator") { - StaticJsonDocument<8> doc; + DynamicJsonDocument doc(8); const char* value = "overflow"; // == 8 chars doc.set(666); // to make sure we override the value @@ -133,7 +133,7 @@ TEST_CASE("Printable") { } SECTION("String deduplication") { - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); doc.add(PrintableString("Hello World!")); doc.add(PrintableString("Hello World!")); REQUIRE(doc.size() == 2); diff --git a/extras/tests/Misc/unsigned_char.cpp b/extras/tests/Misc/unsigned_char.cpp index d3ee492a..5090096a 100644 --- a/extras/tests/Misc/unsigned_char.cpp +++ b/extras/tests/Misc/unsigned_char.cpp @@ -13,7 +13,7 @@ TEST_CASE("unsigned char[]") { SECTION("deserializeJson()") { unsigned char input[] = "{\"a\":42}"; - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(1)); DeserializationError err = deserializeJson(doc, input); REQUIRE(err == DeserializationError::Ok); @@ -22,7 +22,7 @@ TEST_CASE("unsigned char[]") { SECTION("deserializeMsgPack()") { unsigned char input[] = "\xDE\x00\x01\xA5Hello\xA5world"; - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)); DeserializationError err = deserializeMsgPack(doc, input); REQUIRE(err == DeserializationError::Ok); @@ -30,7 +30,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeMsgPack(unsigned char[])") { unsigned char buffer[32]; - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)); doc["hello"] = "world"; size_t n = serializeMsgPack(doc, buffer); @@ -41,7 +41,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeMsgPack(unsigned char*)") { unsigned char buffer[32]; - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)); doc["hello"] = "world"; size_t n = serializeMsgPack(doc, buffer, sizeof(buffer)); @@ -52,7 +52,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeJson(unsigned char[])") { unsigned char buffer[32]; - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)); doc["hello"] = "world"; size_t n = serializeJson(doc, buffer); @@ -63,7 +63,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeJson(unsigned char*)") { unsigned char buffer[32]; - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)); doc["hello"] = "world"; size_t n = serializeJson(doc, buffer, sizeof(buffer)); @@ -74,7 +74,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeJsonPretty(unsigned char[])") { unsigned char buffer[32]; - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)); doc["hello"] = "world"; size_t n = serializeJsonPretty(doc, buffer); @@ -84,7 +84,7 @@ TEST_CASE("unsigned char[]") { SECTION("serializeJsonPretty(unsigned char*)") { unsigned char buffer[32]; - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(2)); doc["hello"] = "world"; size_t n = serializeJsonPretty(doc, buffer, sizeof(buffer)); diff --git a/extras/tests/MixedConfiguration/enable_string_deduplication_0.cpp b/extras/tests/MixedConfiguration/enable_string_deduplication_0.cpp index d763eec1..9463a8e2 100644 --- a/extras/tests/MixedConfiguration/enable_string_deduplication_0.cpp +++ b/extras/tests/MixedConfiguration/enable_string_deduplication_0.cpp @@ -12,7 +12,7 @@ #include TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 0") { - StaticJsonDocument<1024> doc; + DynamicJsonDocument doc(1024); SECTION("deserializeJson()") { SECTION("Deduplicate values") { diff --git a/extras/tests/MixedConfiguration/enable_string_deduplication_1.cpp b/extras/tests/MixedConfiguration/enable_string_deduplication_1.cpp index a8388a96..afd2364d 100644 --- a/extras/tests/MixedConfiguration/enable_string_deduplication_1.cpp +++ b/extras/tests/MixedConfiguration/enable_string_deduplication_1.cpp @@ -12,7 +12,7 @@ #include TEST_CASE("ARDUINOJSON_ENABLE_STRING_DEDUPLICATION = 1") { - StaticJsonDocument<1024> doc; + DynamicJsonDocument doc(1024); SECTION("deserializeJson()") { SECTION("Deduplicate values") { diff --git a/extras/tests/MixedConfiguration/issue1707.cpp b/extras/tests/MixedConfiguration/issue1707.cpp index f3ab7f9f..1e4af9b2 100644 --- a/extras/tests/MixedConfiguration/issue1707.cpp +++ b/extras/tests/MixedConfiguration/issue1707.cpp @@ -12,7 +12,7 @@ #include TEST_CASE("Issue1707") { - StaticJsonDocument<128> doc; + DynamicJsonDocument doc(128); DeserializationError err = deserializeJson(doc, F("{\"hello\":12}")); REQUIRE(err == DeserializationError::Ok); diff --git a/extras/tests/MsgPackDeserializer/CMakeLists.txt b/extras/tests/MsgPackDeserializer/CMakeLists.txt index a5442076..c4573d1a 100644 --- a/extras/tests/MsgPackDeserializer/CMakeLists.txt +++ b/extras/tests/MsgPackDeserializer/CMakeLists.txt @@ -5,7 +5,6 @@ add_executable(MsgPackDeserializerTests deserializeArray.cpp deserializeObject.cpp - deserializeStaticVariant.cpp deserializeVariant.cpp doubleToFloat.cpp filter.cpp diff --git a/extras/tests/MsgPackDeserializer/deserializeStaticVariant.cpp b/extras/tests/MsgPackDeserializer/deserializeStaticVariant.cpp deleted file mode 100644 index 0e126ff2..00000000 --- a/extras/tests/MsgPackDeserializer/deserializeStaticVariant.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON -// MIT License - -#include -#include - -template -static void check(const char* input, DeserializationError expected) { - StaticJsonDocument doc; - - DeserializationError error = deserializeMsgPack(doc, input); - - CAPTURE(input); - REQUIRE(error == expected); -} - -template -static void checkString(const char* input, DeserializationError expected) { - check(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("\x90", DeserializationError::Ok); // [] - check("\x91\x01", - DeserializationError::NoMemory); // [1] - check("\x91\x01", DeserializationError::Ok); // [1] - check("\x92\x01\x02", - DeserializationError::NoMemory); // [1,2] - } - - SECTION("array 16") { - check("\xDC\x00\x00", DeserializationError::Ok); - check("\xDC\x00\x01\x01", - DeserializationError::NoMemory); - check("\xDC\x00\x01\x01", DeserializationError::Ok); - check("\xDC\x00\x02\x01\x02", - DeserializationError::NoMemory); - } - - SECTION("array 32") { - check("\xDD\x00\x00\x00\x00", DeserializationError::Ok); - check("\xDD\x00\x00\x00\x01\x01", - DeserializationError::NoMemory); - check("\xDD\x00\x00\x00\x01\x01", - DeserializationError::Ok); - check("\xDD\x00\x00\x00\x02\x01\x02", - DeserializationError::NoMemory); - } - - SECTION("fixmap") { - SECTION("{}") { - check("\x80", DeserializationError::Ok); - } - SECTION("{H:1}") { - check("\x81\xA1H\x01", - DeserializationError::NoMemory); - check( - "\x81\xA1H\x01", DeserializationError::Ok); - } - SECTION("{H:1,W:2}") { - check( - "\x82\xA1H\x01\xA1W\x02", DeserializationError::NoMemory); - check( - "\x82\xA1H\x01\xA1W\x02", DeserializationError::Ok); - } - } - - SECTION("map 16") { - SECTION("{}") { - check("\xDE\x00\x00", DeserializationError::Ok); - } - SECTION("{H:1}") { - check("\xDE\x00\x01\xA1H\x01", - DeserializationError::NoMemory); - check( - "\xDE\x00\x01\xA1H\x01", DeserializationError::Ok); - } - SECTION("{H:1,W:2}") { - check( - "\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::NoMemory); - check( - "\xDE\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok); - } - } - - SECTION("map 32") { - SECTION("{}") { - check("\xDF\x00\x00\x00\x00", - DeserializationError::Ok); - } - SECTION("{H:1}") { - check("\xDF\x00\x00\x00\x01\xA1H\x01", - DeserializationError::NoMemory); - check( - "\xDF\x00\x00\x00\x01\xA1H\x01", DeserializationError::Ok); - } - SECTION("{H:1,W:2}") { - check( - "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", - DeserializationError::NoMemory); - check( - "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok); - } - } -} diff --git a/extras/tests/MsgPackDeserializer/deserializeVariant.cpp b/extras/tests/MsgPackDeserializer/deserializeVariant.cpp index 87f38d6e..1473ddba 100644 --- a/extras/tests/MsgPackDeserializer/deserializeVariant.cpp +++ b/extras/tests/MsgPackDeserializer/deserializeVariant.cpp @@ -5,8 +5,8 @@ #include #include -template -static void check(const char* input, U expected) { +template +static void checkValue(const char* input, T expected) { DynamicJsonDocument doc(4096); DeserializationError error = deserializeMsgPack(doc, input); @@ -16,132 +16,260 @@ static void check(const char* input, U expected) { REQUIRE(doc.as() == expected); } -#if ARDUINOJSON_USE_LONG_LONG == 0 -static void checkNotSupported(const char* input) { - DynamicJsonDocument doc(4096); - DeserializationError error = deserializeMsgPack(doc, input); - REQUIRE(error == DeserializationError::Ok); - REQUIRE(doc.isNull()); -} -#endif - -static void checkIsNull(const char* input) { - DynamicJsonDocument doc(4096); +static void checkError(size_t capacity, const char* input, + DeserializationError expected) { + DynamicJsonDocument doc(capacity); DeserializationError error = deserializeMsgPack(doc, input); - REQUIRE(error == DeserializationError::Ok); - REQUIRE(doc.as().isNull()); + CAPTURE(input); + REQUIRE(error == expected); } TEST_CASE("deserialize MsgPack value") { SECTION("nil") { - checkIsNull("\xc0"); + checkValue("\xc0", nullptr); } SECTION("bool") { - check("\xc2", false); - check("\xc3", true); + checkValue("\xc2", false); + checkValue("\xc3", true); } SECTION("positive fixint") { - check("\x00", 0); - check("\x7F", 127); + checkValue("\x00", 0); + checkValue("\x7F", 127); } SECTION("negative fixint") { - check("\xe0", -32); - check("\xff", -1); + checkValue("\xe0", -32); + checkValue("\xff", -1); } SECTION("uint 8") { - check("\xcc\x00", 0); - check("\xcc\xff", 255); + checkValue("\xcc\x00", 0); + checkValue("\xcc\xff", 255); } SECTION("uint 16") { - check("\xcd\x00\x00", 0); - check("\xcd\xFF\xFF", 65535); - check("\xcd\x30\x39", 12345); + checkValue("\xcd\x00\x00", 0); + checkValue("\xcd\xFF\xFF", 65535); + checkValue("\xcd\x30\x39", 12345); } SECTION("uint 32") { - check("\xCE\x00\x00\x00\x00", 0x00000000U); - check("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU); - check("\xCE\x12\x34\x56\x78", 0x12345678U); + checkValue("\xCE\x00\x00\x00\x00", 0x00000000U); + checkValue("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU); + checkValue("\xCE\x12\x34\x56\x78", 0x12345678U); } SECTION("uint 64") { #if ARDUINOJSON_USE_LONG_LONG - check("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U); - check("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - 0xFFFFFFFFFFFFFFFFU); - check("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", - 0x123456789ABCDEF0U); + checkValue("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U); + checkValue("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + 0xFFFFFFFFFFFFFFFFU); + checkValue("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", + 0x123456789ABCDEF0U); #else - checkNotSupported("\xCF\x00\x00\x00\x00\x00\x00\x00\x00"); - checkNotSupported("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); - checkNotSupported("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0"); + checkValue("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", nullptr); + checkValue("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr); + checkValue("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr); #endif } SECTION("int 8") { - check("\xd0\x00", 0); - check("\xd0\xff", -1); + checkValue("\xd0\x00", 0); + checkValue("\xd0\xff", -1); } SECTION("int 16") { - check("\xD1\x00\x00", 0); - check("\xD1\xFF\xFF", -1); - check("\xD1\xCF\xC7", -12345); + checkValue("\xD1\x00\x00", 0); + checkValue("\xD1\xFF\xFF", -1); + checkValue("\xD1\xCF\xC7", -12345); } SECTION("int 32") { - check("\xD2\x00\x00\x00\x00", 0); - check("\xD2\xFF\xFF\xFF\xFF", -1); - check("\xD2\xB6\x69\xFD\x2E", -1234567890); + checkValue("\xD2\x00\x00\x00\x00", 0); + checkValue("\xD2\xFF\xFF\xFF\xFF", -1); + checkValue("\xD2\xB6\x69\xFD\x2E", -1234567890); } SECTION("int 64") { #if ARDUINOJSON_USE_LONG_LONG - check("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", int64_t(0U)); - check("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - int64_t(0xFFFFFFFFFFFFFFFFU)); - check("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", - int64_t(0x123456789ABCDEF0)); + checkValue("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", int64_t(0U)); + checkValue("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + int64_t(0xFFFFFFFFFFFFFFFFU)); + checkValue("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", + int64_t(0x123456789ABCDEF0)); #else - checkNotSupported("\xD3\x00\x00\x00\x00\x00\x00\x00\x00"); - checkNotSupported("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); - checkNotSupported("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0"); + checkValue("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", nullptr); + checkValue("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", nullptr); + checkValue("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", nullptr); #endif } SECTION("float 32") { - check("\xCA\x00\x00\x00\x00", 0.0f); - check("\xCA\x40\x48\xF5\xC3", 3.14f); + checkValue("\xCA\x00\x00\x00\x00", 0.0f); + checkValue("\xCA\x40\x48\xF5\xC3", 3.14f); } SECTION("float 64") { - check("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0); - check("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415); + checkValue("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0); + checkValue("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415); } SECTION("fixstr") { - check("\xA0", std::string("")); - check("\xABhello world", std::string("hello world")); - check("\xBFhello world hello world hello !", - std::string("hello world hello world hello !")); + checkValue("\xA0", std::string("")); + checkValue("\xABhello world", std::string("hello world")); + checkValue("\xBFhello world hello world hello !", + std::string("hello world hello world hello !")); } SECTION("str 8") { - check("\xd9\x05hello", std::string("hello")); + checkValue("\xd9\x05hello", std::string("hello")); } SECTION("str 16") { - check("\xda\x00\x05hello", std::string("hello")); + checkValue("\xda\x00\x05hello", std::string("hello")); } SECTION("str 32") { - check("\xdb\x00\x00\x00\x05hello", std::string("hello")); + checkValue("\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); + } } } diff --git a/extras/tests/MsgPackDeserializer/filter.cpp b/extras/tests/MsgPackDeserializer/filter.cpp index 78700db6..f84c3c3e 100644 --- a/extras/tests/MsgPackDeserializer/filter.cpp +++ b/extras/tests/MsgPackDeserializer/filter.cpp @@ -10,10 +10,10 @@ using namespace ArduinoJson::detail; TEST_CASE("deserializeMsgPack() filter") { - StaticJsonDocument<4096> doc; + DynamicJsonDocument doc(4096); DeserializationError error; - StaticJsonDocument<200> filter; + DynamicJsonDocument filter(200); DeserializationOption::Filter filterOpt(filter); SECTION("root is fixmap") { @@ -1032,10 +1032,10 @@ TEST_CASE("deserializeMsgPack() filter") { TEST_CASE("Zero-copy mode") { // issue #1697 char input[] = "\x82\xA7include\x01\xA6ignore\x02"; - StaticJsonDocument<256> filter; + DynamicJsonDocument filter(256); filter["include"] = true; - StaticJsonDocument<256> doc; + DynamicJsonDocument doc(256); DeserializationError err = deserializeMsgPack(doc, input, 18, DeserializationOption::Filter(filter)); @@ -1044,8 +1044,8 @@ TEST_CASE("Zero-copy mode") { // issue #1697 } TEST_CASE("Overloads") { - StaticJsonDocument<256> doc; - StaticJsonDocument<256> filter; + DynamicJsonDocument doc(256); + DynamicJsonDocument filter(256); using namespace DeserializationOption; diff --git a/extras/tests/MsgPackDeserializer/input_types.cpp b/extras/tests/MsgPackDeserializer/input_types.cpp index 783aaa2c..c8284781 100644 --- a/extras/tests/MsgPackDeserializer/input_types.cpp +++ b/extras/tests/MsgPackDeserializer/input_types.cpp @@ -76,7 +76,7 @@ TEST_CASE("deserializeMsgPack(VLA)") { char vla[i]; memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15); - StaticJsonDocument doc; + DynamicJsonDocument doc(JSON_OBJECT_SIZE(1)); DeserializationError err = deserializeMsgPack(doc, vla); REQUIRE(err == DeserializationError::Ok); diff --git a/extras/tests/MsgPackDeserializer/misc.cpp b/extras/tests/MsgPackDeserializer/misc.cpp index 25137b35..33334e73 100644 --- a/extras/tests/MsgPackDeserializer/misc.cpp +++ b/extras/tests/MsgPackDeserializer/misc.cpp @@ -8,7 +8,7 @@ #include TEST_CASE("deserializeMsgPack() returns EmptyInput") { - StaticJsonDocument<100> doc; + DynamicJsonDocument doc(100); SECTION("from sized buffer") { DeserializationError err = deserializeMsgPack(doc, "", 0); diff --git a/keywords.txt b/keywords.txt index 3dff06bf..a4c2a6f4 100644 --- a/keywords.txt +++ b/keywords.txt @@ -37,4 +37,3 @@ JsonString KEYWORD1 DATA_TYPE JsonUInt KEYWORD1 DATA_TYPE JsonVariant KEYWORD1 DATA_TYPE JsonVariantConst KEYWORD1 DATA_TYPE -StaticJsonDocument KEYWORD1 DATA_TYPE diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index 0c8832a1..afc4255f 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -30,7 +30,6 @@ #include "ArduinoJson/Variant/JsonVariantConst.hpp" #include "ArduinoJson/Document/DynamicJsonDocument.hpp" -#include "ArduinoJson/Document/StaticJsonDocument.hpp" #include "ArduinoJson/Array/ElementProxy.hpp" #include "ArduinoJson/Array/JsonArrayImpl.hpp" diff --git a/src/ArduinoJson/Document/StaticJsonDocument.hpp b/src/ArduinoJson/Document/StaticJsonDocument.hpp deleted file mode 100644 index c95f3a7b..00000000 --- a/src/ArduinoJson/Document/StaticJsonDocument.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// ArduinoJson - https://arduinojson.org -// Copyright © 2014-2023, Benoit BLANCHON -// MIT License - -#pragma once - -#include - -ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE - -// A JsonDocument with a memory pool on the stack. -template -class StaticJsonDocument : public JsonDocument { - static const size_t _capacity = - detail::AddPadding::value>::value; - - public: - StaticJsonDocument() : JsonDocument(_buffer, _capacity) {} - - StaticJsonDocument(const StaticJsonDocument& src) - : JsonDocument(_buffer, _capacity) { - set(src); - } - - template - StaticJsonDocument( - const T& src, - typename detail::enable_if< - detail::is_convertible::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 - 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