Call shrinkToFit() in deserializeJson() and deserializeMsgPack()

This commit is contained in:
Benoit Blanchon
2023-07-31 17:34:17 +02:00
parent 752d01a7f1
commit 218a12ca46
14 changed files with 209 additions and 67 deletions

View File

@ -25,3 +25,4 @@ HEAD
* Remove `JsonDocument::memoryUsage()`
* Remove `JsonDocument::garbageCollect()`
* Add `deserializeJson(JsonVariant, ...)` and `deserializeMsgPack(JsonVariant, ...)` (#1226)
* Call `shrinkToFit()` in `deserializeJson()` and `deserializeMsgPack()`

View File

@ -249,13 +249,14 @@ TEST_CASE("deserialize JSON array") {
SECTION("Should clear the JsonArray") {
deserializeJson(doc, "[1,2,3,4]");
deserializeJson(doc, "[]");
JsonArray arr = doc.as<JsonArray>();
spy.clearLog();
deserializeJson(doc, "[]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(arr.size() == 0);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Deallocate(sizeofPool()),
Deallocate(sizeofArray(4)),
});
}
}
@ -312,6 +313,7 @@ TEST_CASE("deserialize JSON array under memory constraints") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("1234567")),
Reallocate(sizeofPool(), sizeofArray(1)),
});
}
}

View File

@ -9,6 +9,9 @@
#include "Allocators.hpp"
using ArduinoJson::detail::sizeofArray;
using ArduinoJson::detail::sizeofObject;
TEST_CASE("deserializeJson(JsonDocument&)") {
SpyingAllocator spy;
JsonDocument doc(&spy);
@ -23,6 +26,7 @@ TEST_CASE("deserializeJson(JsonDocument&)") {
Deallocate(sizeofPool()),
Deallocate(sizeofString("hello")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofArray(1)),
});
}
@ -39,9 +43,11 @@ TEST_CASE("deserializeJson(JsonVariant)") {
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "[[42]]");
REQUIRE(spy.log() == AllocatorLog{
Deallocate(sizeofString("hello")),
});
REQUIRE(spy.log() ==
AllocatorLog{
Deallocate(sizeofString("hello")),
Reallocate(sizeofPool(), sizeofArray(1) + sizeofArray(1)),
});
}
SECTION("variant is unbound") {
@ -64,17 +70,22 @@ TEST_CASE("deserializeJson(ElementProxy)") {
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "[[42]]");
REQUIRE(spy.log() == AllocatorLog{
Deallocate(sizeofString("hello")),
});
REQUIRE(spy.log() ==
AllocatorLog{
Deallocate(sizeofString("hello")),
Reallocate(sizeofPool(), sizeofArray(1) + sizeofArray(1)),
});
}
SECTION("element must be created exists") {
SECTION("element must be created") {
auto err = deserializeJson(doc[1], "[42]");
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "[\"hello\",[42]]");
REQUIRE(spy.log() == AllocatorLog{});
REQUIRE(spy.log() ==
AllocatorLog{
Reallocate(sizeofPool(), sizeofArray(2) + sizeofArray(1)),
});
}
}
@ -89,9 +100,11 @@ TEST_CASE("deserializeJson(MemberProxy)") {
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "{\"hello\":[42]}");
REQUIRE(spy.log() == AllocatorLog{
Deallocate(sizeofString("world")),
});
REQUIRE(spy.log() ==
AllocatorLog{
Deallocate(sizeofString("world")),
Reallocate(sizeofPool(), sizeofObject(1) + sizeofArray(1)),
});
}
SECTION("member must be created exists") {
@ -99,6 +112,9 @@ TEST_CASE("deserializeJson(MemberProxy)") {
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "{\"hello\":\"world\",\"value\":[42]}");
REQUIRE(spy.log() == AllocatorLog{});
REQUIRE(spy.log() ==
AllocatorLog{
Reallocate(sizeofPool(), sizeofObject(2) + sizeofArray(1)),
});
}
}

View File

@ -711,20 +711,6 @@ TEST_CASE("Filtering") {
}
}
TEST_CASE("Zero-copy mode") { // issue #1697
char input[] = "{\"include\":42,\"exclude\":666}";
JsonDocument filter;
filter["include"] = true;
JsonDocument doc;
DeserializationError err =
deserializeJson(doc, input, DeserializationOption::Filter(filter));
REQUIRE(err == DeserializationError::Ok);
CHECK(doc.as<std::string>() == "{\"include\":42}");
}
TEST_CASE("Overloads") {
JsonDocument doc;
JsonDocument filter;
@ -815,3 +801,17 @@ TEST_CASE("Overloads") {
}
#endif
}
TEST_CASE("shrink filter") {
JsonDocument doc;
SpyingAllocator spy;
JsonDocument filter(&spy);
filter["a"] = true;
spy.clearLog();
deserializeJson(doc, "{}", DeserializationOption::Filter(filter));
REQUIRE(spy.log() == AllocatorLog{
Reallocate(sizeofPool(), sizeofObject(1)),
});
}

