diff --git a/src/ArduinoJson/Configuration.hpp b/src/ArduinoJson/Configuration.hpp index 696ce4c9..54c01615 100644 --- a/src/ArduinoJson/Configuration.hpp +++ b/src/ArduinoJson/Configuration.hpp @@ -274,9 +274,9 @@ #endif #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_DOUBLE -# define ARDUINOJSON_USE_EXTENSIONS 1 +# define ARDUINOJSON_USE_8_BYTE_VALUES 1 #else -# define ARDUINOJSON_USE_EXTENSIONS 0 +# define ARDUINOJSON_USE_8_BYTE_VALUES 0 #endif #if defined(nullptr) diff --git a/src/ArduinoJson/Memory/ResourceManager.hpp b/src/ArduinoJson/Memory/ResourceManager.hpp index 12a379c8..d405415c 100644 --- a/src/ArduinoJson/Memory/ResourceManager.hpp +++ b/src/ArduinoJson/Memory/ResourceManager.hpp @@ -18,12 +18,7 @@ class VariantData; class VariantWithId; class ResourceManager { - union SlotData { - VariantData variant; -#if ARDUINOJSON_USE_EXTENSIONS - VariantExtension extension; -#endif - }; + using SlotData = VariantData; // TODO: remove SlotData? public: constexpr static size_t slotSize = sizeof(SlotData); @@ -44,6 +39,7 @@ class ResourceManager { swap(a.stringPool_, b.stringPool_); swap(a.variantPools_, b.variantPools_); swap(a.staticStringsPools_, b.staticStringsPools_); + swap(a.lgValuePools_, b.lgValuePools_); swap_(a.allocator_, b.allocator_); swap_(a.overflowed_, b.overflowed_); } @@ -64,10 +60,10 @@ class ResourceManager { void freeVariant(Slot slot); VariantData* getVariant(SlotId id) const; -#if ARDUINOJSON_USE_EXTENSIONS - Slot allocExtension(); - void freeExtension(SlotId slot); - VariantExtension* getExtension(SlotId id) const; +#if ARDUINOJSON_USE_8_BYTE_VALUES + Slot allocEightByte(); + void freeEightByte(SlotId slot); + EightByteValue* getEightByte(SlotId id) const; #endif template @@ -136,11 +132,17 @@ class ResourceManager { variantPools_.clear(allocator_); stringPool_.clear(allocator_); staticStringsPools_.clear(allocator_); +#if ARDUINOJSON_USE_8_BYTE_VALUES + lgValuePools_.clear(allocator_); +#endif } void shrinkToFit() { variantPools_.shrinkToFit(allocator_); staticStringsPools_.shrinkToFit(allocator_); +#if ARDUINOJSON_USE_8_BYTE_VALUES + lgValuePools_.shrinkToFit(allocator_); +#endif } private: @@ -149,6 +151,9 @@ class ResourceManager { StringPool stringPool_; MemoryPoolList variantPools_; MemoryPoolList staticStringsPools_; +#if ARDUINOJSON_USE_8_BYTE_VALUES + MemoryPoolList eightBytePools_; +#endif }; ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Memory/ResourceManagerImpl.hpp b/src/ArduinoJson/Memory/ResourceManagerImpl.hpp index a701c0d4..8cbc571e 100644 --- a/src/ArduinoJson/Memory/ResourceManagerImpl.hpp +++ b/src/ArduinoJson/Memory/ResourceManagerImpl.hpp @@ -29,23 +29,23 @@ inline VariantData* ResourceManager::getVariant(SlotId id) const { return reinterpret_cast(variantPools_.getSlot(id)); } -#if ARDUINOJSON_USE_EXTENSIONS -inline Slot ResourceManager::allocExtension() { - auto p = variantPools_.allocSlot(allocator_); - if (!p) { +#if ARDUINOJSON_USE_8_BYTE_VALUES +inline Slot ResourceManager::allocEightByte() { + auto slot = eightBytePools_.allocSlot(allocator_); + if (!slot) { overflowed_ = true; return {}; } - return {&p->extension, p.id()}; + return slot; } -inline void ResourceManager::freeExtension(SlotId id) { - auto p = getExtension(id); - variantPools_.freeSlot({reinterpret_cast(p), id}); +inline void ResourceManager::freeEightByte(SlotId id) { + auto p = getEightByte(id); + eightBytePools_.freeSlot({p, id}); } -inline VariantExtension* ResourceManager::getExtension(SlotId id) const { - return &variantPools_.getSlot(id)->extension; +inline EightByteValue* ResourceManager::getEightByte(SlotId id) const { + return eightBytePools_.getSlot(id).ptr(); } #endif diff --git a/src/ArduinoJson/Variant/VariantContent.hpp b/src/ArduinoJson/Variant/VariantContent.hpp index 9c0b820f..74842984 100644 --- a/src/ArduinoJson/Variant/VariantContent.hpp +++ b/src/ArduinoJson/Variant/VariantContent.hpp @@ -16,9 +16,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE enum class VariantTypeBits : uint8_t { OwnedStringBit = 0x01, // 0000 0001 NumberBit = 0x08, // 0000 1000 -#if ARDUINOJSON_USE_EXTENSIONS - ExtensionBit = 0x10, // 0001 0000 -#endif + EightByteBit = 0x10, // 0001 0000 CollectionMask = 0x60, }; @@ -64,8 +62,8 @@ union VariantContent { char asTinyString[tinyStringMaxLength + 1]; }; -#if ARDUINOJSON_USE_EXTENSIONS -union VariantExtension { +#if ARDUINOJSON_USE_8_BYTE_VALUES +union EightByteValue { # if ARDUINOJSON_USE_LONG_LONG uint64_t asUint64; int64_t asInt64; @@ -74,6 +72,9 @@ union VariantExtension { double asDouble; # endif }; + +static_assert(sizeof(EightByteValue) == 8, + "sizeof(EightByteValue) must be 8 bytes"); #endif ARDUINOJSON_END_PRIVATE_NAMESPACE diff --git a/src/ArduinoJson/Variant/VariantData.hpp b/src/ArduinoJson/Variant/VariantData.hpp index e9d7429d..0311fb3c 100644 --- a/src/ArduinoJson/Variant/VariantData.hpp +++ b/src/ArduinoJson/Variant/VariantData.hpp @@ -53,8 +53,8 @@ class VariantData { template typename TVisitor::result_type accept( TVisitor& visit, const ResourceManager* resources) const { -#if ARDUINOJSON_USE_EXTENSIONS - auto extension = getExtension(resources); +#if ARDUINOJSON_USE_EIGHT_BYTE_VALUES + auto eightByteValue = getEightByte(resources); #else (void)resources; // silence warning #endif @@ -64,7 +64,7 @@ class VariantData { #if ARDUINOJSON_USE_DOUBLE case VariantType::Double: - return visit.visit(extension->asDouble); + return visit.visit(eightByteValue->asDouble); #endif case VariantType::Array: @@ -95,10 +95,10 @@ class VariantData { #if ARDUINOJSON_USE_LONG_LONG case VariantType::Int64: - return visit.visit(extension->asInt64); + return visit.visit(eightByteValue->asInt64); case VariantType::Uint64: - return visit.visit(extension->asUint64); + return visit.visit(eightByteValue->asUint64); #endif case VariantType::Boolean: @@ -145,8 +145,8 @@ class VariantData { } bool asBoolean(const ResourceManager* resources) const { -#if ARDUINOJSON_USE_EXTENSIONS - auto extension = getExtension(resources); +#if ARDUINOJSON_USE_EIGHT_BYTE_VALUES + auto eightByteValue = getEightByte(resources); #else (void)resources; // silence warning #endif @@ -160,14 +160,14 @@ class VariantData { return content_.asFloat != 0; #if ARDUINOJSON_USE_DOUBLE case VariantType::Double: - return extension->asDouble != 0; + return eightByteValue->asDouble != 0; #endif case VariantType::Null: return false; #if ARDUINOJSON_USE_LONG_LONG case VariantType::Uint64: case VariantType::Int64: - return extension->asUint64 != 0; + return eightByteValue->asUint64 != 0; #endif default: return true; @@ -193,8 +193,8 @@ class VariantData { template T asFloat(const ResourceManager* resources) const { static_assert(is_floating_point::value, "T must be a floating point"); -#if ARDUINOJSON_USE_EXTENSIONS - auto extension = getExtension(resources); +#if ARDUINOJSON_USE_EIGHT_BYTE_VALUES + auto eightByteValue = getEightByte(resources); #else (void)resources; // silence warning #endif @@ -208,9 +208,9 @@ class VariantData { return static_cast(content_.asInt32); #if ARDUINOJSON_USE_LONG_LONG case VariantType::Uint64: - return static_cast(extension->asUint64); + return static_cast(eightByteValue->asUint64); case VariantType::Int64: - return static_cast(extension->asInt64); + return static_cast(eightByteValue->asInt64); #endif case VariantType::TinyString: str = content_.asTinyString; @@ -225,7 +225,7 @@ class VariantData { return static_cast(content_.asFloat); #if ARDUINOJSON_USE_DOUBLE case VariantType::Double: - return static_cast(extension->asDouble); + return static_cast(eightByteValue->asDouble); #endif default: return 0.0; @@ -238,8 +238,8 @@ class VariantData { template T asIntegral(const ResourceManager* resources) const { static_assert(is_integral::value, "T must be an integral type"); -#if ARDUINOJSON_USE_EXTENSIONS - auto extension = getExtension(resources); +#if ARDUINOJSON_USE_EIGHT_BYTE_VALUES + auto eightByteValue = getEightByte(resources); #else (void)resources; // silence warning #endif @@ -253,9 +253,9 @@ class VariantData { return convertNumber(content_.asInt32); #if ARDUINOJSON_USE_LONG_LONG case VariantType::Uint64: - return convertNumber(extension->asUint64); + return convertNumber(eightByteValue->asUint64); case VariantType::Int64: - return convertNumber(extension->asInt64); + return convertNumber(eightByteValue->asInt64); #endif case VariantType::TinyString: str = content_.asTinyString; @@ -270,7 +270,7 @@ class VariantData { return convertNumber(content_.asFloat); #if ARDUINOJSON_USE_DOUBLE case VariantType::Double: - return convertNumber(extension->asDouble); + return convertNumber(eightByteValue->asDouble); #endif default: return 0; @@ -314,8 +314,8 @@ class VariantData { } } -#if ARDUINOJSON_USE_EXTENSIONS - const VariantExtension* getExtension(const ResourceManager* resources) const; +#if ARDUINOJSON_USE_8_BYTE_VALUES + const EightByteValue* getEightByte(const ResourceManager* resources) const; #endif VariantData* getElement(size_t index, @@ -378,7 +378,7 @@ class VariantData { template bool isInteger(const ResourceManager* resources) const { #if ARDUINOJSON_USE_LONG_LONG - auto extension = getExtension(resources); + auto eightByteValue = getEightByte(resources); #else (void)resources; // silence warning #endif @@ -391,10 +391,10 @@ class VariantData { #if ARDUINOJSON_USE_LONG_LONG case VariantType::Uint64: - return canConvertNumber(extension->asUint64); + return canConvertNumber(eightByteValue->asUint64); case VariantType::Int64: - return canConvertNumber(extension->asInt64); + return canConvertNumber(eightByteValue->asInt64); #endif default: diff --git a/src/ArduinoJson/Variant/VariantImpl.hpp b/src/ArduinoJson/Variant/VariantImpl.hpp index 1c5ec3a3..b1780547 100644 --- a/src/ArduinoJson/Variant/VariantImpl.hpp +++ b/src/ArduinoJson/Variant/VariantImpl.hpp @@ -61,9 +61,9 @@ inline void VariantData::clear(ResourceManager* resources) { if (type_ & VariantTypeBits::OwnedStringBit) resources->dereferenceString(content_.asOwnedString->data); -#if ARDUINOJSON_USE_EXTENSIONS - if (type_ & VariantTypeBits::ExtensionBit) - resources->freeExtension(content_.asSlotId); +#if ARDUINOJSON_USE_EIGHT_BYTE_VALUES + if (type_ & VariantTypeBits::EightByteBit) + resources->freeEightByte(content_.asSlotId); #endif auto collection = asCollection(); @@ -73,12 +73,12 @@ inline void VariantData::clear(ResourceManager* resources) { type_ = VariantType::Null; } -#if ARDUINOJSON_USE_EXTENSIONS -inline const VariantExtension* VariantData::getExtension( +#if ARDUINOJSON_USE_EIGHT_BYTE_VALUES +inline const EightByteValue* VariantData::getEightByteValue( const ResourceManager* resources) const { - return type_ & VariantTypeBits::ExtensionBit - ? resources->getExtension(content_.asSlotId) - : nullptr; + return type_ & VariantTypeBits::EightByteBit + ? resources->getEightByteValue(content_.asSlotId) + : 0; } #endif @@ -101,12 +101,12 @@ enable_if_t VariantData::setFloat( type_ = VariantType::Float; content_.asFloat = valueAsFloat; } else { - auto extension = resources->allocExtension(); - if (!extension) + auto slot = resources->allocEightByte(); + if (!slot) return false; type_ = VariantType::Double; - content_.asSlotId = extension.id(); - extension->asDouble = value; + content_.asSlotId = slot.id(); + slot->asDouble = value; } #else type_ = VariantType::Float; @@ -127,12 +127,12 @@ enable_if_t::value, bool> VariantData::setInteger( } #if ARDUINOJSON_USE_LONG_LONG else { - auto extension = resources->allocExtension(); - if (!extension) + auto slot = resources->allocEightByte(); + if (!slot) return false; type_ = VariantType::Int64; - content_.asSlotId = extension.id(); - extension->asInt64 = value; + content_.asSlotId = slot.id(); + slot->asInt64 = value; } #endif return true; @@ -150,12 +150,12 @@ enable_if_t::value, bool> VariantData::setInteger( } #if ARDUINOJSON_USE_LONG_LONG else { - auto extension = resources->allocExtension(); - if (!extension) + auto slot = resources->allocEightByte(); + if (!slot) return false; type_ = VariantType::Uint64; - content_.asSlotId = extension.id(); - extension->asUint64 = value; + content_.asSlotId = slot.id(); + slot->asUint64 = value; } #endif return true;