diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index b3e71d35..8250664a 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -51,7 +51,6 @@ #include "ArduinoJson/Variant/ConverterImpl.hpp" #include "ArduinoJson/Variant/JsonVariantCopier.hpp" #include "ArduinoJson/Variant/VariantCompare.hpp" -#include "ArduinoJson/Variant/VariantImpl.hpp" #include "ArduinoJson/Variant/VariantRefBaseImpl.hpp" #include "ArduinoJson/Json/JsonDeserializer.hpp" diff --git a/src/ArduinoJson/Memory/ResourceManagerImpl.hpp b/src/ArduinoJson/Memory/ResourceManagerImpl.hpp index 583e11c3..2d9b6dad 100644 --- a/src/ArduinoJson/Memory/ResourceManagerImpl.hpp +++ b/src/ArduinoJson/Memory/ResourceManagerImpl.hpp @@ -4,10 +4,9 @@ #pragma once -#include #include #include -#include +#include ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Memory/StringBuilder.hpp b/src/ArduinoJson/Memory/StringBuilder.hpp index db6c3544..e13dfaa4 100644 --- a/src/ArduinoJson/Memory/StringBuilder.hpp +++ b/src/ArduinoJson/Memory/StringBuilder.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantAttorney.hpp b/src/ArduinoJson/Variant/VariantAttorney.hpp index 41fe61b9..ee4f4c4b 100644 --- a/src/ArduinoJson/Variant/VariantAttorney.hpp +++ b/src/ArduinoJson/Variant/VariantAttorney.hpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include "JsonVariantConst.hpp" diff --git a/src/ArduinoJson/Variant/VariantData.hpp b/src/ArduinoJson/Variant/VariantData.hpp index 086cb934..fc916626 100644 --- a/src/ArduinoJson/Variant/VariantData.hpp +++ b/src/ArduinoJson/Variant/VariantData.hpp @@ -4,12 +4,7 @@ #pragma once -#include #include -#include -#include -#include -#include #include ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE @@ -86,422 +81,4 @@ struct VariantData { } }; -class VariantImpl { - public: - VariantImpl() : data_(nullptr), resources_(nullptr) {} - - VariantImpl(VariantData* data, ResourceManager* resources) - : data_(data), resources_(resources) {} - - VariantData* getData() const { - return data_; - } - - ResourceManager* getResourceManager() const { - return resources_; - } - - template - typename TVisitor::result_type accept(TVisitor& visit) { - if (!data_) - return visit.visit(nullptr); - -#if ARDUINOJSON_USE_8_BYTE_POOL - auto eightByteValue = getEightByte(); -#endif - switch (data_->type) { - case VariantType::Float: - return visit.visit(data_->content.asFloat); - -#if ARDUINOJSON_USE_DOUBLE - case VariantType::Double: - return visit.visit(eightByteValue->asDouble); -#endif - - case VariantType::Array: - return visit.visit(asArray()); - - case VariantType::Object: - return visit.visit(asObject()); - - case VariantType::TinyString: - return visit.visit(JsonString(data_->content.asTinyString)); - - case VariantType::LinkedString: - return visit.visit(JsonString(asLinkedString(), true)); - - case VariantType::OwnedString: - return visit.visit(JsonString(data_->content.asOwnedString->data, - data_->content.asOwnedString->length)); - - case VariantType::RawString: - return visit.visit(RawString(data_->content.asOwnedString->data, - data_->content.asOwnedString->length)); - - case VariantType::Int32: - return visit.visit(static_cast(data_->content.asInt32)); - - case VariantType::Uint32: - return visit.visit(static_cast(data_->content.asUint32)); - -#if ARDUINOJSON_USE_LONG_LONG - case VariantType::Int64: - return visit.visit(eightByteValue->asInt64); - - case VariantType::Uint64: - return visit.visit(eightByteValue->asUint64); -#endif - - case VariantType::Boolean: - return visit.visit(data_->content.asBoolean != 0); - - default: - return visit.visit(nullptr); - } - } - - VariantData* addElement() { - auto array = isNull() ? toArray() : asArray(); - return array.addElement(); - } - - template - bool addValue(const T& value) { - auto array = isNull() ? toArray() : asArray(); - return array.addValue(value); - } - - bool asBoolean() const { - if (!data_) - return false; - -#if ARDUINOJSON_USE_8_BYTE_POOL - auto eightByteValue = getEightByte(); -#endif - switch (data_->type) { - case VariantType::Boolean: - return data_->content.asBoolean; - case VariantType::Uint32: - case VariantType::Int32: - return data_->content.asUint32 != 0; - case VariantType::Float: - return data_->content.asFloat != 0; -#if ARDUINOJSON_USE_DOUBLE - case VariantType::Double: - return eightByteValue->asDouble != 0; -#endif - case VariantType::Null: - return false; -#if ARDUINOJSON_USE_LONG_LONG - case VariantType::Uint64: - case VariantType::Int64: - return eightByteValue->asUint64 != 0; -#endif - default: - return true; - } - } - - ArrayImpl asArray() { - return ArrayImpl(isArray() ? &data_->content.asCollection : nullptr, - resources_); - } - - CollectionImpl asCollection() { - return CollectionImpl( - isCollection() ? &data_->content.asCollection : nullptr, resources_); - } - - template - T asFloat() const { - if (!data_) - return 0.0; - - static_assert(is_floating_point::value, "T must be a floating point"); -#if ARDUINOJSON_USE_8_BYTE_POOL - auto eightByteValue = getEightByte(); -#endif - const char* str = nullptr; - switch (data_->type) { - case VariantType::Boolean: - return static_cast(data_->content.asBoolean); - case VariantType::Uint32: - return static_cast(data_->content.asUint32); - case VariantType::Int32: - return static_cast(data_->content.asInt32); -#if ARDUINOJSON_USE_LONG_LONG - case VariantType::Uint64: - return static_cast(eightByteValue->asUint64); - case VariantType::Int64: - return static_cast(eightByteValue->asInt64); -#endif - case VariantType::TinyString: - str = data_->content.asTinyString; - break; - case VariantType::LinkedString: - str = asLinkedString(); - break; - case VariantType::OwnedString: - str = data_->content.asOwnedString->data; - break; - case VariantType::Float: - return static_cast(data_->content.asFloat); -#if ARDUINOJSON_USE_DOUBLE - case VariantType::Double: - return static_cast(eightByteValue->asDouble); -#endif - default: - return 0.0; - } - - ARDUINOJSON_ASSERT(str != nullptr); - return parseNumber(str); - } - - template - T asIntegral() const { - if (!data_) - return 0; - - static_assert(is_integral::value, "T must be an integral type"); -#if ARDUINOJSON_USE_8_BYTE_POOL - auto eightByteValue = getEightByte(); -#endif - const char* str = nullptr; - switch (data_->type) { - case VariantType::Boolean: - return data_->content.asBoolean; - case VariantType::Uint32: - return convertNumber(data_->content.asUint32); - case VariantType::Int32: - return convertNumber(data_->content.asInt32); -#if ARDUINOJSON_USE_LONG_LONG - case VariantType::Uint64: - return convertNumber(eightByteValue->asUint64); - case VariantType::Int64: - return convertNumber(eightByteValue->asInt64); -#endif - case VariantType::TinyString: - str = data_->content.asTinyString; - break; - case VariantType::LinkedString: - str = asLinkedString(); - break; - case VariantType::OwnedString: - str = data_->content.asOwnedString->data; - break; - case VariantType::Float: - return convertNumber(data_->content.asFloat); -#if ARDUINOJSON_USE_DOUBLE - case VariantType::Double: - return convertNumber(eightByteValue->asDouble); -#endif - default: - return 0; - } - - ARDUINOJSON_ASSERT(str != nullptr); - return parseNumber(str); - } - - ObjectImpl asObject() { - return ObjectImpl(isObject() ? &data_->content.asCollection : nullptr, - resources_); - } - - JsonString asRawString() const { - switch (type()) { - case VariantType::RawString: - return JsonString(data_->content.asOwnedString->data, - data_->content.asOwnedString->length); - default: - return JsonString(); - } - } - - const char* asLinkedString() const; - - JsonString asString() const { - switch (type()) { - case VariantType::TinyString: - return JsonString(data_->content.asTinyString); - case VariantType::LinkedString: - return JsonString(asLinkedString(), true); - case VariantType::OwnedString: - return JsonString(data_->content.asOwnedString->data, - data_->content.asOwnedString->length); - default: - return JsonString(); - } - } - -#if ARDUINOJSON_USE_8_BYTE_POOL - const EightByteValue* getEightByte() const; -#endif - - VariantData* getElement(size_t index) { - return asArray().getElement(index); - } - - template - VariantData* getMember(TAdaptedString key) { - return asObject().getMember(key); - } - - VariantData* getOrAddElement(size_t index) { - auto array = isNull() ? toArray() : asArray(); - return array.getOrAddElement(index); - } - - template - VariantData* getOrAddMember(TAdaptedString key) { - if (key.isNull()) - return nullptr; - auto obj = isNull() ? toObject() : asObject(); - return obj.getOrAddMember(key); - } - - bool isArray() const { - return type() == VariantType::Array; - } - - bool isBoolean() const { - return type() == VariantType::Boolean; - } - - bool isCollection() const { - return type() & VariantTypeBits::CollectionMask; - } - - bool isFloat() const { - return data_ && data_->isFloat(); - } - - template - bool isInteger() const { - if (!data_) - return false; - -#if ARDUINOJSON_USE_LONG_LONG - auto eightByteValue = getEightByte(); -#endif - switch (data_->type) { - case VariantType::Uint32: - return canConvertNumber(data_->content.asUint32); - - case VariantType::Int32: - return canConvertNumber(data_->content.asInt32); - -#if ARDUINOJSON_USE_LONG_LONG - case VariantType::Uint64: - return canConvertNumber(eightByteValue->asUint64); - - case VariantType::Int64: - return canConvertNumber(eightByteValue->asInt64); -#endif - - default: - return false; - } - } - - bool isNull() const { - return type() == VariantType::Null; - } - - bool isObject() const { - return type() == VariantType::Object; - } - - bool isString() const { - return data_ && data_->isString(); - } - - size_t nesting() { - return asCollection().nesting(); - } - - void removeElement(size_t index) { - asArray().removeElement(index); - } - - template - void removeMember(TAdaptedString key) { - asObject().removeMember(key); - } - - bool setBoolean(bool value) { - if (!data_) - return false; - data_->setBoolean(value); - return true; - } - - template - enable_if_t setFloat(T value) { - ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first - if (!data_) - return false; - data_->type = VariantType::Float; - data_->content.asFloat = value; - return true; - } - - template - enable_if_t setFloat(T value); - - template - enable_if_t::value, bool> setInteger(T value); - - template - enable_if_t::value, bool> setInteger(T value); - - template - void setRawString(SerializedValue value); - - template - bool setString(TAdaptedString value); - - bool setLinkedString(const char* s); - - size_t size() { - if (isObject()) - return asObject().size(); - - if (isArray()) - return asArray().size(); - - return 0; - } - - ArrayImpl toArray() { - ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first - if (!data_) - return ArrayImpl(); - data_->type = VariantType::Array; - return ArrayImpl(new (&data_->content.asCollection) CollectionData(), - resources_); - } - - ObjectImpl toObject() { - ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first - if (!data_) - return ObjectImpl(); - data_->type = VariantType::Object; - return ObjectImpl(new (&data_->content.asCollection) CollectionData(), - resources_); - } - - VariantType type() const { - return data_ ? data_->type : VariantType::Null; - } - - // Release the resources used by this variant and set it to null. - void clear(); - - private: - VariantData* data_; - ResourceManager* resources_; -}; - ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantImpl.hpp b/src/ArduinoJson/Variant/VariantImpl.hpp index c4cece47..3fbf39bd 100644 --- a/src/ArduinoJson/Variant/VariantImpl.hpp +++ b/src/ArduinoJson/Variant/VariantImpl.hpp @@ -5,10 +5,506 @@ #pragma once #include +#include +#include +#include +#include #include ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE +class VariantImpl { + public: + VariantImpl() : data_(nullptr), resources_(nullptr) {} + + VariantImpl(VariantData* data, ResourceManager* resources) + : data_(data), resources_(resources) {} + + VariantData* getData() const { + return data_; + } + + ResourceManager* getResourceManager() const { + return resources_; + } + + template + typename TVisitor::result_type accept(TVisitor& visit) { + if (!data_) + return visit.visit(nullptr); + +#if ARDUINOJSON_USE_8_BYTE_POOL + auto eightByteValue = getEightByte(); +#endif + switch (data_->type) { + case VariantType::Float: + return visit.visit(data_->content.asFloat); + +#if ARDUINOJSON_USE_DOUBLE + case VariantType::Double: + return visit.visit(eightByteValue->asDouble); +#endif + + case VariantType::Array: + return visit.visit(asArray()); + + case VariantType::Object: + return visit.visit(asObject()); + + case VariantType::TinyString: + return visit.visit(JsonString(data_->content.asTinyString)); + + case VariantType::LinkedString: + return visit.visit(JsonString(asLinkedString(), true)); + + case VariantType::OwnedString: + return visit.visit(JsonString(data_->content.asOwnedString->data, + data_->content.asOwnedString->length)); + + case VariantType::RawString: + return visit.visit(RawString(data_->content.asOwnedString->data, + data_->content.asOwnedString->length)); + + case VariantType::Int32: + return visit.visit(static_cast(data_->content.asInt32)); + + case VariantType::Uint32: + return visit.visit(static_cast(data_->content.asUint32)); + +#if ARDUINOJSON_USE_LONG_LONG + case VariantType::Int64: + return visit.visit(eightByteValue->asInt64); + + case VariantType::Uint64: + return visit.visit(eightByteValue->asUint64); +#endif + + case VariantType::Boolean: + return visit.visit(data_->content.asBoolean != 0); + + default: + return visit.visit(nullptr); + } + } + + VariantData* addElement() { + auto array = isNull() ? toArray() : asArray(); + return array.addElement(); + } + + template + bool addValue(const T& value) { + auto array = isNull() ? toArray() : asArray(); + return array.addValue(value); + } + + bool asBoolean() const { + if (!data_) + return false; + +#if ARDUINOJSON_USE_8_BYTE_POOL + auto eightByteValue = getEightByte(); +#endif + switch (data_->type) { + case VariantType::Boolean: + return data_->content.asBoolean; + case VariantType::Uint32: + case VariantType::Int32: + return data_->content.asUint32 != 0; + case VariantType::Float: + return data_->content.asFloat != 0; +#if ARDUINOJSON_USE_DOUBLE + case VariantType::Double: + return eightByteValue->asDouble != 0; +#endif + case VariantType::Null: + return false; +#if ARDUINOJSON_USE_LONG_LONG + case VariantType::Uint64: + case VariantType::Int64: + return eightByteValue->asUint64 != 0; +#endif + default: + return true; + } + } + + ArrayImpl asArray() { + return ArrayImpl(isArray() ? &data_->content.asCollection : nullptr, + resources_); + } + + CollectionImpl asCollection() { + return CollectionImpl( + isCollection() ? &data_->content.asCollection : nullptr, resources_); + } + + template + T asFloat() const { + if (!data_) + return 0.0; + + static_assert(is_floating_point::value, "T must be a floating point"); +#if ARDUINOJSON_USE_8_BYTE_POOL + auto eightByteValue = getEightByte(); +#endif + const char* str = nullptr; + switch (data_->type) { + case VariantType::Boolean: + return static_cast(data_->content.asBoolean); + case VariantType::Uint32: + return static_cast(data_->content.asUint32); + case VariantType::Int32: + return static_cast(data_->content.asInt32); +#if ARDUINOJSON_USE_LONG_LONG + case VariantType::Uint64: + return static_cast(eightByteValue->asUint64); + case VariantType::Int64: + return static_cast(eightByteValue->asInt64); +#endif + case VariantType::TinyString: + str = data_->content.asTinyString; + break; + case VariantType::LinkedString: + str = asLinkedString(); + break; + case VariantType::OwnedString: + str = data_->content.asOwnedString->data; + break; + case VariantType::Float: + return static_cast(data_->content.asFloat); +#if ARDUINOJSON_USE_DOUBLE + case VariantType::Double: + return static_cast(eightByteValue->asDouble); +#endif + default: + return 0.0; + } + + ARDUINOJSON_ASSERT(str != nullptr); + return parseNumber(str); + } + + template + T asIntegral() const { + if (!data_) + return 0; + + static_assert(is_integral::value, "T must be an integral type"); +#if ARDUINOJSON_USE_8_BYTE_POOL + auto eightByteValue = getEightByte(); +#endif + const char* str = nullptr; + switch (data_->type) { + case VariantType::Boolean: + return data_->content.asBoolean; + case VariantType::Uint32: + return convertNumber(data_->content.asUint32); + case VariantType::Int32: + return convertNumber(data_->content.asInt32); +#if ARDUINOJSON_USE_LONG_LONG + case VariantType::Uint64: + return convertNumber(eightByteValue->asUint64); + case VariantType::Int64: + return convertNumber(eightByteValue->asInt64); +#endif + case VariantType::TinyString: + str = data_->content.asTinyString; + break; + case VariantType::LinkedString: + str = asLinkedString(); + break; + case VariantType::OwnedString: + str = data_->content.asOwnedString->data; + break; + case VariantType::Float: + return convertNumber(data_->content.asFloat); +#if ARDUINOJSON_USE_DOUBLE + case VariantType::Double: + return convertNumber(eightByteValue->asDouble); +#endif + default: + return 0; + } + + ARDUINOJSON_ASSERT(str != nullptr); + return parseNumber(str); + } + + ObjectImpl asObject() { + return ObjectImpl(isObject() ? &data_->content.asCollection : nullptr, + resources_); + } + + JsonString asRawString() const { + switch (type()) { + case VariantType::RawString: + return JsonString(data_->content.asOwnedString->data, + data_->content.asOwnedString->length); + default: + return JsonString(); + } + } + + const char* asLinkedString() const { + ARDUINOJSON_ASSERT(type() == VariantType::LinkedString); + return resources_->getStaticString(data_->content.asSlotId); + } + + JsonString asString() const { + switch (type()) { + case VariantType::TinyString: + return JsonString(data_->content.asTinyString); + case VariantType::LinkedString: + return JsonString(asLinkedString(), true); + case VariantType::OwnedString: + return JsonString(data_->content.asOwnedString->data, + data_->content.asOwnedString->length); + default: + return JsonString(); + } + } + +#if ARDUINOJSON_USE_8_BYTE_POOL + const EightByteValue* getEightByte() const { + return type() & VariantTypeBits::EightByteBit + ? resources_->getEightByte(data_->content.asSlotId) + : 0; + } +#endif + + VariantData* getElement(size_t index) { + return asArray().getElement(index); + } + + template + VariantData* getMember(TAdaptedString key) { + return asObject().getMember(key); + } + + VariantData* getOrAddElement(size_t index) { + auto array = isNull() ? toArray() : asArray(); + return array.getOrAddElement(index); + } + + template + VariantData* getOrAddMember(TAdaptedString key) { + if (key.isNull()) + return nullptr; + auto obj = isNull() ? toObject() : asObject(); + return obj.getOrAddMember(key); + } + + bool isArray() const { + return type() == VariantType::Array; + } + + bool isBoolean() const { + return type() == VariantType::Boolean; + } + + bool isCollection() const { + return type() & VariantTypeBits::CollectionMask; + } + + bool isFloat() const { + return data_ && data_->isFloat(); + } + + template + bool isInteger() const { + if (!data_) + return false; + +#if ARDUINOJSON_USE_LONG_LONG + auto eightByteValue = getEightByte(); +#endif + switch (data_->type) { + case VariantType::Uint32: + return canConvertNumber(data_->content.asUint32); + + case VariantType::Int32: + return canConvertNumber(data_->content.asInt32); + +#if ARDUINOJSON_USE_LONG_LONG + case VariantType::Uint64: + return canConvertNumber(eightByteValue->asUint64); + + case VariantType::Int64: + return canConvertNumber(eightByteValue->asInt64); +#endif + + default: + return false; + } + } + + bool isNull() const { + return type() == VariantType::Null; + } + + bool isObject() const { + return type() == VariantType::Object; + } + + bool isString() const { + return data_ && data_->isString(); + } + + size_t nesting() { + return asCollection().nesting(); + } + + void removeElement(size_t index) { + asArray().removeElement(index); + } + + template + void removeMember(TAdaptedString key) { + asObject().removeMember(key); + } + + bool setBoolean(bool value) { + if (!data_) + return false; + data_->setBoolean(value); + return true; + } + + template + enable_if_t setFloat(T value) { + ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first + if (!data_) + return false; + data_->type = VariantType::Float; + data_->content.asFloat = value; + return true; + } + + template + enable_if_t setFloat(T value) { + ARDUINOJSON_ASSERT(isNull()); // must call clear() first + + if (!data_) + return false; + + float valueAsFloat = static_cast(value); + +#if ARDUINOJSON_USE_DOUBLE + if (value == valueAsFloat) { + data_->type = VariantType::Float; + data_->content.asFloat = valueAsFloat; + } else { + auto slot = resources_->allocEightByte(); + if (!slot) + return false; + data_->type = VariantType::Double; + data_->content.asSlotId = slot.id(); + slot->asDouble = value; + } +#else + data_->type = VariantType::Float; + data_->content.asFloat = valueAsFloat; +#endif + return true; + } + + template + enable_if_t::value, bool> setInteger(T value) { + ARDUINOJSON_ASSERT(isNull()); // must call clear() first + + if (!data_) + return false; + + if (canConvertNumber(value)) { + data_->type = VariantType::Int32; + data_->content.asInt32 = static_cast(value); + } +#if ARDUINOJSON_USE_LONG_LONG + else { + auto slot = resources_->allocEightByte(); + if (!slot) + return false; + data_->type = VariantType::Int64; + data_->content.asSlotId = slot.id(); + slot->asInt64 = value; + } +#endif + return true; + } + + template + enable_if_t::value, bool> setInteger(T value) { + ARDUINOJSON_ASSERT(isNull()); // must call clear() first + + if (!data_) + return false; + + if (canConvertNumber(value)) { + data_->type = VariantType::Uint32; + data_->content.asUint32 = static_cast(value); + } +#if ARDUINOJSON_USE_LONG_LONG + else { + auto slot = resources_->allocEightByte(); + if (!slot) + return false; + data_->type = VariantType::Uint64; + data_->content.asSlotId = slot.id(); + slot->asUint64 = value; + } +#endif + return true; + } + + template + void setRawString(SerializedValue value); + + template + bool setString(TAdaptedString value); + + bool setLinkedString(const char* s); + + size_t size() { + if (isObject()) + return asObject().size(); + + if (isArray()) + return asArray().size(); + + return 0; + } + + ArrayImpl toArray() { + ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first + if (!data_) + return ArrayImpl(); + data_->type = VariantType::Array; + return ArrayImpl(new (&data_->content.asCollection) CollectionData(), + resources_); + } + + ObjectImpl toObject() { + ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first + if (!data_) + return ObjectImpl(); + data_->type = VariantType::Object; + return ObjectImpl(new (&data_->content.asCollection) CollectionData(), + resources_); + } + + VariantType type() const { + return data_ ? data_->type : VariantType::Null; + } + + // Release the resources used by this variant and set it to null. + void clear(); + + private: + VariantData* data_; + ResourceManager* resources_; +}; + template inline void VariantImpl::setRawString(SerializedValue value) { if (!data_) @@ -75,93 +571,4 @@ inline void VariantImpl::clear() { data_->type = VariantType::Null; } -#if ARDUINOJSON_USE_8_BYTE_POOL -inline const EightByteValue* VariantImpl::getEightByte() const { - return type() & VariantTypeBits::EightByteBit - ? resources_->getEightByte(data_->content.asSlotId) - : 0; -} -#endif - -inline const char* VariantImpl::asLinkedString() const { - ARDUINOJSON_ASSERT(type() == VariantType::LinkedString); - return resources_->getStaticString(data_->content.asSlotId); -} - -template -enable_if_t VariantImpl::setFloat(T value) { - ARDUINOJSON_ASSERT(isNull()); // must call clear() first - - if (!data_) - return false; - - float valueAsFloat = static_cast(value); - -#if ARDUINOJSON_USE_DOUBLE - if (value == valueAsFloat) { - data_->type = VariantType::Float; - data_->content.asFloat = valueAsFloat; - } else { - auto slot = resources_->allocEightByte(); - if (!slot) - return false; - data_->type = VariantType::Double; - data_->content.asSlotId = slot.id(); - slot->asDouble = value; - } -#else - data_->type = VariantType::Float; - data_->content.asFloat = valueAsFloat; -#endif - return true; -} - -template -enable_if_t::value, bool> VariantImpl::setInteger(T value) { - ARDUINOJSON_ASSERT(isNull()); // must call clear() first - - if (!data_) - return false; - - if (canConvertNumber(value)) { - data_->type = VariantType::Int32; - data_->content.asInt32 = static_cast(value); - } -#if ARDUINOJSON_USE_LONG_LONG - else { - auto slot = resources_->allocEightByte(); - if (!slot) - return false; - data_->type = VariantType::Int64; - data_->content.asSlotId = slot.id(); - slot->asInt64 = value; - } -#endif - return true; -} - -template -enable_if_t::value, bool> VariantImpl::setInteger(T value) { - ARDUINOJSON_ASSERT(isNull()); // must call clear() first - - if (!data_) - return false; - - if (canConvertNumber(value)) { - data_->type = VariantType::Uint32; - data_->content.asUint32 = static_cast(value); - } -#if ARDUINOJSON_USE_LONG_LONG - else { - auto slot = resources_->allocEightByte(); - if (!slot) - return false; - data_->type = VariantType::Uint64; - data_->content.asSlotId = slot.id(); - slot->asUint64 = value; - } -#endif - return true; -} - ARDUINOJSON_END_PRIVATE_NAMESPACE