Add JsonVariant::release()

This commit is contained in:
Benoit Blanchon
2023-05-25 09:35:40 +02:00
parent da45c4bc4f
commit 8ab45e6f82
4 changed files with 61 additions and 43 deletions

View File

@ -286,7 +286,7 @@ class JsonDeserializer {
slot->setKey(savedKey); slot->setKey(savedKey);
object.add(slot); object.add(slot);
} else { } else {
variantRelease(slot->data(), pool_); slot->data()->setNull(pool_);
} }
// Parse value // Parse value

View File

@ -18,11 +18,11 @@ inline size_t slotSize(const VariantSlot* var) {
return n; return n;
} }
inline void slotRelease(const VariantSlot* slot, MemoryPool* pool) { inline void slotRelease(VariantSlot* slot, MemoryPool* pool) {
ARDUINOJSON_ASSERT(slot != nullptr); ARDUINOJSON_ASSERT(slot != nullptr);
if (slot->ownsKey()) if (slot->ownsKey())
pool->dereferenceString(slot->key()); pool->dereferenceString(slot->key());
variantRelease(slot->data(), pool); slot->data()->setNull(pool);
} }
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -16,6 +16,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename T> template <typename T>
T parseNumber(const char* s); T parseNumber(const char* s);
void slotRelease(VariantSlot* slot, MemoryPool* pool);
class VariantData { class VariantData {
VariantContent content_; // must be first to allow cast from array to variant VariantContent content_; // must be first to allow cast from array to variant
@ -176,13 +177,6 @@ class VariantData {
return slotData(object->get(key)); return slotData(object->get(key));
} }
const char* getOwnedString() const {
if (flags_ & OWNED_VALUE_BIT)
return content_.asOwnedString->data;
else
return nullptr;
}
bool isArray() const { bool isArray() const {
return (flags_ & VALUE_IS_ARRAY) != 0; return (flags_ & VALUE_IS_ARRAY) != 0;
} }
@ -257,11 +251,21 @@ class VariantData {
content_.asBoolean = value; content_.asBoolean = value;
} }
void setBoolean(bool value, MemoryPool* pool) {
release(pool);
setBoolean(value);
}
void setFloat(JsonFloat value) { void setFloat(JsonFloat value) {
setType(VALUE_IS_FLOAT); setType(VALUE_IS_FLOAT);
content_.asFloat = value; content_.asFloat = value;
} }
void setFloat(JsonFloat value, MemoryPool* pool) {
release(pool);
setFloat(value);
}
template <typename T> template <typename T>
typename enable_if<is_signed<T>::value>::type setInteger(T value) { typename enable_if<is_signed<T>::value>::type setInteger(T value) {
setType(VALUE_IS_SIGNED_INTEGER); setType(VALUE_IS_SIGNED_INTEGER);
@ -274,16 +278,32 @@ class VariantData {
content_.asUnsignedInteger = static_cast<JsonUInt>(value); content_.asUnsignedInteger = static_cast<JsonUInt>(value);
} }
template <typename T>
void setInteger(T value, MemoryPool* pool) {
release(pool);
setInteger(value);
}
void setNull() { void setNull() {
setType(VALUE_IS_NULL); setType(VALUE_IS_NULL);
} }
void setNull(MemoryPool* pool) {
release(pool);
setNull();
}
void setRawString(StringNode* s) { void setRawString(StringNode* s) {
ARDUINOJSON_ASSERT(s); ARDUINOJSON_ASSERT(s);
setType(VALUE_IS_RAW_STRING); setType(VALUE_IS_RAW_STRING);
content_.asOwnedString = s; content_.asOwnedString = s;
} }
void setRawString(StringNode* s, MemoryPool* pool) {
release(pool);
setRawString(s);
}
void setString(const char* s) { void setString(const char* s) {
ARDUINOJSON_ASSERT(s); ARDUINOJSON_ASSERT(s);
setType(VALUE_IS_LINKED_STRING); setType(VALUE_IS_LINKED_STRING);
@ -306,17 +326,38 @@ class VariantData {
return content_.asCollection; return content_.asCollection;
} }
CollectionData& toArray(MemoryPool* pool) {
release(pool);
return toArray();
}
CollectionData& toObject() { CollectionData& toObject() {
setType(VALUE_IS_OBJECT); setType(VALUE_IS_OBJECT);
content_.asCollection.clear(); content_.asCollection.clear();
return content_.asCollection; return content_.asCollection;
} }
CollectionData& toObject(MemoryPool* pool) {
release(pool);
return toObject();
}
uint8_t type() const { uint8_t type() const {
return flags_ & VALUE_MASK; return flags_ & VALUE_MASK;
} }
private: 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) { void setType(uint8_t t) {
flags_ &= OWNED_KEY_BIT; flags_ &= OWNED_KEY_BIT;
flags_ |= t; flags_ |= t;

View File

@ -11,7 +11,6 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
void slotRelease(const VariantSlot* slot, MemoryPool* pool);
bool collectionCopy(CollectionData* dst, const CollectionData* src, bool collectionCopy(CollectionData* dst, const CollectionData* src,
MemoryPool* pool); MemoryPool* pool);
VariantData* collectionAddElement(CollectionData* array, MemoryPool* pool); VariantData* collectionAddElement(CollectionData* array, MemoryPool* pool);
@ -30,19 +29,6 @@ inline typename TVisitor::result_type variantAccept(const VariantData* var,
return visitor.visitNull(); 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, inline bool variantCopyFrom(VariantData* dst, const VariantData* src,
MemoryPool* pool) { MemoryPool* pool) {
if (!dst) if (!dst)
@ -81,31 +67,27 @@ inline bool variantCopyFrom(VariantData* dst, const VariantData* src,
inline void variantSetNull(VariantData* var, MemoryPool* pool) { inline void variantSetNull(VariantData* var, MemoryPool* pool) {
if (!var) if (!var)
return; return;
variantRelease(var, pool); var->setNull(pool);
var->setNull();
} }
inline void variantSetBoolean(VariantData* var, bool value, MemoryPool* pool) { inline void variantSetBoolean(VariantData* var, bool value, MemoryPool* pool) {
if (!var) if (!var)
return; return;
variantRelease(var, pool); var->setBoolean(value, pool);
var->setBoolean(value);
} }
inline void variantSetFloat(VariantData* var, JsonFloat value, inline void variantSetFloat(VariantData* var, JsonFloat value,
MemoryPool* pool) { MemoryPool* pool) {
if (!var) if (!var)
return; return;
variantRelease(var, pool); var->setFloat(value, pool);
var->setFloat(value);
} }
template <typename T> template <typename T>
inline void variantSetInteger(VariantData* var, T value, MemoryPool* pool) { inline void variantSetInteger(VariantData* var, T value, MemoryPool* pool) {
if (!var) if (!var)
return; return;
variantRelease(var, pool); var->setInteger(value, pool);
var->setInteger(value);
} }
template <typename TAdaptedString> template <typename TAdaptedString>
@ -113,12 +95,10 @@ inline void variantSetString(VariantData* var, TAdaptedString value,
MemoryPool* pool) { MemoryPool* pool) {
if (!var) if (!var)
return; return;
variantRelease(var, pool); var->setNull(pool);
if (value.isNull()) { if (value.isNull())
var->setNull();
return; return;
}
if (value.isLinked()) { if (value.isLinked()) {
var->setString(value.data()); var->setString(value.data());
@ -137,12 +117,11 @@ inline void variantSetRawString(VariantData* var, SerializedValue<T> value,
MemoryPool* pool) { MemoryPool* pool) {
if (!var) if (!var)
return; return;
variantRelease(var, pool);
auto dup = pool->saveString(adaptString(value.data(), value.size())); auto dup = pool->saveString(adaptString(value.data(), value.size()));
if (dup) if (dup)
var->setRawString(dup); var->setRawString(dup, pool);
else else
var->setNull(); var->setNull(pool);
} }
inline size_t variantSize(const VariantData* var) { 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) { inline CollectionData* variantToArray(VariantData* var, MemoryPool* pool) {
if (!var) if (!var)
return 0; return 0;
variantRelease(var, pool); return &var->toArray(pool);
return &var->toArray();
} }
inline CollectionData* variantToObject(VariantData* var, MemoryPool* pool) { inline CollectionData* variantToObject(VariantData* var, MemoryPool* pool) {
if (!var) if (!var)
return 0; return 0;
variantRelease(var, pool); return &var->toObject(pool);
return &var->toObject();
} }
inline VariantData* variantGetElement(const VariantData* var, size_t index) { inline VariantData* variantGetElement(const VariantData* var, size_t index) {