Store object members with two slots: one for the key and one for the value

This commit is contained in:
Benoit Blanchon
2024-08-24 10:45:51 +02:00
parent a2b09bfbd2
commit 09c89dcacf
24 changed files with 229 additions and 173 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 8,
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 6,
"sizeof(VariantSlot)");
void setup() {}
+1 -1
View File
@@ -8,7 +8,7 @@ static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 16,
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 12,
"sizeof(VariantSlot)");
int main() {}
+1 -1
View File
@@ -8,7 +8,7 @@ static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 24,
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 16,
"sizeof(VariantSlot)");
int main() {}
+1 -1
View File
@@ -8,7 +8,7 @@ static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 24,
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 16,
"sizeof(VariantSlot)");
int main() {}
+6
View File
@@ -68,6 +68,12 @@ TEST_CASE("JsonArray::remove()") {
REQUIRE(array[1] == 2);
}
SECTION("remove end()") {
array.remove(array.end());
REQUIRE(3 == array.size());
}
SECTION("In a loop") {
for (JsonArray::iterator it = array.begin(); it != array.end(); ++it) {
if (*it == 2)
+2 -2
View File
@@ -308,12 +308,12 @@ TEST_CASE("deserialize JSON object") {
REQUIRE(doc["a"] == 2);
}
SECTION("NUL in keys") { // we don't support NULs in keys
SECTION("NUL in keys") {
DeserializationError err =
deserializeJson(doc, "{\"x\\u0000a\":1,\"x\\u0000b\":2}");
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "{\"x\":2}");
REQUIRE(doc.as<std::string>() == "{\"x\\u0000a\":1,\"x\\u0000b\":2}");
}
}
+36 -4
View File
@@ -345,12 +345,12 @@ TEST_CASE("Deduplicate keys") {
}
TEST_CASE("MemberProxy under memory constraints") {
KillswitchAllocator killswitch;
SpyingAllocator spy(&killswitch);
TimebombAllocator timebomb(1);
SpyingAllocator spy(&timebomb);
JsonDocument doc(&spy);
SECTION("key allocation fails") {
killswitch.on();
SECTION("key slot allocation fails") {
timebomb.setCountdown(0);
doc["hello"_s] = "world";
@@ -361,4 +361,36 @@ TEST_CASE("MemberProxy under memory constraints") {
AllocateFail(sizeofPool()),
});
}
SECTION("value slot allocation fails") {
timebomb.setCountdown(1);
// fill the pool entirely, but leave one slot for the key
doc["foo"][ARDUINOJSON_POOL_CAPACITY - 4] = 1;
REQUIRE(doc.overflowed() == false);
doc["hello"_s] = "world";
REQUIRE(doc.is<JsonObject>());
REQUIRE(doc.size() == 1);
REQUIRE(doc.overflowed() == true);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
AllocateFail(sizeofPool()),
});
}
SECTION("key string allocation fails") {
timebomb.setCountdown(1);
doc["hello"_s] = "world";
REQUIRE(doc.is<JsonObject>());
REQUIRE(doc.size() == 0);
REQUIRE(doc.overflowed() == true);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
AllocateFail(sizeofString("hello")),
});
}
}
+1 -1
View File
@@ -178,7 +178,7 @@ TEST_CASE("JsonDocument::shrinkToFit()") {
AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("abcdefg")),
Reallocate(sizeofPool(), sizeofPool(1)),
Reallocate(sizeofPool(), sizeofPool(2)),
});
}
}