View File

@ -29,6 +29,7 @@ TEST_CASE("deserializeJson(char*)") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("world")),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}

View File

@ -7,6 +7,8 @@
#include "Allocators.hpp"
using ArduinoJson::detail::sizeofArray;
TEST_CASE("deserializeJson() misc cases") {
SpyingAllocator spy;
JsonDocument doc(&spy);
@ -35,12 +37,13 @@ TEST_CASE("deserializeJson() misc cases") {
SECTION("Should clear the JsonVariant") {
deserializeJson(doc, "[1,2,3]");
spy.clearLog();
deserializeJson(doc, "{}");
REQUIRE(doc.is<JsonObject>());
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Deallocate(sizeofPool()),
Deallocate(sizeofArray(3)),
});
}
}

View File

@ -296,6 +296,7 @@ TEST_CASE("deserialize JSON object") {
Deallocate(sizeofString("b")),
Deallocate(sizeofString("c")),
Deallocate(sizeofStringBuffer()),
Reallocate(sizeofPool(), sizeofObject(2) + sizeofObject(1)),
});
}
@ -318,22 +319,17 @@ TEST_CASE("deserialize JSON object") {
SECTION("Should clear the JsonObject") {
deserializeJson(doc, "{\"hello\":\"world\"}");
spy.clearLog();
deserializeJson(doc, "{}");
JsonObject obj = doc.as<JsonObject>();
REQUIRE(doc.is<JsonObject>());
REQUIRE(obj.size() == 0);
REQUIRE(spy.log() ==
AllocatorLog{
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("hello")),
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("world")),
Deallocate(sizeofPool()),
Deallocate(sizeofString("hello")),
Deallocate(sizeofString("world")),
});
REQUIRE(doc.size() == 0);
REQUIRE(spy.log() == AllocatorLog{
Deallocate(sizeofObject(1)),
Deallocate(sizeofString("hello")),
Deallocate(sizeofString("world")),
});
}
SECTION("Issue #1335") {

View File

@ -120,6 +120,7 @@ TEST_CASE("Allocation of the key fails") {
Reallocate(sizeofStringBuffer(), sizeofString("hello")),
Allocate(sizeofPool()),
AllocateFail(sizeofStringBuffer()),
ReallocateFail(sizeofPool(), sizeofObject(1)),
});
}
@ -141,6 +142,7 @@ TEST_CASE("Allocation of the key fails") {
Reallocate(sizeofStringBuffer(), sizeofString("hello")),
Allocate(sizeofPool()),
AllocateFail(sizeofStringBuffer()),
ReallocateFail(sizeofPool(), sizeofObject(1)),
});
}
}
@ -171,6 +173,7 @@ TEST_CASE("Deduplicate values") {
Reallocate(sizeofStringBuffer(), sizeofString("example")),
Allocate(sizeofStringBuffer()),
Deallocate(sizeofStringBuffer()),
Reallocate(sizeofPool(), sizeofArray(2)),
});
}
@ -190,5 +193,6 @@ TEST_CASE("Deduplicate keys") {
Reallocate(sizeofStringBuffer(), sizeofString("example")),
Allocate(sizeofStringBuffer()),
Deallocate(sizeofStringBuffer()),
Reallocate(sizeofPool(), sizeofArray(2) + 2 * sizeofObject(1)),
});
}

View File

