forked from bblanchon/ArduinoJson
Compare commits
10 Commits
string-lit
...
replace-ex
Author | SHA1 | Date | |
---|---|---|---|
53f858f55c | |||
6cdd59034d | |||
6ccac18fd4 | |||
3f6fff7d0c | |||
cc2fea45cd | |||
4159af66eb | |||
05942b620a | |||
23c73b061e | |||
c2e756d942 | |||
94aacf873e |
@ -12,7 +12,7 @@ static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
|
|||||||
|
|
||||||
static_assert(ARDUINOJSON_USE_DOUBLE == 0, "ARDUINOJSON_USE_DOUBLE");
|
static_assert(ARDUINOJSON_USE_DOUBLE == 0, "ARDUINOJSON_USE_DOUBLE");
|
||||||
|
|
||||||
static_assert(ArduinoJson::detail::ResourceManager::slotSize == 6, "slot size");
|
static_assert(sizeof(ArduinoJson::detail::VariantData) == 6, "slot size");
|
||||||
|
|
||||||
void setup() {}
|
void setup() {}
|
||||||
void loop() {}
|
void loop() {}
|
||||||
|
@ -10,7 +10,7 @@ static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
|
|||||||
|
|
||||||
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
|
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
|
||||||
|
|
||||||
static_assert(ArduinoJson::detail::ResourceManager::slotSize == 8, "slot size");
|
static_assert(sizeof(VariantData) == 8, "slot size");
|
||||||
|
|
||||||
void setup() {}
|
void setup() {}
|
||||||
void loop() {}
|
void loop() {}
|
||||||
|
@ -10,7 +10,6 @@ static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
|
|||||||
|
|
||||||
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
|
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
|
||||||
|
|
||||||
static_assert(ArduinoJson::detail::ResourceManager::slotSize == 16,
|
static_assert(sizeof(ArduinoJson::detail::VariantData) == 16, "slot size");
|
||||||
"slot size");
|
|
||||||
|
|
||||||
int main() {}
|
int main() {}
|
||||||
|
@ -10,6 +10,6 @@ static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
|
|||||||
|
|
||||||
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
|
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
|
||||||
|
|
||||||
static_assert(ArduinoJson::detail::ResourceManager::slotSize == 8, "slot size");
|
static_assert(sizeof(ArduinoJson::detail::VariantData) == 8, "slot size");
|
||||||
|
|
||||||
int main() {}
|
int main() {}
|
||||||
|
@ -269,10 +269,10 @@ inline size_t sizeofPoolList(size_t n = ARDUINOJSON_INITIAL_POOL_COUNT) {
|
|||||||
return sizeof(MemoryPool<VariantData>) * n;
|
return sizeof(MemoryPool<VariantData>) * n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T = ArduinoJson::detail::VariantData>
|
||||||
inline size_t sizeofPool(
|
inline size_t sizeofPool(
|
||||||
ArduinoJson::detail::SlotCount n = ARDUINOJSON_POOL_CAPACITY) {
|
ArduinoJson::detail::SlotCount n = ARDUINOJSON_POOL_CAPACITY) {
|
||||||
using namespace ArduinoJson::detail;
|
return ArduinoJson::detail::MemoryPool<T>::slotsToBytes(n);
|
||||||
return MemoryPool<VariantData>::slotsToBytes(n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t sizeofStaticStringPool(
|
inline size_t sizeofStaticStringPool(
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "Allocators.hpp"
|
#include "Allocators.hpp"
|
||||||
#include "Literals.hpp"
|
#include "Literals.hpp"
|
||||||
|
|
||||||
using ArduinoJson::detail::sizeofArray;
|
using namespace ArduinoJson::detail;
|
||||||
|
|
||||||
TEST_CASE("JsonArray::add(T)") {
|
TEST_CASE("JsonArray::add(T)") {
|
||||||
SpyingAllocator spy;
|
SpyingAllocator spy;
|
||||||
@ -33,7 +33,8 @@ TEST_CASE("JsonArray::add(T)") {
|
|||||||
REQUIRE(array[0].is<double>());
|
REQUIRE(array[0].is<double>());
|
||||||
REQUIRE_FALSE(array[0].is<bool>());
|
REQUIRE_FALSE(array[0].is<bool>());
|
||||||
REQUIRE(spy.log() == AllocatorLog{
|
REQUIRE(spy.log() == AllocatorLog{
|
||||||
Allocate(sizeofPool()),
|
Allocate(sizeofPool<VariantData>()),
|
||||||
|
Allocate(sizeofPool<EightByteValue>()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "Allocators.hpp"
|
#include "Allocators.hpp"
|
||||||
|
|
||||||
using ArduinoJson::detail::sizeofArray;
|
using namespace ArduinoJson::detail;
|
||||||
|
|
||||||
TEST_CASE("deserialize JSON array") {
|
TEST_CASE("deserialize JSON array") {
|
||||||
SpyingAllocator spy;
|
SpyingAllocator spy;
|
||||||
@ -92,8 +92,12 @@ TEST_CASE("deserialize JSON array") {
|
|||||||
REQUIRE(arr[0].as<double>() == Approx(4.2123456));
|
REQUIRE(arr[0].as<double>() == Approx(4.2123456));
|
||||||
REQUIRE(arr[1] == -7E89);
|
REQUIRE(arr[1] == -7E89);
|
||||||
REQUIRE(spy.log() == AllocatorLog{
|
REQUIRE(spy.log() == AllocatorLog{
|
||||||
Allocate(sizeofPool()),
|
Allocate(sizeofPool<VariantData>()),
|
||||||
Reallocate(sizeofPool(), sizeofPool(4)),
|
Allocate(sizeofPool<EightByteValue>()),
|
||||||
|
Reallocate(sizeofPool<VariantData>(),
|
||||||
|
sizeofPool<VariantData>(2)),
|
||||||
|
Reallocate(sizeofPool<EightByteValue>(),
|
||||||
|
sizeofPool<EightByteValue>(2)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ TEST_CASE("deserializeJson() returns NoMemory if string length overflows") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("deserializeJson() returns NoMemory if extension allocation fails") {
|
TEST_CASE("deserializeJson() returns NoMemory if 8-bit slot allocation fails") {
|
||||||
JsonDocument doc(FailingAllocator::instance());
|
JsonDocument doc(FailingAllocator::instance());
|
||||||
|
|
||||||
SECTION("uint32_t should pass") {
|
SECTION("uint32_t should pass") {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "Allocators.hpp"
|
#include "Allocators.hpp"
|
||||||
#include "Literals.hpp"
|
#include "Literals.hpp"
|
||||||
|
|
||||||
using ArduinoJson::detail::sizeofObject;
|
using namespace ArduinoJson::detail;
|
||||||
|
|
||||||
enum ErrorCode { ERROR_01 = 1, ERROR_10 = 10 };
|
enum ErrorCode { ERROR_01 = 1, ERROR_10 = 10 };
|
||||||
|
|
||||||
@ -197,10 +197,10 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
|||||||
REQUIRE(result == true);
|
REQUIRE(result == true);
|
||||||
REQUIRE(variant.is<double>() == true);
|
REQUIRE(variant.is<double>() == true);
|
||||||
REQUIRE(variant.as<double>() == 1.2);
|
REQUIRE(variant.as<double>() == 1.2);
|
||||||
REQUIRE(spy.log() ==
|
REQUIRE(spy.log() == AllocatorLog{
|
||||||
AllocatorLog{
|
Allocate(sizeofPool<EightByteValue>()),
|
||||||
Allocate(sizeofPool()),
|
Reallocate(sizeofPool<EightByteValue>(),
|
||||||
Reallocate(sizeofPool(), sizeofPool(1)), // one extension slot
|
sizeofPool<EightByteValue>(1)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,10 +220,10 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
|||||||
REQUIRE(result == true);
|
REQUIRE(result == true);
|
||||||
REQUIRE(variant.is<int64_t>() == true);
|
REQUIRE(variant.is<int64_t>() == true);
|
||||||
REQUIRE(variant.as<int64_t>() == -2147483649LL);
|
REQUIRE(variant.as<int64_t>() == -2147483649LL);
|
||||||
REQUIRE(spy.log() ==
|
REQUIRE(spy.log() == AllocatorLog{
|
||||||
AllocatorLog{
|
Allocate(sizeofPool<EightByteValue>()),
|
||||||
Allocate(sizeofPool()),
|
Reallocate(sizeofPool<EightByteValue>(),
|
||||||
Reallocate(sizeofPool(), sizeofPool(1)), // one extension slot
|
sizeofPool<EightByteValue>(1)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,10 +243,10 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
|||||||
REQUIRE(result == true);
|
REQUIRE(result == true);
|
||||||
REQUIRE(variant.is<uint64_t>() == true);
|
REQUIRE(variant.is<uint64_t>() == true);
|
||||||
REQUIRE(variant.as<uint64_t>() == 4294967296);
|
REQUIRE(variant.as<uint64_t>() == 4294967296);
|
||||||
REQUIRE(spy.log() ==
|
REQUIRE(spy.log() == AllocatorLog{
|
||||||
AllocatorLog{
|
Allocate(sizeofPool<EightByteValue>()),
|
||||||
Allocate(sizeofPool()),
|
Reallocate(sizeofPool<EightByteValue>(),
|
||||||
Reallocate(sizeofPool(), sizeofPool(1)), // one extension slot
|
sizeofPool<EightByteValue>(1)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,7 +378,7 @@ TEST_CASE("JsonVariant::set() releases the previous value") {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SECTION("float") {
|
SECTION("float") {
|
||||||
v.set(1.2);
|
v.set(1.2f);
|
||||||
REQUIRE(spy.log() == AllocatorLog{
|
REQUIRE(spy.log() == AllocatorLog{
|
||||||
Deallocate(sizeofString("world")),
|
Deallocate(sizeofString("world")),
|
||||||
});
|
});
|
||||||
@ -393,7 +393,7 @@ TEST_CASE("JsonVariant::set() releases the previous value") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("JsonVariant::set() reuses extension slot") {
|
TEST_CASE("JsonVariant::set() reuses 8-bit slot") {
|
||||||
SpyingAllocator spy;
|
SpyingAllocator spy;
|
||||||
JsonDocument doc(&spy);
|
JsonDocument doc(&spy);
|
||||||
JsonVariant variant = doc.to<JsonVariant>();
|
JsonVariant variant = doc.to<JsonVariant>();
|
||||||
|
@ -73,7 +73,7 @@ inline bool ArrayData::addValue(const T& value, ResourceManager* resources) {
|
|||||||
|
|
||||||
// Returns the size (in bytes) of an array with n elements.
|
// Returns the size (in bytes) of an array with n elements.
|
||||||
constexpr size_t sizeofArray(size_t n) {
|
constexpr size_t sizeofArray(size_t n) {
|
||||||
return n * ResourceManager::slotSize;
|
return n * sizeof(VariantData);
|
||||||
}
|
}
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -274,9 +274,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_DOUBLE
|
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_DOUBLE
|
||||||
# define ARDUINOJSON_USE_EXTENSIONS 1
|
# define ARDUINOJSON_USE_8_BYTE_POOL 1
|
||||||
#else
|
#else
|
||||||
# define ARDUINOJSON_USE_EXTENSIONS 0
|
# define ARDUINOJSON_USE_8_BYTE_POOL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(nullptr)
|
#if defined(nullptr)
|
||||||
|
@ -18,16 +18,7 @@ class VariantData;
|
|||||||
class VariantWithId;
|
class VariantWithId;
|
||||||
|
|
||||||
class ResourceManager {
|
class ResourceManager {
|
||||||
union SlotData {
|
|
||||||
VariantData variant;
|
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
|
||||||
VariantExtension extension;
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr static size_t slotSize = sizeof(SlotData);
|
|
||||||
|
|
||||||
ResourceManager(Allocator* allocator = DefaultAllocator::instance())
|
ResourceManager(Allocator* allocator = DefaultAllocator::instance())
|
||||||
: allocator_(allocator), overflowed_(false) {}
|
: allocator_(allocator), overflowed_(false) {}
|
||||||
|
|
||||||
@ -35,6 +26,9 @@ class ResourceManager {
|
|||||||
stringPool_.clear(allocator_);
|
stringPool_.clear(allocator_);
|
||||||
variantPools_.clear(allocator_);
|
variantPools_.clear(allocator_);
|
||||||
staticStringsPools_.clear(allocator_);
|
staticStringsPools_.clear(allocator_);
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
eightBytePools_.clear(allocator_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceManager(const ResourceManager&) = delete;
|
ResourceManager(const ResourceManager&) = delete;
|
||||||
@ -44,6 +38,9 @@ class ResourceManager {
|
|||||||
swap(a.stringPool_, b.stringPool_);
|
swap(a.stringPool_, b.stringPool_);
|
||||||
swap(a.variantPools_, b.variantPools_);
|
swap(a.variantPools_, b.variantPools_);
|
||||||
swap(a.staticStringsPools_, b.staticStringsPools_);
|
swap(a.staticStringsPools_, b.staticStringsPools_);
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
swap(a.eightBytePools_, b.eightBytePools_);
|
||||||
|
#endif
|
||||||
swap_(a.allocator_, b.allocator_);
|
swap_(a.allocator_, b.allocator_);
|
||||||
swap_(a.overflowed_, b.overflowed_);
|
swap_(a.overflowed_, b.overflowed_);
|
||||||
}
|
}
|
||||||
@ -64,10 +61,10 @@ class ResourceManager {
|
|||||||
void freeVariant(Slot<VariantData> slot);
|
void freeVariant(Slot<VariantData> slot);
|
||||||
VariantData* getVariant(SlotId id) const;
|
VariantData* getVariant(SlotId id) const;
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
Slot<VariantExtension> allocExtension();
|
Slot<EightByteValue> allocEightByte();
|
||||||
void freeExtension(SlotId slot);
|
void freeEightByte(SlotId slot);
|
||||||
VariantExtension* getExtension(SlotId id) const;
|
EightByteValue* getEightByte(SlotId id) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
@ -136,19 +133,28 @@ class ResourceManager {
|
|||||||
variantPools_.clear(allocator_);
|
variantPools_.clear(allocator_);
|
||||||
stringPool_.clear(allocator_);
|
stringPool_.clear(allocator_);
|
||||||
staticStringsPools_.clear(allocator_);
|
staticStringsPools_.clear(allocator_);
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
eightBytePools_.clear(allocator_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void shrinkToFit() {
|
void shrinkToFit() {
|
||||||
variantPools_.shrinkToFit(allocator_);
|
variantPools_.shrinkToFit(allocator_);
|
||||||
staticStringsPools_.shrinkToFit(allocator_);
|
staticStringsPools_.shrinkToFit(allocator_);
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
eightBytePools_.shrinkToFit(allocator_);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Allocator* allocator_;
|
Allocator* allocator_;
|
||||||
bool overflowed_;
|
bool overflowed_;
|
||||||
StringPool stringPool_;
|
StringPool stringPool_;
|
||||||
MemoryPoolList<SlotData> variantPools_;
|
MemoryPoolList<VariantData> variantPools_;
|
||||||
MemoryPoolList<const char*> staticStringsPools_;
|
MemoryPoolList<const char*> staticStringsPools_;
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
MemoryPoolList<EightByteValue> eightBytePools_;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -12,40 +12,41 @@
|
|||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
inline Slot<VariantData> ResourceManager::allocVariant() {
|
inline Slot<VariantData> ResourceManager::allocVariant() {
|
||||||
auto p = variantPools_.allocSlot(allocator_);
|
auto slot = variantPools_.allocSlot(allocator_);
|
||||||
if (!p) {
|
if (!slot) {
|
||||||
overflowed_ = true;
|
overflowed_ = true;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return {new (&p->variant) VariantData, p.id()};
|
new (slot.ptr()) VariantData();
|
||||||
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void ResourceManager::freeVariant(Slot<VariantData> variant) {
|
inline void ResourceManager::freeVariant(Slot<VariantData> slot) {
|
||||||
variant->clear(this);
|
slot->clear(this);
|
||||||
variantPools_.freeSlot({alias_cast<SlotData*>(variant.ptr()), variant.id()});
|
variantPools_.freeSlot(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* ResourceManager::getVariant(SlotId id) const {
|
inline VariantData* ResourceManager::getVariant(SlotId id) const {
|
||||||
return reinterpret_cast<VariantData*>(variantPools_.getSlot(id));
|
return reinterpret_cast<VariantData*>(variantPools_.getSlot(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
inline Slot<VariantExtension> ResourceManager::allocExtension() {
|
inline Slot<EightByteValue> ResourceManager::allocEightByte() {
|
||||||
auto p = variantPools_.allocSlot(allocator_);
|
auto slot = eightBytePools_.allocSlot(allocator_);
|
||||||
if (!p) {
|
if (!slot) {
|
||||||
overflowed_ = true;
|
overflowed_ = true;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return {&p->extension, p.id()};
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void ResourceManager::freeExtension(SlotId id) {
|
inline void ResourceManager::freeEightByte(SlotId id) {
|
||||||
auto p = getExtension(id);
|
auto p = getEightByte(id);
|
||||||
variantPools_.freeSlot({reinterpret_cast<SlotData*>(p), id});
|
eightBytePools_.freeSlot({p, id});
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantExtension* ResourceManager::getExtension(SlotId id) const {
|
inline EightByteValue* ResourceManager::getEightByte(SlotId id) const {
|
||||||
return &variantPools_.getSlot(id)->extension;
|
return eightBytePools_.getSlot(id);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ inline VariantData* ObjectData::addPair(VariantData** value,
|
|||||||
|
|
||||||
// Returns the size (in bytes) of an object with n members.
|
// Returns the size (in bytes) of an object with n members.
|
||||||
constexpr size_t sizeofObject(size_t n) {
|
constexpr size_t sizeofObject(size_t n) {
|
||||||
return 2 * n * ResourceManager::slotSize;
|
return 2 * n * sizeof(VariantData);
|
||||||
}
|
}
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -16,9 +16,7 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
|||||||
enum class VariantTypeBits : uint8_t {
|
enum class VariantTypeBits : uint8_t {
|
||||||
OwnedStringBit = 0x01, // 0000 0001
|
OwnedStringBit = 0x01, // 0000 0001
|
||||||
NumberBit = 0x08, // 0000 1000
|
NumberBit = 0x08, // 0000 1000
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
EightByteBit = 0x10, // 0001 0000
|
||||||
ExtensionBit = 0x10, // 0001 0000
|
|
||||||
#endif
|
|
||||||
CollectionMask = 0x60,
|
CollectionMask = 0x60,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,8 +62,8 @@ union VariantContent {
|
|||||||
char asTinyString[tinyStringMaxLength + 1];
|
char asTinyString[tinyStringMaxLength + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
union VariantExtension {
|
union EightByteValue {
|
||||||
# if ARDUINOJSON_USE_LONG_LONG
|
# if ARDUINOJSON_USE_LONG_LONG
|
||||||
uint64_t asUint64;
|
uint64_t asUint64;
|
||||||
int64_t asInt64;
|
int64_t asInt64;
|
||||||
@ -74,6 +72,9 @@ union VariantExtension {
|
|||||||
double asDouble;
|
double asDouble;
|
||||||
# endif
|
# endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(EightByteValue) == 8,
|
||||||
|
"sizeof(EightByteValue) must be 8 bytes");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -53,8 +53,8 @@ class VariantData {
|
|||||||
template <typename TVisitor>
|
template <typename TVisitor>
|
||||||
typename TVisitor::result_type accept(
|
typename TVisitor::result_type accept(
|
||||||
TVisitor& visit, const ResourceManager* resources) const {
|
TVisitor& visit, const ResourceManager* resources) const {
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
auto extension = getExtension(resources);
|
auto eightByteValue = getEightByte(resources);
|
||||||
#else
|
#else
|
||||||
(void)resources; // silence warning
|
(void)resources; // silence warning
|
||||||
#endif
|
#endif
|
||||||
@ -64,7 +64,7 @@ class VariantData {
|
|||||||
|
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
case VariantType::Double:
|
case VariantType::Double:
|
||||||
return visit.visit(extension->asDouble);
|
return visit.visit(eightByteValue->asDouble);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case VariantType::Array:
|
case VariantType::Array:
|
||||||
@ -95,10 +95,10 @@ class VariantData {
|
|||||||
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
case VariantType::Int64:
|
case VariantType::Int64:
|
||||||
return visit.visit(extension->asInt64);
|
return visit.visit(eightByteValue->asInt64);
|
||||||
|
|
||||||
case VariantType::Uint64:
|
case VariantType::Uint64:
|
||||||
return visit.visit(extension->asUint64);
|
return visit.visit(eightByteValue->asUint64);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case VariantType::Boolean:
|
case VariantType::Boolean:
|
||||||
@ -145,8 +145,8 @@ class VariantData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool asBoolean(const ResourceManager* resources) const {
|
bool asBoolean(const ResourceManager* resources) const {
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
auto extension = getExtension(resources);
|
auto eightByteValue = getEightByte(resources);
|
||||||
#else
|
#else
|
||||||
(void)resources; // silence warning
|
(void)resources; // silence warning
|
||||||
#endif
|
#endif
|
||||||
@ -160,14 +160,14 @@ class VariantData {
|
|||||||
return content_.asFloat != 0;
|
return content_.asFloat != 0;
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
case VariantType::Double:
|
case VariantType::Double:
|
||||||
return extension->asDouble != 0;
|
return eightByteValue->asDouble != 0;
|
||||||
#endif
|
#endif
|
||||||
case VariantType::Null:
|
case VariantType::Null:
|
||||||
return false;
|
return false;
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
case VariantType::Uint64:
|
case VariantType::Uint64:
|
||||||
case VariantType::Int64:
|
case VariantType::Int64:
|
||||||
return extension->asUint64 != 0;
|
return eightByteValue->asUint64 != 0;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
@ -193,8 +193,8 @@ class VariantData {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T asFloat(const ResourceManager* resources) const {
|
T asFloat(const ResourceManager* resources) const {
|
||||||
static_assert(is_floating_point<T>::value, "T must be a floating point");
|
static_assert(is_floating_point<T>::value, "T must be a floating point");
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
auto extension = getExtension(resources);
|
auto eightByteValue = getEightByte(resources);
|
||||||
#else
|
#else
|
||||||
(void)resources; // silence warning
|
(void)resources; // silence warning
|
||||||
#endif
|
#endif
|
||||||
@ -208,9 +208,9 @@ class VariantData {
|
|||||||
return static_cast<T>(content_.asInt32);
|
return static_cast<T>(content_.asInt32);
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
case VariantType::Uint64:
|
case VariantType::Uint64:
|
||||||
return static_cast<T>(extension->asUint64);
|
return static_cast<T>(eightByteValue->asUint64);
|
||||||
case VariantType::Int64:
|
case VariantType::Int64:
|
||||||
return static_cast<T>(extension->asInt64);
|
return static_cast<T>(eightByteValue->asInt64);
|
||||||
#endif
|
#endif
|
||||||
case VariantType::TinyString:
|
case VariantType::TinyString:
|
||||||
str = content_.asTinyString;
|
str = content_.asTinyString;
|
||||||
@ -225,7 +225,7 @@ class VariantData {
|
|||||||
return static_cast<T>(content_.asFloat);
|
return static_cast<T>(content_.asFloat);
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
case VariantType::Double:
|
case VariantType::Double:
|
||||||
return static_cast<T>(extension->asDouble);
|
return static_cast<T>(eightByteValue->asDouble);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return 0.0;
|
return 0.0;
|
||||||
@ -238,8 +238,8 @@ class VariantData {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T asIntegral(const ResourceManager* resources) const {
|
T asIntegral(const ResourceManager* resources) const {
|
||||||
static_assert(is_integral<T>::value, "T must be an integral type");
|
static_assert(is_integral<T>::value, "T must be an integral type");
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
auto extension = getExtension(resources);
|
auto eightByteValue = getEightByte(resources);
|
||||||
#else
|
#else
|
||||||
(void)resources; // silence warning
|
(void)resources; // silence warning
|
||||||
#endif
|
#endif
|
||||||
@ -253,9 +253,9 @@ class VariantData {
|
|||||||
return convertNumber<T>(content_.asInt32);
|
return convertNumber<T>(content_.asInt32);
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
case VariantType::Uint64:
|
case VariantType::Uint64:
|
||||||
return convertNumber<T>(extension->asUint64);
|
return convertNumber<T>(eightByteValue->asUint64);
|
||||||
case VariantType::Int64:
|
case VariantType::Int64:
|
||||||
return convertNumber<T>(extension->asInt64);
|
return convertNumber<T>(eightByteValue->asInt64);
|
||||||
#endif
|
#endif
|
||||||
case VariantType::TinyString:
|
case VariantType::TinyString:
|
||||||
str = content_.asTinyString;
|
str = content_.asTinyString;
|
||||||
@ -270,7 +270,7 @@ class VariantData {
|
|||||||
return convertNumber<T>(content_.asFloat);
|
return convertNumber<T>(content_.asFloat);
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
case VariantType::Double:
|
case VariantType::Double:
|
||||||
return convertNumber<T>(extension->asDouble);
|
return convertNumber<T>(eightByteValue->asDouble);
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@ -314,8 +314,8 @@ class VariantData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
const VariantExtension* getExtension(const ResourceManager* resources) const;
|
const EightByteValue* getEightByte(const ResourceManager* resources) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VariantData* getElement(size_t index,
|
VariantData* getElement(size_t index,
|
||||||
@ -378,7 +378,7 @@ class VariantData {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
bool isInteger(const ResourceManager* resources) const {
|
bool isInteger(const ResourceManager* resources) const {
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
auto extension = getExtension(resources);
|
auto eightByteValue = getEightByte(resources);
|
||||||
#else
|
#else
|
||||||
(void)resources; // silence warning
|
(void)resources; // silence warning
|
||||||
#endif
|
#endif
|
||||||
@ -391,10 +391,10 @@ class VariantData {
|
|||||||
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
case VariantType::Uint64:
|
case VariantType::Uint64:
|
||||||
return canConvertNumber<T>(extension->asUint64);
|
return canConvertNumber<T>(eightByteValue->asUint64);
|
||||||
|
|
||||||
case VariantType::Int64:
|
case VariantType::Int64:
|
||||||
return canConvertNumber<T>(extension->asInt64);
|
return canConvertNumber<T>(eightByteValue->asInt64);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -61,9 +61,9 @@ inline void VariantData::clear(ResourceManager* resources) {
|
|||||||
if (type_ & VariantTypeBits::OwnedStringBit)
|
if (type_ & VariantTypeBits::OwnedStringBit)
|
||||||
resources->dereferenceString(content_.asOwnedString->data);
|
resources->dereferenceString(content_.asOwnedString->data);
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
if (type_ & VariantTypeBits::ExtensionBit)
|
if (type_ & VariantTypeBits::EightByteBit)
|
||||||
resources->freeExtension(content_.asSlotId);
|
resources->freeEightByte(content_.asSlotId);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto collection = asCollection();
|
auto collection = asCollection();
|
||||||
@ -73,12 +73,12 @@ inline void VariantData::clear(ResourceManager* resources) {
|
|||||||
type_ = VariantType::Null;
|
type_ = VariantType::Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_EXTENSIONS
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
inline const VariantExtension* VariantData::getExtension(
|
inline const EightByteValue* VariantData::getEightByte(
|
||||||
const ResourceManager* resources) const {
|
const ResourceManager* resources) const {
|
||||||
return type_ & VariantTypeBits::ExtensionBit
|
return type_ & VariantTypeBits::EightByteBit
|
||||||
? resources->getExtension(content_.asSlotId)
|
? resources->getEightByte(content_.asSlotId)
|
||||||
: nullptr;
|
: 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -101,12 +101,12 @@ enable_if_t<sizeof(T) == 8, bool> VariantData::setFloat(
|
|||||||
type_ = VariantType::Float;
|
type_ = VariantType::Float;
|
||||||
content_.asFloat = valueAsFloat;
|
content_.asFloat = valueAsFloat;
|
||||||
} else {
|
} else {
|
||||||
auto extension = resources->allocExtension();
|
auto slot = resources->allocEightByte();
|
||||||
if (!extension)
|
if (!slot)
|
||||||
return false;
|
return false;
|
||||||
type_ = VariantType::Double;
|
type_ = VariantType::Double;
|
||||||
content_.asSlotId = extension.id();
|
content_.asSlotId = slot.id();
|
||||||
extension->asDouble = value;
|
slot->asDouble = value;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
type_ = VariantType::Float;
|
type_ = VariantType::Float;
|
||||||
@ -127,12 +127,12 @@ enable_if_t<is_signed<T>::value, bool> VariantData::setInteger(
|
|||||||
}
|
}
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
else {
|
else {
|
||||||
auto extension = resources->allocExtension();
|
auto slot = resources->allocEightByte();
|
||||||
if (!extension)
|
if (!slot)
|
||||||
return false;
|
return false;
|
||||||
type_ = VariantType::Int64;
|
type_ = VariantType::Int64;
|
||||||
content_.asSlotId = extension.id();
|
content_.asSlotId = slot.id();
|
||||||
extension->asInt64 = value;
|
slot->asInt64 = value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
@ -150,12 +150,12 @@ enable_if_t<is_unsigned<T>::value, bool> VariantData::setInteger(
|
|||||||
}
|
}
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
else {
|
else {
|
||||||
auto extension = resources->allocExtension();
|
auto slot = resources->allocEightByte();
|
||||||
if (!extension)
|
if (!slot)
|
||||||
return false;
|
return false;
|
||||||
type_ = VariantType::Uint64;
|
type_ = VariantType::Uint64;
|
||||||
content_.asSlotId = extension.id();
|
content_.asSlotId = slot.id();
|
||||||
extension->asUint64 = value;
|
slot->asUint64 = value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
|
Reference in New Issue
Block a user