diff --git a/src/ArduinoJson/Json/JsonDeserializer.hpp b/src/ArduinoJson/Json/JsonDeserializer.hpp index d6b5afee..9602496a 100644 --- a/src/ArduinoJson/Json/JsonDeserializer.hpp +++ b/src/ArduinoJson/Json/JsonDeserializer.hpp @@ -286,7 +286,7 @@ class JsonDeserializer { slot->setKey(savedKey); object.add(slot); } else { - variantRelease(slot->data(), pool_); + slot->data()->setNull(pool_); } // Parse value diff --git a/src/ArduinoJson/Variant/SlotFunctions.hpp b/src/ArduinoJson/Variant/SlotFunctions.hpp index c0683c0d..00bebf37 100644 --- a/src/ArduinoJson/Variant/SlotFunctions.hpp +++ b/src/ArduinoJson/Variant/SlotFunctions.hpp @@ -18,11 +18,11 @@ inline size_t slotSize(const VariantSlot* var) { return n; } -inline void slotRelease(const VariantSlot* slot, MemoryPool* pool) { +inline void slotRelease(VariantSlot* slot, MemoryPool* pool) { ARDUINOJSON_ASSERT(slot != nullptr); if (slot->ownsKey()) pool->dereferenceString(slot->key()); - variantRelease(slot->data(), pool); + slot->data()->setNull(pool); } ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantData.hpp b/src/ArduinoJson/Variant/VariantData.hpp index 19fe1559..ba6545d6 100644 --- a/src/ArduinoJson/Variant/VariantData.hpp +++ b/src/ArduinoJson/Variant/VariantData.hpp @@ -16,6 +16,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE template T parseNumber(const char* s); +void slotRelease(VariantSlot* slot, MemoryPool* pool); class VariantData { VariantContent content_; // must be first to allow cast from array to variant @@ -176,13 +177,6 @@ class VariantData { return slotData(object->get(key)); } - const char* getOwnedString() const { - if (flags_ & OWNED_VALUE_BIT) - return content_.asOwnedString->data; - else - return nullptr; - } - bool isArray() const { return (flags_ & VALUE_IS_ARRAY) != 0; } @@ -257,11 +251,21 @@ class VariantData { content_.asBoolean = value; } + void setBoolean(bool value, MemoryPool* pool) { + release(pool); + setBoolean(value); + } + void setFloat(JsonFloat value) { setType(VALUE_IS_FLOAT); content_.asFloat = value; } + void setFloat(JsonFloat value, MemoryPool* pool) { + release(pool); + setFloat(value); + } + template typename enable_if::value>::type setInteger(T value) { setType(VALUE_IS_SIGNED_INTEGER); @@ -274,16 +278,32 @@ class VariantData { content_.asUnsignedInteger = static_cast(value); } + template + void setInteger(T value, MemoryPool* pool) { + release(pool); + setInteger(value); + } + void setNull() { setType(VALUE_IS_NULL); } + void setNull(MemoryPool* pool) { + release(pool); + setNull(); + } + void setRawString(StringNode* s) { ARDUINOJSON_ASSERT(s); setType(VALUE_IS_RAW_STRING); content_.asOwnedString = s; } + void setRawString(StringNode* s, MemoryPool* pool) { + release(pool); + setRawString(s); + } + void setString(const char* s) { ARDUINOJSON_ASSERT(s); setType(VALUE_IS_LINKED_STRING); @@ -306,17 +326,38 @@ class VariantData { return content_.asCollection; } + CollectionData& toArray(MemoryPool* pool) { + release(pool); + return toArray(); + } + CollectionData& toObject() { setType(VALUE_IS_OBJECT); content_.asCollection.clear(); return content_.asCollection; } + CollectionData& toObject(MemoryPool* pool) { + release(pool); + return toObject(); + } + uint8_t type() const { return flags_ & VALUE_MASK; } private: + void release(MemoryPool* pool) { + if (flags_ & OWNED_VALUE_BIT) + pool->dereferenceString(content_.asOwnedString->data); + + auto c = asCollection(); + if (c) { + for (auto slot = c->head(); slot; slot = slot->next()) + slotRelease(slot, pool); + } + } + void setType(uint8_t t) { flags_ &= OWNED_KEY_BIT; flags_ |= t; diff --git a/src/ArduinoJson/Variant/VariantFunctions.hpp b/src/ArduinoJson/Variant/VariantFunctions.hpp index ef74096a..f6745d02 100644 --- a/src/ArduinoJson/Variant/VariantFunctions.hpp +++ b/src/ArduinoJson/Variant/VariantFunctions.hpp @@ -11,7 +11,6 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE -void slotRelease(const VariantSlot* slot, MemoryPool* pool); bool collectionCopy(CollectionData* dst, const CollectionData* src, MemoryPool* pool); VariantData* collectionAddElement(CollectionData* array, MemoryPool* pool); @@ -30,19 +29,6 @@ inline typename TVisitor::result_type variantAccept(const VariantData* var, return visitor.visitNull(); } -inline void variantRelease(const VariantData* var, MemoryPool* pool) { - ARDUINOJSON_ASSERT(var != nullptr); - auto s = var->getOwnedString(); - if (s) - pool->dereferenceString(s); - - auto c = var->asCollection(); - if (c) { - for (auto slot = c->head(); slot; slot = slot->next()) - slotRelease(slot, pool); - } -} - inline bool variantCopyFrom(VariantData* dst, const VariantData* src, MemoryPool* pool) { if (!dst) @@ -81,31 +67,27 @@ inline bool variantCopyFrom(VariantData* dst, const VariantData* src, inline void variantSetNull(VariantData* var, MemoryPool* pool) { if (!var) return; - variantRelease(var, pool); - var->setNull(); + var->setNull(pool); } inline void variantSetBoolean(VariantData* var, bool value, MemoryPool* pool) { if (!var) return; - variantRelease(var, pool); - var->setBoolean(value); + var->setBoolean(value, pool); } inline void variantSetFloat(VariantData* var, JsonFloat value, MemoryPool* pool) { if (!var) return; - variantRelease(var, pool); - var->setFloat(value); + var->setFloat(value, pool); } template inline void variantSetInteger(VariantData* var, T value, MemoryPool* pool) { if (!var) return; - variantRelease(var, pool); - var->setInteger(value); + var->setInteger(value, pool); } template @@ -113,12 +95,10 @@ inline void variantSetString(VariantData* var, TAdaptedString value, MemoryPool* pool) { if (!var) return; - variantRelease(var, pool); + var->setNull(pool); - if (value.isNull()) { - var->setNull(); + if (value.isNull()) return; - } if (value.isLinked()) { var->setString(value.data()); @@ -137,12 +117,11 @@ inline void variantSetRawString(VariantData* var, SerializedValue value, MemoryPool* pool) { if (!var) return; - variantRelease(var, pool); auto dup = pool->saveString(adaptString(value.data(), value.size())); if (dup) - var->setRawString(dup); + var->setRawString(dup, pool); else - var->setNull(); + var->setNull(pool); } inline size_t variantSize(const VariantData* var) { @@ -152,15 +131,13 @@ inline size_t variantSize(const VariantData* var) { inline CollectionData* variantToArray(VariantData* var, MemoryPool* pool) { if (!var) return 0; - variantRelease(var, pool); - return &var->toArray(); + return &var->toArray(pool); } inline CollectionData* variantToObject(VariantData* var, MemoryPool* pool) { if (!var) return 0; - variantRelease(var, pool); - return &var->toObject(); + return &var->toObject(pool); } inline VariantData* variantGetElement(const VariantData* var, size_t index) {