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);
object.add(slot);
} else {
variantRelease(slot->data(), pool_);
slot->data()->setNull(pool_);
}
// Parse value

View File

@ -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

View File

@ -16,6 +16,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename T>
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 T>
typename enable_if<is_signed<T>::value>::type setInteger(T value) {
setType(VALUE_IS_SIGNED_INTEGER);
@ -274,16 +278,32 @@ class VariantData {
content_.asUnsignedInteger = static_cast<JsonUInt>(value);
}
template <typename T>
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;

View File

@ -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 <typename T>
inline void variantSetInteger(VariantData* var, T value, MemoryPool* pool) {
if (!var)
return;
variantRelease(var, pool);
var->setInteger(value);
var->setInteger(value, pool);
}
template <typename TAdaptedString>
@ -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<T> 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) {