@ -9,6 +9,9 @@
#include "Allocators.hpp"
using ArduinoJson::detail::sizeofArray;
using ArduinoJson::detail::sizeofObject;
TEST_CASE("deserializeMsgPack(JsonDocument&)") {
SpyingAllocator spy;
JsonDocument doc(&spy);
@ -23,6 +26,7 @@ TEST_CASE("deserializeMsgPack(JsonDocument&)") {
Deallocate(sizeofPool()),
Deallocate(sizeofString("hello")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofArray(1)),
});
}
@ -39,9 +43,11 @@ TEST_CASE("deserializeMsgPack(JsonVariant)") {
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "[[42]]");
REQUIRE(spy.log() == AllocatorLog{
Deallocate(sizeofString("hello")),
});
REQUIRE(spy.log() ==
AllocatorLog{
Deallocate(sizeofString("hello")),
Reallocate(sizeofPool(), sizeofArray(1) + sizeofArray(1)),
});
}
SECTION("variant is unbound") {
@ -64,9 +70,11 @@ TEST_CASE("deserializeMsgPack(ElementProxy)") {
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "[[42]]");
REQUIRE(spy.log() == AllocatorLog{
Deallocate(sizeofString("hello")),
});
REQUIRE(spy.log() ==
AllocatorLog{
Deallocate(sizeofString("hello")),
Reallocate(sizeofPool(), sizeofArray(1) + sizeofArray(1)),
});
}
SECTION("element must be created exists") {
@ -74,7 +82,10 @@ TEST_CASE("deserializeMsgPack(ElementProxy)") {
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "[\"hello\",[42]]");
REQUIRE(spy.log() == AllocatorLog{});
REQUIRE(spy.log() ==
AllocatorLog{
Reallocate(sizeofPool(), sizeofArray(2) + sizeofArray(1)),
});
}
}
@ -91,14 +102,18 @@ TEST_CASE("deserializeMsgPack(MemberProxy)") {
REQUIRE(doc.as<std::string>() == "{\"hello\":[42]}");
REQUIRE(spy.log() == AllocatorLog{
Deallocate(sizeofString("world")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
SECTION("member must be created exists") {
SECTION("member must be created") {
auto err = deserializeMsgPack(doc["value"], "\x91\x2A");
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "{\"hello\":\"world\",\"value\":[42]}");
REQUIRE(spy.log() == AllocatorLog{});
REQUIRE(spy.log() ==
AllocatorLog{
Reallocate(sizeofPool(), sizeofObject(2) + sizeofArray(1)),
});
}
}

View File

@ -80,6 +80,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -105,6 +106,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -119,6 +121,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -133,6 +136,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -147,6 +151,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -161,6 +166,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -175,6 +181,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -189,6 +196,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -203,6 +211,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -218,6 +227,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -233,6 +243,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -249,6 +260,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -265,6 +277,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -280,6 +293,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -296,6 +310,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -310,6 +325,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -324,6 +340,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -338,6 +355,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -353,6 +371,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -367,6 +386,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -381,6 +401,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -396,6 +417,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -410,6 +432,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -425,6 +448,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -443,6 +467,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -458,6 +483,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -475,6 +501,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -494,6 +521,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -511,6 +539,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -528,6 +557,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -545,6 +575,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -562,6 +593,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -581,6 +613,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -598,6 +631,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -615,6 +649,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
@ -632,6 +667,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofObject(1)),
});
}
}
@ -662,6 +698,8 @@ TEST_CASE("deserializeMsgPack() filter") {
Reallocate(sizeofStringBuffer(), sizeofString("measure")),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2) + sizeofArray(2) +
2 * sizeofObject(1)),
});
}
@ -686,6 +724,8 @@ TEST_CASE("deserializeMsgPack() filter") {
Reallocate(sizeofStringBuffer(), sizeofString("measure")),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2) + sizeofArray(2) +
2 * sizeofObject(1)),
});
}
@ -710,6 +750,8 @@ TEST_CASE("deserializeMsgPack() filter") {
Reallocate(sizeofStringBuffer(), sizeofString("measure")),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2) + sizeofArray(2) +
2 * sizeofObject(1)),
});
}
@ -726,6 +768,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -742,6 +785,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -758,6 +802,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -774,6 +819,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -790,6 +836,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -806,6 +853,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -822,6 +870,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -839,6 +888,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -857,6 +907,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -873,6 +924,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -889,6 +941,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -906,6 +959,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -924,6 +978,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -941,6 +996,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -959,6 +1015,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -975,6 +1032,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1004,6 +1062,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1021,6 +1080,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1040,6 +1100,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1061,6 +1122,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
}
@ -1091,6 +1153,7 @@ TEST_CASE("deserializeMsgPack() filter") {
CHECK(doc.as<std::string>() == "[1,2,3]");
CHECK(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofArray(3)),
});
}
}
@ -1121,6 +1184,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Reallocate(sizeofStringBuffer(), sizeofString("measure")),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2) + sizeofObject(1)),
});
}
@ -1143,6 +1207,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Reallocate(sizeofStringBuffer(), sizeofString("measure")),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2) + sizeofObject(1)),
});
}
@ -1166,6 +1231,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Reallocate(sizeofStringBuffer(), sizeofString("measure")),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2) + sizeofObject(1)),
});
}
@ -1182,6 +1248,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1198,6 +1265,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1214,6 +1282,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1230,6 +1299,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1246,6 +1316,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1262,6 +1333,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1278,6 +1350,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1294,6 +1367,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1312,6 +1386,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1328,6 +1403,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1344,6 +1420,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1360,6 +1437,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1373,12 +1451,12 @@ TEST_CASE("deserializeMsgPack() filter") {
CHECK(doc.as<std::string>() == "{\"onlyobj\":null,\"include\":42}");
CHECK(spy.log() ==
AllocatorLog{
// string builder's buffer
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")),
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1390,12 +1468,12 @@ TEST_CASE("deserializeMsgPack() filter") {
CHECK(doc.as<std::string>() == "{\"onlyobj\":null,\"include\":42}");
CHECK(spy.log() ==
AllocatorLog{
// string builder's buffer
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")),
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1409,12 +1487,12 @@ TEST_CASE("deserializeMsgPack() filter") {
CHECK(doc.as<std::string>() == "{\"onlyobj\":null,\"include\":42}");
CHECK(spy.log() ==
AllocatorLog{
// string builder's buffer
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")),
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1426,12 +1504,12 @@ TEST_CASE("deserializeMsgPack() filter") {
CHECK(doc.as<std::string>() == "{\"onlyobj\":null,\"include\":42}");
CHECK(spy.log() ==
AllocatorLog{
// string builder's buffer
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")),
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1456,12 +1534,12 @@ TEST_CASE("deserializeMsgPack() filter") {
CHECK(spy.log() ==
AllocatorLog{
// string builder's buffer
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")),
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1473,12 +1551,12 @@ TEST_CASE("deserializeMsgPack() filter") {
CHECK(doc.as<std::string>() == "{\"onlyobj\":null,\"include\":42}");
CHECK(spy.log() ==
AllocatorLog{
// string builder's buffer
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")),
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1492,12 +1570,12 @@ TEST_CASE("deserializeMsgPack() filter") {
CHECK(doc.as<std::string>() == "{\"onlyobj\":null,\"include\":42}");
CHECK(spy.log() ==
AllocatorLog{
// string builder's buffer
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("onlyarr")),
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
@ -1517,6 +1595,7 @@ TEST_CASE("deserializeMsgPack() filter") {
Allocate(sizeofPool()),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("include")),
Reallocate(sizeofPool(), sizeofObject(2)),
});
}
}

View File

@ -110,6 +110,17 @@
# define ARDUINOJSON_INITIAL_POOL_COUNT 4
#endif
// Automatically call shrinkToFit() from deserializeXxx()
// Disabled by default on 8-bit platforms because it's not worth the increase in
// code size
#ifndef ARDUINOJSON_AUTO_SHRINK
# if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ <= 2
# define ARDUINOJSON_AUTO_SHRINK 0
# else
# define ARDUINOJSON_AUTO_SHRINK 1
# endif
#endif
#ifdef ARDUINO
// Enable support for Arduino's String class

View File

@ -4,14 +4,21 @@
#pragma once
#include <ArduinoJson/Namespace.hpp>
#include <ArduinoJson/Variant/JsonVariant.hpp>
#include <ArduinoJson/Variant/VariantAttorney.hpp>
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
namespace DeserializationOption {
class Filter {
public:
explicit Filter(JsonVariantConst v) : variant_(v) {}
#if ARDUINOJSON_AUTO_SHRINK
explicit Filter(JsonDocument& doc) : variant_(doc) {
doc.shrinkToFit();
}
#endif
explicit Filter(JsonVariantConst variant) : variant_(variant) {}
bool allow() const {
return variant_;

View File

@ -43,8 +43,12 @@ DeserializationError doDeserialize(TDestination&& dst, TReader reader,
return DeserializationError::NoMemory;
auto resources = VariantAttorney::getResourceManager(dst);
dst.clear();
return TDeserializer<TReader>(resources, reader)
.parse(*data, options.filter, options.nestingLimit);
auto err = TDeserializer<TReader>(resources, reader)
.parse(*data, options.filter, options.nestingLimit);
#if ARDUINOJSON_AUTO_SHRINK
resources->shrinkToFit();
#endif
return err;
}
template <template <typename> class TDeserializer, typename TDestination,

View File

@ -26,9 +26,12 @@ inline void VariantPool::destroy(Allocator* allocator) {
}
inline void VariantPool::shrinkToFit(Allocator* allocator) {
slots_ = reinterpret_cast<VariantSlot*>(
auto newSlots = reinterpret_cast<VariantSlot*>(
allocator->reallocate(slots_, slotsToBytes(usage_)));
capacity_ = usage_;
if (newSlots) {
slots_ = newSlots;
capacity_ = usage_;
}
}
inline SlotWithId VariantPool::allocSlot() {