mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-29 18:27:37 +02:00
Release VariantData
resources explicitly before setting value
This commit is contained in:
@ -283,7 +283,7 @@ class JsonDeserializer {
|
||||
if (!member)
|
||||
return DeserializationError::NoMemory;
|
||||
} else {
|
||||
member->setNull(resources_);
|
||||
member->clear(resources_);
|
||||
}
|
||||
|
||||
// Parse value
|
||||
|
@ -20,7 +20,7 @@ inline Slot<VariantData> ResourceManager::allocVariant() {
|
||||
}
|
||||
|
||||
inline void ResourceManager::freeVariant(Slot<VariantData> variant) {
|
||||
variant->setNull(this);
|
||||
variant->clear(this);
|
||||
variantPools_.freeSlot(variant);
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ struct Converter<MsgPackBinary> : private detail::VariantAttorney {
|
||||
if (!data)
|
||||
return;
|
||||
auto resources = getResourceManager(dst);
|
||||
data->clear(resources);
|
||||
if (src.data()) {
|
||||
size_t headerSize = src.size() >= 0x10000 ? 5
|
||||
: src.size() >= 0x100 ? 3
|
||||
@ -62,7 +63,6 @@ struct Converter<MsgPackBinary> : private detail::VariantAttorney {
|
||||
return;
|
||||
}
|
||||
}
|
||||
data->setNull();
|
||||
}
|
||||
|
||||
static MsgPackBinary fromJson(JsonVariantConst src) {
|
||||
|
@ -35,6 +35,7 @@ struct Converter<MsgPackExtension> : private detail::VariantAttorney {
|
||||
if (!data)
|
||||
return;
|
||||
auto resources = getResourceManager(dst);
|
||||
data->clear(resources);
|
||||
if (src.data()) {
|
||||
uint8_t format, sizeBytes;
|
||||
if (src.size() >= 0x10000) {
|
||||
@ -76,7 +77,6 @@ struct Converter<MsgPackExtension> : private detail::VariantAttorney {
|
||||
return;
|
||||
}
|
||||
}
|
||||
data->setNull();
|
||||
}
|
||||
|
||||
static MsgPackExtension fromJson(JsonVariantConst src) {
|
||||
|
@ -63,7 +63,9 @@ struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
|
||||
auto data = getData(dst);
|
||||
if (!data)
|
||||
return false;
|
||||
data->setInteger(src, getResourceManager(dst));
|
||||
auto resources = getResourceManager(dst);
|
||||
data->clear(resources);
|
||||
data->setInteger(src);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -103,7 +105,9 @@ struct Converter<bool> : private detail::VariantAttorney {
|
||||
auto data = getData(dst);
|
||||
if (!data)
|
||||
return false;
|
||||
data->setBoolean(src, getResourceManager(dst));
|
||||
auto resources = getResourceManager(dst);
|
||||
data->clear(resources);
|
||||
data->setBoolean(src);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -125,7 +129,9 @@ struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
|
||||
auto data = getData(dst);
|
||||
if (!data)
|
||||
return false;
|
||||
data->setFloat(static_cast<JsonFloat>(src), getResourceManager(dst));
|
||||
auto resources = getResourceManager(dst);
|
||||
data->clear(resources);
|
||||
data->setFloat(static_cast<JsonFloat>(src));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -199,7 +205,7 @@ struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
|
||||
template <>
|
||||
struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
|
||||
static void toJson(detail::nullptr_t, JsonVariant dst) {
|
||||
detail::VariantData::setNull(getData(dst), getResourceManager(dst));
|
||||
detail::VariantData::clear(getData(dst), getResourceManager(dst));
|
||||
}
|
||||
static detail::nullptr_t fromJson(JsonVariantConst) {
|
||||
return nullptr;
|
||||
@ -252,12 +258,11 @@ inline void convertToJson(const ::Printable& src, JsonVariant dst) {
|
||||
auto data = detail::VariantAttorney::getData(dst);
|
||||
if (!resources || !data)
|
||||
return;
|
||||
data->clear(resources);
|
||||
detail::StringBuilderPrint print(resources);
|
||||
src.printTo(print);
|
||||
if (print.overflowed()) {
|
||||
data->setNull();
|
||||
if (print.overflowed())
|
||||
return;
|
||||
}
|
||||
data->setOwnedString(print.save());
|
||||
}
|
||||
|
||||
|
@ -344,64 +344,38 @@ class VariantData {
|
||||
var->removeMember(key, resources);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
void reset() { // TODO: remove
|
||||
type_ = VALUE_IS_NULL;
|
||||
}
|
||||
|
||||
void setBoolean(bool value) {
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
type_ = VALUE_IS_BOOLEAN;
|
||||
content_.asBoolean = value;
|
||||
}
|
||||
|
||||
void setBoolean(bool value, ResourceManager* resources) {
|
||||
release(resources);
|
||||
setBoolean(value);
|
||||
}
|
||||
|
||||
void setFloat(JsonFloat value) {
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
type_ = VALUE_IS_FLOAT;
|
||||
content_.asFloat = value;
|
||||
}
|
||||
|
||||
void setFloat(JsonFloat value, ResourceManager* resources) {
|
||||
release(resources);
|
||||
setFloat(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
enable_if_t<is_signed<T>::value> setInteger(T value) {
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
type_ = VALUE_IS_SIGNED_INTEGER;
|
||||
content_.asSignedInteger = value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
enable_if_t<is_unsigned<T>::value> setInteger(T value) {
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
type_ = VALUE_IS_UNSIGNED_INTEGER;
|
||||
content_.asUnsignedInteger = static_cast<JsonUInt>(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void setInteger(T value, ResourceManager* resources) {
|
||||
release(resources);
|
||||
setInteger(value);
|
||||
}
|
||||
|
||||
void setNull() {
|
||||
type_ = VALUE_IS_NULL;
|
||||
}
|
||||
|
||||
void setNull(ResourceManager* resources) {
|
||||
release(resources);
|
||||
setNull();
|
||||
}
|
||||
|
||||
static void setNull(VariantData* var, ResourceManager* resources) {
|
||||
if (!var)
|
||||
return;
|
||||
var->setNull(resources);
|
||||
}
|
||||
|
||||
void setRawString(StringNode* s) {
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
ARDUINOJSON_ASSERT(s);
|
||||
type_ = VALUE_IS_RAW_STRING;
|
||||
content_.asOwnedString = s;
|
||||
@ -415,6 +389,7 @@ class VariantData {
|
||||
ResourceManager* resources) {
|
||||
if (!var)
|
||||
return;
|
||||
var->clear(resources);
|
||||
var->setRawString(value, resources);
|
||||
}
|
||||
|
||||
@ -431,16 +406,19 @@ class VariantData {
|
||||
ResourceManager* resources) {
|
||||
if (!var)
|
||||
return;
|
||||
var->clear(resources);
|
||||
var->setString(value, resources);
|
||||
}
|
||||
|
||||
void setLinkedString(const char* s) {
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
ARDUINOJSON_ASSERT(s);
|
||||
type_ = VALUE_IS_LINKED_STRING;
|
||||
content_.asLinkedString = s;
|
||||
}
|
||||
|
||||
void setOwnedString(StringNode* s) {
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
ARDUINOJSON_ASSERT(s);
|
||||
type_ = VALUE_IS_OWNED_STRING;
|
||||
content_.asOwnedString = s;
|
||||
@ -461,45 +439,45 @@ class VariantData {
|
||||
}
|
||||
|
||||
ArrayData& toArray() {
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
type_ = VALUE_IS_ARRAY;
|
||||
new (&content_.asArray) ArrayData();
|
||||
return content_.asArray;
|
||||
}
|
||||
|
||||
ArrayData& toArray(ResourceManager* resources) {
|
||||
release(resources);
|
||||
return toArray();
|
||||
}
|
||||
|
||||
static ArrayData* toArray(VariantData* var, ResourceManager* resources) {
|
||||
if (!var)
|
||||
return 0;
|
||||
return &var->toArray(resources);
|
||||
var->clear(resources);
|
||||
return &var->toArray();
|
||||
}
|
||||
|
||||
ObjectData& toObject() {
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
type_ = VALUE_IS_OBJECT;
|
||||
new (&content_.asObject) ObjectData();
|
||||
return content_.asObject;
|
||||
}
|
||||
|
||||
ObjectData& toObject(ResourceManager* resources) {
|
||||
release(resources);
|
||||
return toObject();
|
||||
}
|
||||
|
||||
static ObjectData* toObject(VariantData* var, ResourceManager* resources) {
|
||||
if (!var)
|
||||
return 0;
|
||||
return &var->toObject(resources);
|
||||
var->clear(resources);
|
||||
return &var->toObject();
|
||||
}
|
||||
|
||||
uint8_t type() const {
|
||||
return type_;
|
||||
}
|
||||
|
||||
private:
|
||||
void release(ResourceManager* resources);
|
||||
// Release the resources used by this variant and set it to null.
|
||||
void clear(ResourceManager* resources);
|
||||
|
||||
static void clear(VariantData* var, ResourceManager* resources) {
|
||||
if (!var)
|
||||
return;
|
||||
var->clear(resources);
|
||||
}
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -12,18 +12,16 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
template <typename T>
|
||||
inline void VariantData::setRawString(SerializedValue<T> value,
|
||||
ResourceManager* resources) {
|
||||
release(resources);
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
auto dup = resources->saveString(adaptString(value.data(), value.size()));
|
||||
if (dup)
|
||||
setRawString(dup);
|
||||
else
|
||||
setNull();
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline bool VariantData::setString(TAdaptedString value,
|
||||
ResourceManager* resources) {
|
||||
setNull(resources);
|
||||
ARDUINOJSON_ASSERT(type_ == VALUE_IS_NULL); // must call clear() first
|
||||
|
||||
if (value.isNull())
|
||||
return false;
|
||||
@ -42,13 +40,15 @@ inline bool VariantData::setString(TAdaptedString value,
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void VariantData::release(ResourceManager* resources) {
|
||||
inline void VariantData::clear(ResourceManager* resources) {
|
||||
if (type_ & OWNED_VALUE_BIT)
|
||||
resources->dereferenceString(content_.asOwnedString->data);
|
||||
|
||||
auto collection = asCollection();
|
||||
if (collection)
|
||||
collection->clear(resources);
|
||||
|
||||
type_ = VALUE_IS_NULL;
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -29,7 +29,7 @@ class VariantRefBase : public VariantTag {
|
||||
// Sets the value to null.
|
||||
// https://arduinojson.org/v7/api/jsonvariant/clear/
|
||||
void clear() const {
|
||||
VariantData::setNull(getOrCreateData(), getResourceManager());
|
||||
VariantData::clear(getOrCreateData(), getResourceManager());
|
||||
}
|
||||
|
||||
// Returns true if the value is null or the reference is unbound.
|
||||
|
@ -174,7 +174,7 @@ enable_if_t<is_same<T, JsonVariant>::value, JsonVariant>
|
||||
VariantRefBase<TDerived>::to() const {
|
||||
auto data = getOrCreateData();
|
||||
auto resources = getResourceManager();
|
||||
detail::VariantData::setNull(data, resources);
|
||||
detail::VariantData::clear(data, resources);
|
||||
return JsonVariant(data, resources);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user