forked from bblanchon/ArduinoJson
Replace extension with eight-byte values
This commit is contained in:
@ -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)
|
||||
|
@ -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<VariantData> slot);
|
||||
VariantData* getVariant(SlotId id) const;
|
||||
|
||||
#if ARDUINOJSON_USE_EXTENSIONS
|
||||
Slot<VariantExtension> allocExtension();
|
||||
void freeExtension(SlotId slot);
|
||||
VariantExtension* getExtension(SlotId id) const;
|
||||
#if ARDUINOJSON_USE_8_BYTE_VALUES
|
||||
Slot<EightByteValue> allocEightByte();
|
||||
void freeEightByte(SlotId slot);
|
||||
EightByteValue* getEightByte(SlotId id) const;
|
||||
#endif
|
||||
|
||||
template <typename TAdaptedString>
|
||||
@ -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<SlotData> variantPools_;
|
||||
MemoryPoolList<const char*> staticStringsPools_;
|
||||
#if ARDUINOJSON_USE_8_BYTE_VALUES
|
||||
MemoryPoolList<EightByteValue> eightBytePools_;
|
||||
#endif
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -29,23 +29,23 @@ inline VariantData* ResourceManager::getVariant(SlotId id) const {
|
||||
return reinterpret_cast<VariantData*>(variantPools_.getSlot(id));
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_USE_EXTENSIONS
|
||||
inline Slot<VariantExtension> ResourceManager::allocExtension() {
|
||||
auto p = variantPools_.allocSlot(allocator_);
|
||||
if (!p) {
|
||||
#if ARDUINOJSON_USE_8_BYTE_VALUES
|
||||
inline Slot<EightByteValue> 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<SlotData*>(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
|
||||
|
||||
|
@ -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
|
||||
|
@ -53,8 +53,8 @@ class VariantData {
|
||||
template <typename TVisitor>
|
||||
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 <typename T>
|
||||
T asFloat(const ResourceManager* resources) const {
|
||||
static_assert(is_floating_point<T>::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<T>(content_.asInt32);
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
case VariantType::Uint64:
|
||||
return static_cast<T>(extension->asUint64);
|
||||
return static_cast<T>(eightByteValue->asUint64);
|
||||
case VariantType::Int64:
|
||||
return static_cast<T>(extension->asInt64);
|
||||
return static_cast<T>(eightByteValue->asInt64);
|
||||
#endif
|
||||
case VariantType::TinyString:
|
||||
str = content_.asTinyString;
|
||||
@ -225,7 +225,7 @@ class VariantData {
|
||||
return static_cast<T>(content_.asFloat);
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
case VariantType::Double:
|
||||
return static_cast<T>(extension->asDouble);
|
||||
return static_cast<T>(eightByteValue->asDouble);
|
||||
#endif
|
||||
default:
|
||||
return 0.0;
|
||||
@ -238,8 +238,8 @@ class VariantData {
|
||||
template <typename T>
|
||||
T asIntegral(const ResourceManager* resources) const {
|
||||
static_assert(is_integral<T>::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<T>(content_.asInt32);
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
case VariantType::Uint64:
|
||||
return convertNumber<T>(extension->asUint64);
|
||||
return convertNumber<T>(eightByteValue->asUint64);
|
||||
case VariantType::Int64:
|
||||
return convertNumber<T>(extension->asInt64);
|
||||
return convertNumber<T>(eightByteValue->asInt64);
|
||||
#endif
|
||||
case VariantType::TinyString:
|
||||
str = content_.asTinyString;
|
||||
@ -270,7 +270,7 @@ class VariantData {
|
||||
return convertNumber<T>(content_.asFloat);
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
case VariantType::Double:
|
||||
return convertNumber<T>(extension->asDouble);
|
||||
return convertNumber<T>(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 <typename T>
|
||||
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<T>(extension->asUint64);
|
||||
return canConvertNumber<T>(eightByteValue->asUint64);
|
||||
|
||||
case VariantType::Int64:
|
||||
return canConvertNumber<T>(extension->asInt64);
|
||||
return canConvertNumber<T>(eightByteValue->asInt64);
|
||||
#endif
|
||||
|
||||
default:
|
||||
|
@ -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<sizeof(T) == 8, bool> 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<is_signed<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<is_unsigned<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;
|
||||
|
Reference in New Issue
Block a user