forked from bblanchon/ArduinoJson
Compare commits
5 Commits
string-lit
...
7.5
Author | SHA1 | Date | |
---|---|---|---|
cc73fec1cf | |||
535a9b3e86 | |||
72075e9ad2 | |||
56b269bea8 | |||
817998d0fe |
@ -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::detail::ResourceManager::slotSize == 6, "slot size");
|
||||
static_assert(sizeof(ArduinoJson::detail::VariantData) == 6, "slot size");
|
||||
|
||||
void setup() {}
|
||||
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::detail::ResourceManager::slotSize == 8, "slot size");
|
||||
static_assert(sizeof(ArduinoJson::detail::VariantData) == 8, "slot size");
|
||||
|
||||
void setup() {}
|
||||
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::detail::ResourceManager::slotSize == 16,
|
||||
"slot size");
|
||||
static_assert(sizeof(ArduinoJson::detail::VariantData) == 16, "slot size");
|
||||
|
||||
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::detail::ResourceManager::slotSize == 8, "slot size");
|
||||
static_assert(sizeof(ArduinoJson::detail::VariantData) == 8, "slot size");
|
||||
|
||||
int main() {}
|
||||
|
@ -269,10 +269,10 @@ inline size_t sizeofPoolList(size_t n = ARDUINOJSON_INITIAL_POOL_COUNT) {
|
||||
return sizeof(MemoryPool<VariantData>) * n;
|
||||
}
|
||||
|
||||
template <typename T = ArduinoJson::detail::VariantData>
|
||||
inline size_t sizeofPool(
|
||||
ArduinoJson::detail::SlotCount n = ARDUINOJSON_POOL_CAPACITY) {
|
||||
using namespace ArduinoJson::detail;
|
||||
return MemoryPool<VariantData>::slotsToBytes(n);
|
||||
return ArduinoJson::detail::MemoryPool<T>::slotsToBytes(n);
|
||||
}
|
||||
|
||||
inline size_t sizeofStaticStringPool(
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "Allocators.hpp"
|
||||
#include "Literals.hpp"
|
||||
|
||||
using ArduinoJson::detail::sizeofArray;
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("JsonArray::add(T)") {
|
||||
SpyingAllocator spy;
|
||||
@ -33,7 +33,8 @@ TEST_CASE("JsonArray::add(T)") {
|
||||
REQUIRE(array[0].is<double>());
|
||||
REQUIRE_FALSE(array[0].is<bool>());
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Allocate(sizeofPool<VariantData>()),
|
||||
Allocate(sizeofPool<EightByteValue>()),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include "Allocators.hpp"
|
||||
|
||||
using ArduinoJson::detail::sizeofArray;
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
TEST_CASE("deserialize JSON array") {
|
||||
SpyingAllocator spy;
|
||||
@ -92,8 +92,12 @@ TEST_CASE("deserialize JSON array") {
|
||||
REQUIRE(arr[0].as<double>() == Approx(4.2123456));
|
||||
REQUIRE(arr[1] == -7E89);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(4)),
|
||||
Allocate(sizeofPool<VariantData>()),
|
||||
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());
|
||||
|
||||
SECTION("uint32_t should pass") {
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "Allocators.hpp"
|
||||
#include "Literals.hpp"
|
||||
|
||||
using ArduinoJson::detail::sizeofObject;
|
||||
using namespace ArduinoJson::detail;
|
||||
|
||||
enum ErrorCode { ERROR_01 = 1, ERROR_10 = 10 };
|
||||
|
||||
@ -197,11 +197,11 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<double>() == true);
|
||||
REQUIRE(variant.as<double>() == 1.2);
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)), // one extension slot
|
||||
});
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool<EightByteValue>()),
|
||||
Reallocate(sizeofPool<EightByteValue>(),
|
||||
sizeofPool<EightByteValue>(1)),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("int32_t") {
|
||||
@ -220,11 +220,11 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<int64_t>() == true);
|
||||
REQUIRE(variant.as<int64_t>() == -2147483649LL);
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)), // one extension slot
|
||||
});
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool<EightByteValue>()),
|
||||
Reallocate(sizeofPool<EightByteValue>(),
|
||||
sizeofPool<EightByteValue>(1)),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("uint32_t") {
|
||||
@ -243,11 +243,11 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
REQUIRE(result == true);
|
||||
REQUIRE(variant.is<uint64_t>() == true);
|
||||
REQUIRE(variant.as<uint64_t>() == 4294967296);
|
||||
REQUIRE(spy.log() ==
|
||||
AllocatorLog{
|
||||
Allocate(sizeofPool()),
|
||||
Reallocate(sizeofPool(), sizeofPool(1)), // one extension slot
|
||||
});
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
Allocate(sizeofPool<EightByteValue>()),
|
||||
Reallocate(sizeofPool<EightByteValue>(),
|
||||
sizeofPool<EightByteValue>(1)),
|
||||
});
|
||||
}
|
||||
|
||||
SECTION("JsonDocument") {
|
||||
@ -378,7 +378,7 @@ TEST_CASE("JsonVariant::set() releases the previous value") {
|
||||
}
|
||||
|
||||
SECTION("float") {
|
||||
v.set(1.2);
|
||||
v.set(1.2f);
|
||||
REQUIRE(spy.log() == AllocatorLog{
|
||||
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;
|
||||
JsonDocument doc(&spy);
|
||||
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.
|
||||
constexpr size_t sizeofArray(size_t n) {
|
||||
return n * ResourceManager::slotSize;
|
||||
return n * sizeof(VariantData);
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -23,7 +23,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
JsonArray() : data_(0), resources_(0) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArray(detail::ArrayData* data, detail::ResourceManager* resources)
|
||||
JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
|
||||
: data_(data), resources_(resources) {}
|
||||
|
||||
// Returns a JsonVariant pointing to the array.
|
||||
@ -37,7 +37,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Returns a read-only reference to the array.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/
|
||||
operator JsonArrayConst() const {
|
||||
return JsonArrayConst(data_, resources_);
|
||||
return JsonArrayConst(getData(), resources_);
|
||||
}
|
||||
|
||||
// Appends a new (empty) element to the array.
|
||||
@ -55,7 +55,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
template <typename T, detail::enable_if_t<
|
||||
detail::is_same<T, JsonVariant>::value, int> = 0>
|
||||
JsonVariant add() const {
|
||||
return JsonVariant(detail::ArrayData::addElement(data_, resources_),
|
||||
return JsonVariant(detail::VariantData::addElement(data_, resources_),
|
||||
resources_);
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// https://arduinojson.org/v7/api/jsonarray/add/
|
||||
template <typename T>
|
||||
bool add(const T& value) const {
|
||||
return detail::ArrayData::addValue(data_, value, resources_);
|
||||
return detail::VariantData::addValue(data_, value, resources_);
|
||||
}
|
||||
|
||||
// Appends a value to the array.
|
||||
@ -71,15 +71,16 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
template <typename T,
|
||||
detail::enable_if_t<!detail::is_const<T>::value, int> = 0>
|
||||
bool add(T* value) const {
|
||||
return detail::ArrayData::addValue(data_, value, resources_);
|
||||
return detail::VariantData::addValue(data_, value, resources_);
|
||||
}
|
||||
|
||||
// Returns an iterator to the first element of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/begin/
|
||||
iterator begin() const {
|
||||
if (!data_)
|
||||
auto array = detail::VariantData::asArray(data_);
|
||||
if (!array)
|
||||
return iterator();
|
||||
return iterator(data_->createIterator(resources_), resources_);
|
||||
return iterator(array->createIterator(resources_), resources_);
|
||||
}
|
||||
|
||||
// Returns an iterator following the last element of the array.
|
||||
@ -106,13 +107,14 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Removes the element at the specified iterator.
|
||||
// https://arduinojson.org/v7/api/jsonarray/remove/
|
||||
void remove(iterator it) const {
|
||||
detail::ArrayData::remove(data_, it.iterator_, resources_);
|
||||
detail::ArrayData::remove(detail::VariantData::asArray(data_), it.iterator_,
|
||||
resources_);
|
||||
}
|
||||
|
||||
// Removes the element at the specified index.
|
||||
// https://arduinojson.org/v7/api/jsonarray/remove/
|
||||
void remove(size_t index) const {
|
||||
detail::ArrayData::removeElement(data_, index, resources_);
|
||||
detail::VariantData::removeElement(data_, index, resources_);
|
||||
}
|
||||
|
||||
// Removes the element at the specified index.
|
||||
@ -127,7 +129,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
// Removes all the elements of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/clear/
|
||||
void clear() const {
|
||||
detail::ArrayData::clear(data_, resources_);
|
||||
detail::ArrayData::clear(detail::VariantData::asArray(data_), resources_);
|
||||
}
|
||||
|
||||
// Gets or sets the element at the specified index.
|
||||
@ -150,25 +152,25 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(collectionToVariant(data_), resources_);
|
||||
return JsonVariantConst(data_, resources_);
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonarray/isnull/
|
||||
bool isNull() const {
|
||||
return data_ == 0;
|
||||
return !data_ || !data_->isArray();
|
||||
}
|
||||
|
||||
// Returns true if the reference is bound.
|
||||
// https://arduinojson.org/v7/api/jsonarray/isnull/
|
||||
operator bool() const {
|
||||
return data_ != 0;
|
||||
return !isNull();
|
||||
}
|
||||
|
||||
// Returns the depth (nesting level) of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarray/nesting/
|
||||
size_t nesting() const {
|
||||
return detail::VariantData::nesting(collectionToVariant(data_), resources_);
|
||||
return detail::VariantData::nesting(data_, resources_);
|
||||
}
|
||||
|
||||
// Returns the number of elements in the array.
|
||||
@ -205,14 +207,14 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
|
||||
}
|
||||
|
||||
detail::VariantData* getData() const {
|
||||
return collectionToVariant(data_);
|
||||
return data_;
|
||||
}
|
||||
|
||||
detail::VariantData* getOrCreateData() const {
|
||||
return collectionToVariant(data_);
|
||||
return data_;
|
||||
}
|
||||
|
||||
detail::ArrayData* data_;
|
||||
detail::VariantData* data_;
|
||||
detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
|
@ -24,9 +24,10 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
// Returns an iterator to the first element of the array.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/begin/
|
||||
iterator begin() const {
|
||||
if (!data_)
|
||||
auto array = detail::VariantData::asArray(data_);
|
||||
if (!array)
|
||||
return iterator();
|
||||
return iterator(data_->createIterator(resources_), resources_);
|
||||
return iterator(array->createIterator(resources_), resources_);
|
||||
}
|
||||
|
||||
// Returns an iterator to the element following the last element of the array.
|
||||
@ -39,7 +40,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
JsonArrayConst() : data_(0), resources_(0) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonArrayConst(const detail::ArrayData* data,
|
||||
JsonArrayConst(const detail::VariantData* data,
|
||||
const detail::ResourceManager* resources)
|
||||
: data_(data), resources_(resources) {}
|
||||
|
||||
@ -49,7 +50,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
detail::enable_if_t<detail::is_integral<T>::value, int> = 0>
|
||||
JsonVariantConst operator[](T index) const {
|
||||
return JsonVariantConst(
|
||||
detail::ArrayData::getElement(data_, size_t(index), resources_),
|
||||
detail::VariantData::getElement(data_, size_t(index), resources_),
|
||||
resources_);
|
||||
}
|
||||
|
||||
@ -71,13 +72,13 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
// Returns true if the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/isnull/
|
||||
bool isNull() const {
|
||||
return data_ == 0;
|
||||
return !data_ || !data_->isArray();
|
||||
}
|
||||
|
||||
// Returns true if the reference is bound.
|
||||
// https://arduinojson.org/v7/api/jsonarrayconst/isnull/
|
||||
operator bool() const {
|
||||
return data_ != 0;
|
||||
return !isNull();
|
||||
}
|
||||
|
||||
// Returns the depth (nesting level) of the array.
|
||||
@ -100,10 +101,10 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
|
||||
|
||||
private:
|
||||
const detail::VariantData* getData() const {
|
||||
return collectionToVariant(data_);
|
||||
return data_;
|
||||
}
|
||||
|
||||
const detail::ArrayData* data_;
|
||||
const detail::VariantData* data_;
|
||||
const detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
|
@ -274,9 +274,9 @@
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_DOUBLE
|
||||
# define ARDUINOJSON_USE_EXTENSIONS 1
|
||||
# define ARDUINOJSON_USE_8_BYTE_POOL 1
|
||||
#else
|
||||
# define ARDUINOJSON_USE_EXTENSIONS 0
|
||||
# define ARDUINOJSON_USE_8_BYTE_POOL 0
|
||||
#endif
|
||||
|
||||
#if defined(nullptr)
|
||||
|
@ -18,16 +18,7 @@ class VariantData;
|
||||
class VariantWithId;
|
||||
|
||||
class ResourceManager {
|
||||
union SlotData {
|
||||
VariantData variant;
|
||||
#if ARDUINOJSON_USE_EXTENSIONS
|
||||
VariantExtension extension;
|
||||
#endif
|
||||
};
|
||||
|
||||
public:
|
||||
constexpr static size_t slotSize = sizeof(SlotData);
|
||||
|
||||
ResourceManager(Allocator* allocator = DefaultAllocator::instance())
|
||||
: allocator_(allocator), overflowed_(false) {}
|
||||
|
||||
@ -35,6 +26,9 @@ class ResourceManager {
|
||||
stringPool_.clear(allocator_);
|
||||
variantPools_.clear(allocator_);
|
||||
staticStringsPools_.clear(allocator_);
|
||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||
eightBytePools_.clear(allocator_);
|
||||
#endif
|
||||
}
|
||||
|
||||
ResourceManager(const ResourceManager&) = delete;
|
||||
@ -44,6 +38,9 @@ class ResourceManager {
|
||||
swap(a.stringPool_, b.stringPool_);
|
||||
swap(a.variantPools_, b.variantPools_);
|
||||
swap(a.staticStringsPools_, b.staticStringsPools_);
|
||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||
swap(a.eightBytePools_, b.eightBytePools_);
|
||||
#endif
|
||||
swap_(a.allocator_, b.allocator_);
|
||||
swap_(a.overflowed_, b.overflowed_);
|
||||
}
|
||||
@ -64,10 +61,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_POOL
|
||||
Slot<EightByteValue> allocEightByte();
|
||||
void freeEightByte(SlotId slot);
|
||||
EightByteValue* getEightByte(SlotId id) const;
|
||||
#endif
|
||||
|
||||
template <typename TAdaptedString>
|
||||
@ -136,19 +133,28 @@ class ResourceManager {
|
||||
variantPools_.clear(allocator_);
|
||||
stringPool_.clear(allocator_);
|
||||
staticStringsPools_.clear(allocator_);
|
||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||
eightBytePools_.clear(allocator_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void shrinkToFit() {
|
||||
variantPools_.shrinkToFit(allocator_);
|
||||
staticStringsPools_.shrinkToFit(allocator_);
|
||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||
eightBytePools_.shrinkToFit(allocator_);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
Allocator* allocator_;
|
||||
bool overflowed_;
|
||||
StringPool stringPool_;
|
||||
MemoryPoolList<SlotData> variantPools_;
|
||||
MemoryPoolList<VariantData> variantPools_;
|
||||
MemoryPoolList<const char*> staticStringsPools_;
|
||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||
MemoryPoolList<EightByteValue> eightBytePools_;
|
||||
#endif
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -12,40 +12,41 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
inline Slot<VariantData> ResourceManager::allocVariant() {
|
||||
auto p = variantPools_.allocSlot(allocator_);
|
||||
if (!p) {
|
||||
auto slot = variantPools_.allocSlot(allocator_);
|
||||
if (!slot) {
|
||||
overflowed_ = true;
|
||||
return {};
|
||||
}
|
||||
return {new (&p->variant) VariantData, p.id()};
|
||||
new (slot.ptr()) VariantData();
|
||||
return slot;
|
||||
}
|
||||
|
||||
inline void ResourceManager::freeVariant(Slot<VariantData> variant) {
|
||||
variant->clear(this);
|
||||
variantPools_.freeSlot({alias_cast<SlotData*>(variant.ptr()), variant.id()});
|
||||
inline void ResourceManager::freeVariant(Slot<VariantData> slot) {
|
||||
slot->clear(this);
|
||||
variantPools_.freeSlot(slot);
|
||||
}
|
||||
|
||||
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_POOL
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -23,7 +23,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
JsonObject() : data_(0), resources_(0) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonObject(detail::ObjectData* data, detail::ResourceManager* resource)
|
||||
JsonObject(detail::VariantData* data, detail::ResourceManager* resource)
|
||||
: data_(data), resources_(resource) {}
|
||||
|
||||
operator JsonVariant() const {
|
||||
@ -37,25 +37,25 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
}
|
||||
|
||||
operator JsonVariantConst() const {
|
||||
return JsonVariantConst(collectionToVariant(data_), resources_);
|
||||
return JsonVariantConst(data_, resources_);
|
||||
}
|
||||
|
||||
// Returns true if the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonobject/isnull/
|
||||
bool isNull() const {
|
||||
return data_ == 0;
|
||||
return !data_ || !data_->isObject();
|
||||
}
|
||||
|
||||
// Returns true if the reference is bound.
|
||||
// https://arduinojson.org/v7/api/jsonobject/isnull/
|
||||
operator bool() const {
|
||||
return data_ != 0;
|
||||
return !isNull();
|
||||
}
|
||||
|
||||
// Returns the depth (nesting level) of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobject/nesting/
|
||||
size_t nesting() const {
|
||||
return detail::VariantData::nesting(collectionToVariant(data_), resources_);
|
||||
return detail::VariantData::nesting(data_, resources_);
|
||||
}
|
||||
|
||||
// Returns the number of members in the object.
|
||||
@ -67,9 +67,10 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Returns an iterator to the first key-value pair of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobject/begin/
|
||||
iterator begin() const {
|
||||
if (!data_)
|
||||
auto obj = detail::VariantData::asObject(data_);
|
||||
if (!obj)
|
||||
return iterator();
|
||||
return iterator(data_->createIterator(resources_), resources_);
|
||||
return iterator(obj->createIterator(resources_), resources_);
|
||||
}
|
||||
|
||||
// Returns an iterator following the last key-value pair of the object.
|
||||
@ -81,7 +82,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Removes all the members of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobject/clear/
|
||||
void clear() const {
|
||||
detail::ObjectData::clear(data_, resources_);
|
||||
detail::ObjectData::clear(detail::VariantData::asObject(data_), resources_);
|
||||
}
|
||||
|
||||
// Copies an object.
|
||||
@ -131,7 +132,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// Removes the member at the specified iterator.
|
||||
// https://arduinojson.org/v7/api/jsonobject/remove/
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
detail::ObjectData::remove(data_, it.iterator_, resources_);
|
||||
detail::ObjectData::remove(detail::VariantData::asObject(data_),
|
||||
it.iterator_, resources_);
|
||||
}
|
||||
|
||||
// Removes the member with the specified key.
|
||||
@ -139,8 +141,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
template <typename TString,
|
||||
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
|
||||
void remove(const TString& key) const {
|
||||
detail::ObjectData::removeMember(data_, detail::adaptString(key),
|
||||
resources_);
|
||||
detail::VariantData::removeMember(data_, detail::adaptString(key),
|
||||
resources_);
|
||||
}
|
||||
|
||||
// Removes the member with the specified key.
|
||||
@ -156,8 +158,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
// https://arduinojson.org/v7/api/jsonobject/remove/
|
||||
template <typename TChar>
|
||||
FORCE_INLINE void remove(TChar* key) const {
|
||||
detail::ObjectData::removeMember(data_, detail::adaptString(key),
|
||||
resources_);
|
||||
detail::VariantData::removeMember(data_, detail::adaptString(key),
|
||||
resources_);
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj[key].is<T>() instead
|
||||
@ -166,8 +168,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
|
||||
ARDUINOJSON_DEPRECATED("use obj[key].is<T>() instead")
|
||||
bool containsKey(const TString& key) const {
|
||||
return detail::ObjectData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
return detail::VariantData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj["key"].is<T>() instead
|
||||
@ -178,8 +180,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
int> = 0>
|
||||
ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead")
|
||||
bool containsKey(TChar* key) const {
|
||||
return detail::ObjectData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
return detail::VariantData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj[key].is<T>() instead
|
||||
@ -231,14 +233,14 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
|
||||
}
|
||||
|
||||
detail::VariantData* getData() const {
|
||||
return detail::collectionToVariant(data_);
|
||||
return data_;
|
||||
}
|
||||
|
||||
detail::VariantData* getOrCreateData() const {
|
||||
return detail::collectionToVariant(data_);
|
||||
return data_;
|
||||
}
|
||||
|
||||
detail::ObjectData* data_;
|
||||
detail::VariantData* data_;
|
||||
detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
|
@ -22,7 +22,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
JsonObjectConst() : data_(0), resources_(0) {}
|
||||
|
||||
// INTERNAL USE ONLY
|
||||
JsonObjectConst(const detail::ObjectData* data,
|
||||
JsonObjectConst(const detail::VariantData* data,
|
||||
const detail::ResourceManager* resources)
|
||||
: data_(data), resources_(resources) {}
|
||||
|
||||
@ -33,13 +33,13 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
// Returns true if the reference is unbound.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/isnull/
|
||||
bool isNull() const {
|
||||
return data_ == 0;
|
||||
return !data_ || !data_->isObject();
|
||||
}
|
||||
|
||||
// Returns true if the reference is bound.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/isnull/
|
||||
operator bool() const {
|
||||
return data_ != 0;
|
||||
return !isNull();
|
||||
}
|
||||
|
||||
// Returns the depth (nesting level) of the object.
|
||||
@ -57,9 +57,10 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
// Returns an iterator to the first key-value pair of the object.
|
||||
// https://arduinojson.org/v7/api/jsonobjectconst/begin/
|
||||
iterator begin() const {
|
||||
if (!data_)
|
||||
auto obj = detail::VariantData::asObject(data_);
|
||||
if (!obj)
|
||||
return iterator();
|
||||
return iterator(data_->createIterator(resources_), resources_);
|
||||
return iterator(obj->createIterator(resources_), resources_);
|
||||
}
|
||||
|
||||
// Returns an iterator following the last key-value pair of the object.
|
||||
@ -74,8 +75,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
|
||||
ARDUINOJSON_DEPRECATED("use obj[key].is<T>() instead")
|
||||
bool containsKey(const TString& key) const {
|
||||
return detail::ObjectData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
return detail::VariantData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj["key"].is<T>() instead
|
||||
@ -83,8 +84,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
template <typename TChar>
|
||||
ARDUINOJSON_DEPRECATED("use obj[\"key\"].is<T>() instead")
|
||||
bool containsKey(TChar* key) const {
|
||||
return detail::ObjectData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
return detail::VariantData::getMember(data_, detail::adaptString(key),
|
||||
resources_) != 0;
|
||||
}
|
||||
|
||||
// DEPRECATED: use obj[key].is<T>() instead
|
||||
@ -101,7 +102,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
template <typename TString,
|
||||
detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
|
||||
JsonVariantConst operator[](const TString& key) const {
|
||||
return JsonVariantConst(detail::ObjectData::getMember(
|
||||
return JsonVariantConst(detail::VariantData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
resources_);
|
||||
}
|
||||
@ -113,7 +114,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
!detail::is_const<TChar>::value,
|
||||
int> = 0>
|
||||
JsonVariantConst operator[](TChar* key) const {
|
||||
return JsonVariantConst(detail::ObjectData::getMember(
|
||||
return JsonVariantConst(detail::VariantData::getMember(
|
||||
data_, detail::adaptString(key), resources_),
|
||||
resources_);
|
||||
}
|
||||
@ -137,10 +138,10 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
|
||||
|
||||
private:
|
||||
const detail::VariantData* getData() const {
|
||||
return collectionToVariant(data_);
|
||||
return data_;
|
||||
}
|
||||
|
||||
const detail::ObjectData* data_;
|
||||
const detail::VariantData* data_;
|
||||
const detail::ResourceManager* resources_;
|
||||
};
|
||||
|
||||
|
@ -86,7 +86,7 @@ inline VariantData* ObjectData::addPair(VariantData** value,
|
||||
|
||||
// Returns the size (in bytes) of an object with n members.
|
||||
constexpr size_t sizeofObject(size_t n) {
|
||||
return 2 * n * ResourceManager::slotSize;
|
||||
return 2 * n * sizeof(VariantData);
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -329,9 +329,7 @@ struct Converter<JsonArrayConst> : private detail::VariantAttorney {
|
||||
}
|
||||
|
||||
static JsonArrayConst fromJson(JsonVariantConst src) {
|
||||
auto data = getData(src);
|
||||
auto array = data ? data->asArray() : nullptr;
|
||||
return JsonArrayConst(array, getResourceManager(src));
|
||||
return JsonArrayConst(getData(src), getResourceManager(src));
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariantConst src) {
|
||||
@ -350,9 +348,7 @@ struct Converter<JsonArray> : private detail::VariantAttorney {
|
||||
}
|
||||
|
||||
static JsonArray fromJson(JsonVariant src) {
|
||||
auto data = getData(src);
|
||||
auto resources = getResourceManager(src);
|
||||
return JsonArray(data != 0 ? data->asArray() : 0, resources);
|
||||
return JsonArray(getData(src), getResourceManager(src));
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariant src) {
|
||||
@ -371,9 +367,7 @@ struct Converter<JsonObjectConst> : private detail::VariantAttorney {
|
||||
}
|
||||
|
||||
static JsonObjectConst fromJson(JsonVariantConst src) {
|
||||
auto data = getData(src);
|
||||
auto object = data != 0 ? data->asObject() : nullptr;
|
||||
return JsonObjectConst(object, getResourceManager(src));
|
||||
return JsonObjectConst(getData(src), getResourceManager(src));
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariantConst src) {
|
||||
@ -392,9 +386,7 @@ struct Converter<JsonObject> : private detail::VariantAttorney {
|
||||
}
|
||||
|
||||
static JsonObject fromJson(JsonVariant src) {
|
||||
auto data = getData(src);
|
||||
auto resources = getResourceManager(src);
|
||||
return JsonObject(data != 0 ? data->asObject() : 0, resources);
|
||||
return JsonObject(getData(src), getResourceManager(src));
|
||||
}
|
||||
|
||||
static bool checkJson(JsonVariant src) {
|
||||
|
@ -30,11 +30,13 @@ class VisitorAdapter {
|
||||
: visitor_(&visitor), resources_(resources) {}
|
||||
|
||||
result_type visit(const ArrayData& value) {
|
||||
return visitor_->visit(JsonArrayConst(&value, resources_));
|
||||
return visitor_->visit(
|
||||
JsonArrayConst(collectionToVariant(&value), resources_));
|
||||
}
|
||||
|
||||
result_type visit(const ObjectData& value) {
|
||||
return visitor_->visit(JsonObjectConst(&value, resources_));
|
||||
return visitor_->visit(
|
||||
JsonObjectConst(collectionToVariant(&value), resources_));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -16,8 +16,8 @@ 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
|
||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||
EightByteBit = 0x10, // 0001 0000
|
||||
#endif
|
||||
CollectionMask = 0x60,
|
||||
};
|
||||
@ -64,8 +64,8 @@ union VariantContent {
|
||||
char asTinyString[tinyStringMaxLength + 1];
|
||||
};
|
||||
|
||||
#if ARDUINOJSON_USE_EXTENSIONS
|
||||
union VariantExtension {
|
||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||
union EightByteValue {
|
||||
# if ARDUINOJSON_USE_LONG_LONG
|
||||
uint64_t asUint64;
|
||||
int64_t asInt64;
|
||||
@ -74,6 +74,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_8_BYTE_POOL
|
||||
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_8_BYTE_POOL
|
||||
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;
|
||||
@ -182,6 +182,14 @@ class VariantData {
|
||||
return const_cast<VariantData*>(this)->asArray();
|
||||
}
|
||||
|
||||
static ArrayData* asArray(VariantData* var) {
|
||||
return var ? var->asArray() : 0;
|
||||
}
|
||||
|
||||
static const ArrayData* asArray(const VariantData* var) {
|
||||
return var ? var->asArray() : 0;
|
||||
}
|
||||
|
||||
CollectionData* asCollection() {
|
||||
return isCollection() ? &content_.asCollection : 0;
|
||||
}
|
||||
@ -193,8 +201,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_8_BYTE_POOL
|
||||
auto eightByteValue = getEightByte(resources);
|
||||
#else
|
||||
(void)resources; // silence warning
|
||||
#endif
|
||||
@ -208,9 +216,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 +233,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 +246,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_8_BYTE_POOL
|
||||
auto eightByteValue = getEightByte(resources);
|
||||
#else
|
||||
(void)resources; // silence warning
|
||||
#endif
|
||||
@ -253,9 +261,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 +278,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;
|
||||
@ -288,6 +296,14 @@ class VariantData {
|
||||
return const_cast<VariantData*>(this)->asObject();
|
||||
}
|
||||
|
||||
static ObjectData* asObject(VariantData* var) {
|
||||
return var ? var->asObject() : 0;
|
||||
}
|
||||
|
||||
static const ObjectData* asObject(const VariantData* var) {
|
||||
return var ? var->asObject() : 0;
|
||||
}
|
||||
|
||||
JsonString asRawString() const {
|
||||
switch (type_) {
|
||||
case VariantType::RawString:
|
||||
@ -314,8 +330,8 @@ class VariantData {
|
||||
}
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_USE_EXTENSIONS
|
||||
const VariantExtension* getExtension(const ResourceManager* resources) const;
|
||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||
const EightByteValue* getEightByte(const ResourceManager* resources) const;
|
||||
#endif
|
||||
|
||||
VariantData* getElement(size_t index,
|
||||
@ -378,7 +394,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 +407,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:
|
||||
@ -568,11 +584,12 @@ class VariantData {
|
||||
return content_.asArray;
|
||||
}
|
||||
|
||||
static ArrayData* toArray(VariantData* var, ResourceManager* resources) {
|
||||
static VariantData* toArray(VariantData* var, ResourceManager* resources) {
|
||||
if (!var)
|
||||
return 0;
|
||||
var->clear(resources);
|
||||
return &var->toArray();
|
||||
var->toArray();
|
||||
return var;
|
||||
}
|
||||
|
||||
ObjectData& toObject() {
|
||||
@ -582,11 +599,12 @@ class VariantData {
|
||||
return content_.asObject;
|
||||
}
|
||||
|
||||
static ObjectData* toObject(VariantData* var, ResourceManager* resources) {
|
||||
static VariantData* toObject(VariantData* var, ResourceManager* resources) {
|
||||
if (!var)
|
||||
return 0;
|
||||
var->clear(resources);
|
||||
return &var->toObject();
|
||||
var->toObject();
|
||||
return var;
|
||||
}
|
||||
|
||||
VariantType type() const {
|
||||
|
@ -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_8_BYTE_POOL
|
||||
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_8_BYTE_POOL
|
||||
inline const EightByteValue* VariantData::getEightByte(
|
||||
const ResourceManager* resources) const {
|
||||
return type_ & VariantTypeBits::ExtensionBit
|
||||
? resources->getExtension(content_.asSlotId)
|
||||
: nullptr;
|
||||
return type_ & VariantTypeBits::EightByteBit
|
||||
? resources->getEightByte(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