From c37990d79120ddcba1e073220ef0599d3d8a1cb5 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 3 Jul 2023 11:53:56 +0200 Subject: [PATCH] CollectionData: `addSlot()` returns an iterator --- extras/tests/JsonDocument/MemberProxy.cpp | 2 +- extras/tests/JsonDocument/garbageCollect.cpp | 5 ++-- src/ArduinoJson/Array/ArrayData.hpp | 4 ++- src/ArduinoJson/Array/ArrayImpl.hpp | 4 --- src/ArduinoJson/Collection/CollectionData.hpp | 5 +++- src/ArduinoJson/Collection/CollectionImpl.hpp | 15 +++++++++- src/ArduinoJson/Object/ObjectData.hpp | 28 ++++++++++++++++-- src/ArduinoJson/Object/ObjectImpl.hpp | 29 ------------------- 8 files changed, 51 insertions(+), 41 deletions(-) diff --git a/extras/tests/JsonDocument/MemberProxy.cpp b/extras/tests/JsonDocument/MemberProxy.cpp index 002983fe..e6a48a39 100644 --- a/extras/tests/JsonDocument/MemberProxy.cpp +++ b/extras/tests/JsonDocument/MemberProxy.cpp @@ -400,7 +400,7 @@ TEST_CASE("MemberProxy under memory constraints") { REQUIRE(doc.is()); REQUIRE(doc.size() == 0); - REQUIRE(doc.memoryUsage() == sizeofObject(1)); + REQUIRE(doc.memoryUsage() == 0); REQUIRE(doc.overflowed() == true); } } diff --git a/extras/tests/JsonDocument/garbageCollect.cpp b/extras/tests/JsonDocument/garbageCollect.cpp index a32734fb..17c60ca1 100644 --- a/extras/tests/JsonDocument/garbageCollect.cpp +++ b/extras/tests/JsonDocument/garbageCollect.cpp @@ -48,7 +48,8 @@ TEST_CASE("JsonDocument::garbageCollect()") { REQUIRE(doc.memoryUsage() == sizeofObject(2) + sizeofString(7)); REQUIRE(doc.as() == "{\"dancing\":2}"); - REQUIRE(spyingAllocator.log() == AllocatorLog() - << AllocatorLog::AllocateFail(4096)); + REQUIRE(spyingAllocator.log() == + AllocatorLog() << AllocatorLog::AllocateFail(4096) + << AllocatorLog::AllocateFail(sizeofString(7))); } } diff --git a/src/ArduinoJson/Array/ArrayData.hpp b/src/ArduinoJson/Array/ArrayData.hpp index fe7f758f..42df1276 100644 --- a/src/ArduinoJson/Array/ArrayData.hpp +++ b/src/ArduinoJson/Array/ArrayData.hpp @@ -10,7 +10,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE class ArrayData : public CollectionData { public: - VariantData* addElement(ResourceManager* resources); + VariantData* addElement(ResourceManager* resources) { + return addSlot(resources).data(); + } static VariantData* addElement(ArrayData* array, ResourceManager* resources) { if (!array) diff --git a/src/ArduinoJson/Array/ArrayImpl.hpp b/src/ArduinoJson/Array/ArrayImpl.hpp index c1cf14f3..36aae4ff 100644 --- a/src/ArduinoJson/Array/ArrayImpl.hpp +++ b/src/ArduinoJson/Array/ArrayImpl.hpp @@ -18,10 +18,6 @@ inline ArrayData::iterator ArrayData::at(size_t index) const { return it; } -inline VariantData* ArrayData::addElement(ResourceManager* resources) { - return slotData(addSlot(resources)); -} - inline bool ArrayData::copyFrom(const ArrayData& src, ResourceManager* resources) { clear(resources); diff --git a/src/ArduinoJson/Collection/CollectionData.hpp b/src/ArduinoJson/Collection/CollectionData.hpp index a61eeebf..51bb2175 100644 --- a/src/ArduinoJson/Collection/CollectionData.hpp +++ b/src/ArduinoJson/Collection/CollectionData.hpp @@ -52,6 +52,9 @@ class CollectionIterator { const char* key() const; bool ownsKey() const; + void setKey(StringNode*); + void setKey(const char*); + VariantData* data() { return reinterpret_cast(slot_); } @@ -107,7 +110,7 @@ class CollectionData { } protected: - VariantSlot* addSlot(ResourceManager*); + iterator addSlot(ResourceManager*); private: VariantSlot* getPreviousSlot(VariantSlot*) const; diff --git a/src/ArduinoJson/Collection/CollectionImpl.hpp b/src/ArduinoJson/Collection/CollectionImpl.hpp index f54feb2f..0b9ec9af 100644 --- a/src/ArduinoJson/Collection/CollectionImpl.hpp +++ b/src/ArduinoJson/Collection/CollectionImpl.hpp @@ -17,6 +17,18 @@ inline const char* CollectionIterator::key() const { return slot_->key(); } +inline void CollectionIterator::setKey(const char* s) { + ARDUINOJSON_ASSERT(slot_ != nullptr); + ARDUINOJSON_ASSERT(s != nullptr); + return slot_->setKey(s); +} + +inline void CollectionIterator::setKey(StringNode* s) { + ARDUINOJSON_ASSERT(slot_ != nullptr); + ARDUINOJSON_ASSERT(s != nullptr); + return slot_->setKey(s); +} + inline bool CollectionIterator::ownsKey() const { ARDUINOJSON_ASSERT(slot_ != nullptr); return slot_->ownsKey(); @@ -27,7 +39,8 @@ inline void CollectionIterator::next() { slot_ = slot_->next(); } -inline VariantSlot* CollectionData::addSlot(ResourceManager* resources) { +inline CollectionData::iterator CollectionData::addSlot( + ResourceManager* resources) { auto slot = resources->allocVariant(); if (!slot) return nullptr; diff --git a/src/ArduinoJson/Object/ObjectData.hpp b/src/ArduinoJson/Object/ObjectData.hpp index f4ce5fa6..2277f34b 100644 --- a/src/ArduinoJson/Object/ObjectData.hpp +++ b/src/ArduinoJson/Object/ObjectData.hpp @@ -10,10 +10,34 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE class ObjectData : public CollectionData { public: - VariantData* addMember(StringNode* key, ResourceManager* resources); + VariantData* addMember(StringNode* key, ResourceManager* resources) { + ARDUINOJSON_ASSERT(key != nullptr); + auto it = addSlot(resources); + if (it.done()) + return nullptr; + + it.setKey(key); + return it.data(); + } template - VariantData* addMember(TAdaptedString key, ResourceManager* resources); + VariantData* addMember(TAdaptedString key, ResourceManager* resources) { + ARDUINOJSON_ASSERT(!key.isNull()); + if (key.isLinked()) { + auto it = addSlot(resources); + if (!it.done()) + it.setKey(key.data()); + return it.data(); + } else { + auto storedKey = resources->saveString(key); + if (!storedKey) + return nullptr; + auto it = addSlot(resources); + if (!it.done()) + it.setKey(storedKey); + return it.data(); + } + } bool copyFrom(const ObjectData& src, ResourceManager* resources); diff --git a/src/ArduinoJson/Object/ObjectImpl.hpp b/src/ArduinoJson/Object/ObjectImpl.hpp index 51d5a851..d13ebae0 100644 --- a/src/ArduinoJson/Object/ObjectImpl.hpp +++ b/src/ArduinoJson/Object/ObjectImpl.hpp @@ -9,35 +9,6 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE -inline VariantData* ObjectData::addMember(StringNode* key, - ResourceManager* resources) { - ARDUINOJSON_ASSERT(key != nullptr); - auto slot = addSlot(resources); - if (!slot) - return nullptr; - - slot->setKey(key); - return slot->data(); -} - -template -inline VariantData* ObjectData::addMember(TAdaptedString key, - ResourceManager* resources) { - ARDUINOJSON_ASSERT(!key.isNull()); - auto slot = addSlot(resources); - if (!slot) - return nullptr; - if (key.isLinked()) - slot->setKey(key.data()); - else { - auto storedKey = resources->saveString(key); - if (!storedKey) - return nullptr; - slot->setKey(storedKey); - } - return slot->data(); -} - inline bool ObjectData::copyFrom(const ObjectData& src, ResourceManager* resources) { clear(resources);