mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-28 09:47:31 +02:00
Make MemoryPool
generic
This commit is contained in:
@ -265,12 +265,14 @@ class TimebombAllocator : public ArduinoJson::Allocator {
|
||||
} // namespace
|
||||
|
||||
inline size_t sizeofPoolList(size_t n = ARDUINOJSON_INITIAL_POOL_COUNT) {
|
||||
return sizeof(ArduinoJson::detail::MemoryPool) * n;
|
||||
using namespace ArduinoJson::detail;
|
||||
return sizeof(MemoryPool<VariantData>) * n;
|
||||
}
|
||||
|
||||
inline size_t sizeofPool(
|
||||
ArduinoJson::detail::SlotCount n = ARDUINOJSON_POOL_CAPACITY) {
|
||||
return ArduinoJson::detail::MemoryPool::slotsToBytes(n);
|
||||
using namespace ArduinoJson::detail;
|
||||
return MemoryPool<VariantData>::slotsToBytes(n);
|
||||
}
|
||||
|
||||
inline size_t sizeofStringBuffer(size_t iteration = 1) {
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/MemoryPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/StringBuilder.hpp>
|
||||
#include <catch.hpp>
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/MemoryPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/MemoryPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <catch.hpp>
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/MemoryPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/MemoryPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
@ -3,7 +3,6 @@
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Memory/MemoryPoolImpl.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/ResourceManagerImpl.hpp>
|
||||
#include <catch.hpp>
|
||||
|
@ -36,13 +36,13 @@
|
||||
#include "ArduinoJson/Array/ElementProxy.hpp"
|
||||
#include "ArduinoJson/Array/Utilities.hpp"
|
||||
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
||||
#include "ArduinoJson/Memory/MemoryPoolImpl.hpp"
|
||||
#include "ArduinoJson/Memory/ResourceManagerImpl.hpp"
|
||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
||||
#include "ArduinoJson/Variant/JsonVariantCopier.hpp"
|
||||
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
||||
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
||||
#include "ArduinoJson/Variant/VariantRefBaseImpl.hpp"
|
||||
|
||||
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class VariantData;
|
||||
class ResourceManager;
|
||||
|
||||
class CollectionIterator {
|
||||
friend class CollectionData;
|
||||
@ -78,9 +79,7 @@ class CollectionData {
|
||||
|
||||
using iterator = CollectionIterator;
|
||||
|
||||
iterator createIterator(const ResourceManager* resources) const {
|
||||
return iterator(resources->getVariant(head_), head_);
|
||||
}
|
||||
iterator createIterator(const ResourceManager* resources) const;
|
||||
|
||||
size_t size(const ResourceManager*) const;
|
||||
size_t nesting(const ResourceManager*) const;
|
||||
@ -98,15 +97,17 @@ class CollectionData {
|
||||
}
|
||||
|
||||
protected:
|
||||
void appendOne(VariantWithId slot, const ResourceManager* resources);
|
||||
void appendPair(VariantWithId key, VariantWithId value,
|
||||
void appendOne(SlotWithId<VariantData> slot,
|
||||
const ResourceManager* resources);
|
||||
void appendPair(SlotWithId<VariantData> key, SlotWithId<VariantData> value,
|
||||
const ResourceManager* resources);
|
||||
|
||||
void removeOne(iterator it, ResourceManager* resources);
|
||||
void removePair(iterator it, ResourceManager* resources);
|
||||
|
||||
private:
|
||||
VariantWithId getPreviousSlot(VariantData*, const ResourceManager*) const;
|
||||
SlotWithId<VariantData> getPreviousSlot(VariantData*,
|
||||
const ResourceManager*) const;
|
||||
};
|
||||
|
||||
inline const VariantData* collectionToVariant(
|
||||
|
@ -25,7 +25,12 @@ inline void CollectionIterator::next(const ResourceManager* resources) {
|
||||
nextId_ = slot_->next();
|
||||
}
|
||||
|
||||
inline void CollectionData::appendOne(VariantWithId slot,
|
||||
inline CollectionData::iterator CollectionData::createIterator(
|
||||
const ResourceManager* resources) const {
|
||||
return iterator(resources->getVariant(head_), head_);
|
||||
}
|
||||
|
||||
inline void CollectionData::appendOne(SlotWithId<VariantData> slot,
|
||||
const ResourceManager* resources) {
|
||||
if (tail_ != NULL_SLOT) {
|
||||
auto tail = resources->getVariant(tail_);
|
||||
@ -37,7 +42,8 @@ inline void CollectionData::appendOne(VariantWithId slot,
|
||||
}
|
||||
}
|
||||
|
||||
inline void CollectionData::appendPair(VariantWithId key, VariantWithId value,
|
||||
inline void CollectionData::appendPair(SlotWithId<VariantData> key,
|
||||
SlotWithId<VariantData> value,
|
||||
const ResourceManager* resources) {
|
||||
key->setNext(value.id());
|
||||
|
||||
@ -57,22 +63,22 @@ inline void CollectionData::clear(ResourceManager* resources) {
|
||||
auto currId = next;
|
||||
auto slot = resources->getVariant(next);
|
||||
next = slot->next();
|
||||
resources->freeVariant(VariantWithId(slot, currId));
|
||||
resources->freeVariant(SlotWithId<VariantData>(slot, currId));
|
||||
}
|
||||
|
||||
head_ = NULL_SLOT;
|
||||
tail_ = NULL_SLOT;
|
||||
}
|
||||
|
||||
inline VariantWithId CollectionData::getPreviousSlot(
|
||||
inline SlotWithId<VariantData> CollectionData::getPreviousSlot(
|
||||
VariantData* target, const ResourceManager* resources) const {
|
||||
auto prev = VariantWithId();
|
||||
auto prev = SlotWithId<VariantData>();
|
||||
auto currentId = head_;
|
||||
while (currentId != NULL_SLOT) {
|
||||
auto currentSlot = resources->getVariant(currentId);
|
||||
if (currentSlot == target)
|
||||
break;
|
||||
prev = VariantWithId(currentSlot, currentId);
|
||||
prev = SlotWithId<VariantData>(currentSlot, currentId);
|
||||
currentId = currentSlot->next();
|
||||
}
|
||||
return prev;
|
||||
|
@ -10,15 +10,15 @@
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class VariantData;
|
||||
using SlotId = uint_t<ARDUINOJSON_SLOT_ID_SIZE * 8>;
|
||||
using SlotCount = SlotId;
|
||||
const SlotId NULL_SLOT = SlotId(-1);
|
||||
|
||||
template <typename T>
|
||||
class SlotWithId {
|
||||
public:
|
||||
SlotWithId() : slot_(nullptr), id_(NULL_SLOT) {}
|
||||
SlotWithId(VariantData* slot, SlotId id) : slot_(slot), id_(id) {
|
||||
SlotWithId(T* slot, SlotId id) : slot_(slot), id_(id) {
|
||||
ARDUINOJSON_ASSERT((slot == nullptr) == (id == NULL_SLOT));
|
||||
}
|
||||
|
||||
@ -30,38 +30,81 @@ class SlotWithId {
|
||||
return id_;
|
||||
}
|
||||
|
||||
VariantData* ptr() const {
|
||||
T* ptr() const {
|
||||
return slot_;
|
||||
}
|
||||
|
||||
VariantData* operator->() {
|
||||
T* operator->() const {
|
||||
ARDUINOJSON_ASSERT(slot_ != nullptr);
|
||||
return slot_;
|
||||
}
|
||||
|
||||
private:
|
||||
VariantData* slot_;
|
||||
T* slot_;
|
||||
SlotId id_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MemoryPool {
|
||||
public:
|
||||
void create(SlotCount cap, Allocator* allocator);
|
||||
void destroy(Allocator* allocator);
|
||||
void create(SlotCount cap, Allocator* allocator) {
|
||||
ARDUINOJSON_ASSERT(cap > 0);
|
||||
slots_ = reinterpret_cast<T*>(allocator->allocate(slotsToBytes(cap)));
|
||||
capacity_ = slots_ ? cap : 0;
|
||||
usage_ = 0;
|
||||
}
|
||||
|
||||
SlotWithId allocSlot();
|
||||
VariantData* getSlot(SlotId id) const;
|
||||
void clear();
|
||||
void shrinkToFit(Allocator*);
|
||||
SlotCount usage() const;
|
||||
void destroy(Allocator* allocator) {
|
||||
if (slots_)
|
||||
allocator->deallocate(slots_);
|
||||
slots_ = nullptr;
|
||||
capacity_ = 0;
|
||||
usage_ = 0;
|
||||
}
|
||||
|
||||
static SlotCount bytesToSlots(size_t);
|
||||
static size_t slotsToBytes(SlotCount);
|
||||
SlotWithId<T> allocSlot() {
|
||||
if (!slots_)
|
||||
return {};
|
||||
if (usage_ >= capacity_)
|
||||
return {};
|
||||
auto index = usage_++;
|
||||
return {slots_ + index, SlotId(index)};
|
||||
}
|
||||
|
||||
T* getSlot(SlotId id) const {
|
||||
ARDUINOJSON_ASSERT(id < usage_);
|
||||
return slots_ + id;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
usage_ = 0;
|
||||
}
|
||||
|
||||
void shrinkToFit(Allocator* allocator) {
|
||||
auto newSlots = reinterpret_cast<T*>(
|
||||
allocator->reallocate(slots_, slotsToBytes(usage_)));
|
||||
if (newSlots) {
|
||||
slots_ = newSlots;
|
||||
capacity_ = usage_;
|
||||
}
|
||||
}
|
||||
|
||||
SlotCount usage() const {
|
||||
return usage_;
|
||||
}
|
||||
|
||||
static SlotCount bytesToSlots(size_t n) {
|
||||
return static_cast<SlotCount>(n / sizeof(T));
|
||||
}
|
||||
|
||||
static size_t slotsToBytes(SlotCount n) {
|
||||
return n * sizeof(T);
|
||||
}
|
||||
|
||||
private:
|
||||
SlotCount capacity_;
|
||||
SlotCount usage_;
|
||||
VariantData* slots_;
|
||||
T* slots_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -1,81 +0,0 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
inline void MemoryPool::create(SlotCount cap, Allocator* allocator) {
|
||||
ARDUINOJSON_ASSERT(cap > 0);
|
||||
slots_ =
|
||||
reinterpret_cast<VariantData*>(allocator->allocate(slotsToBytes(cap)));
|
||||
capacity_ = slots_ ? cap : 0;
|
||||
usage_ = 0;
|
||||
}
|
||||
|
||||
inline void MemoryPool::destroy(Allocator* allocator) {
|
||||
if (slots_)
|
||||
allocator->deallocate(slots_);
|
||||
slots_ = nullptr;
|
||||
capacity_ = 0;
|
||||
usage_ = 0;
|
||||
}
|
||||
|
||||
inline void MemoryPool::shrinkToFit(Allocator* allocator) {
|
||||
auto newSlots = reinterpret_cast<VariantData*>(
|
||||
allocator->reallocate(slots_, slotsToBytes(usage_)));
|
||||
if (newSlots) {
|
||||
slots_ = newSlots;
|
||||
capacity_ = usage_;
|
||||
}
|
||||
}
|
||||
|
||||
inline SlotWithId MemoryPool::allocSlot() {
|
||||
if (!slots_)
|
||||
return {};
|
||||
if (usage_ >= capacity_)
|
||||
return {};
|
||||
auto index = usage_++;
|
||||
auto slot = &slots_[index];
|
||||
return {slot, SlotId(index)};
|
||||
}
|
||||
|
||||
inline VariantData* MemoryPool::getSlot(SlotId id) const {
|
||||
ARDUINOJSON_ASSERT(id < usage_);
|
||||
return &slots_[id];
|
||||
}
|
||||
|
||||
inline SlotCount MemoryPool::usage() const {
|
||||
return usage_;
|
||||
}
|
||||
|
||||
inline void MemoryPool::clear() {
|
||||
usage_ = 0;
|
||||
}
|
||||
|
||||
inline SlotCount MemoryPool::bytesToSlots(size_t n) {
|
||||
return static_cast<SlotCount>(n / sizeof(VariantData));
|
||||
}
|
||||
|
||||
inline size_t MemoryPool::slotsToBytes(SlotCount n) {
|
||||
return n * sizeof(VariantData);
|
||||
}
|
||||
|
||||
inline SlotWithId MemoryPoolList::allocFromFreeList() {
|
||||
ARDUINOJSON_ASSERT(freeList_ != NULL_SLOT);
|
||||
auto id = freeList_;
|
||||
auto slot = getSlot(freeList_);
|
||||
freeList_ = reinterpret_cast<FreeSlot*>(slot)->next;
|
||||
return {slot, id};
|
||||
}
|
||||
|
||||
inline void MemoryPoolList::freeSlot(SlotWithId slot) {
|
||||
reinterpret_cast<FreeSlot*>(slot.ptr())->next = freeList_;
|
||||
freeList_ = slot.id();
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
@ -14,12 +14,17 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
using PoolCount = SlotId;
|
||||
|
||||
template <typename T>
|
||||
class MemoryPoolList {
|
||||
struct FreeSlot {
|
||||
SlotId next;
|
||||
};
|
||||
|
||||
static_assert(sizeof(FreeSlot) <= sizeof(T), "T is too small");
|
||||
|
||||
public:
|
||||
using Pool = MemoryPool<T>;
|
||||
|
||||
MemoryPoolList() = default;
|
||||
|
||||
~MemoryPoolList() {
|
||||
@ -74,7 +79,7 @@ class MemoryPoolList {
|
||||
return *this;
|
||||
}
|
||||
|
||||
SlotWithId allocSlot(Allocator* allocator) {
|
||||
SlotWithId<T> allocSlot(Allocator* allocator) {
|
||||
// try to allocate from free list
|
||||
if (freeList_ != NULL_SLOT) {
|
||||
return allocFromFreeList();
|
||||
@ -95,9 +100,12 @@ class MemoryPoolList {
|
||||
return allocFromLastPool();
|
||||
}
|
||||
|
||||
void freeSlot(SlotWithId slot);
|
||||
void freeSlot(SlotWithId<T> slot) {
|
||||
reinterpret_cast<FreeSlot*>(slot.ptr())->next = freeList_;
|
||||
freeList_ = slot.id();
|
||||
}
|
||||
|
||||
VariantData* getSlot(SlotId id) const {
|
||||
T* getSlot(SlotId id) const {
|
||||
if (id == NULL_SLOT)
|
||||
return nullptr;
|
||||
auto poolIndex = SlotId(id / ARDUINOJSON_POOL_CAPACITY);
|
||||
@ -125,21 +133,31 @@ class MemoryPoolList {
|
||||
return total;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return Pool::slotsToBytes(usage());
|
||||
}
|
||||
|
||||
void shrinkToFit(Allocator* allocator) {
|
||||
if (count_ > 0)
|
||||
pools_[count_ - 1].shrinkToFit(allocator);
|
||||
if (pools_ != preallocatedPools_ && count_ != capacity_) {
|
||||
pools_ = static_cast<MemoryPool*>(
|
||||
allocator->reallocate(pools_, count_ * sizeof(MemoryPool)));
|
||||
pools_ = static_cast<Pool*>(
|
||||
allocator->reallocate(pools_, count_ * sizeof(Pool)));
|
||||
ARDUINOJSON_ASSERT(pools_ != nullptr); // realloc to smaller can't fail
|
||||
capacity_ = count_;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
SlotWithId allocFromFreeList();
|
||||
SlotWithId<T> allocFromFreeList() {
|
||||
ARDUINOJSON_ASSERT(freeList_ != NULL_SLOT);
|
||||
auto id = freeList_;
|
||||
auto slot = getSlot(freeList_);
|
||||
freeList_ = reinterpret_cast<FreeSlot*>(slot)->next;
|
||||
return {slot, id};
|
||||
}
|
||||
|
||||
SlotWithId allocFromLastPool() {
|
||||
SlotWithId<T> allocFromLastPool() {
|
||||
ARDUINOJSON_ASSERT(count_ > 0);
|
||||
auto poolIndex = SlotId(count_ - 1);
|
||||
auto slot = pools_[poolIndex].allocSlot();
|
||||
@ -149,7 +167,7 @@ class MemoryPoolList {
|
||||
SlotId(poolIndex * ARDUINOJSON_POOL_CAPACITY + slot.id())};
|
||||
}
|
||||
|
||||
MemoryPool* addPool(Allocator* allocator) {
|
||||
Pool* addPool(Allocator* allocator) {
|
||||
if (count_ == capacity_ && !increaseCapacity(allocator))
|
||||
return nullptr;
|
||||
auto pool = &pools_[count_++];
|
||||
@ -167,24 +185,23 @@ class MemoryPoolList {
|
||||
auto newCapacity = PoolCount(capacity_ * 2);
|
||||
|
||||
if (pools_ == preallocatedPools_) {
|
||||
newPools = allocator->allocate(newCapacity * sizeof(MemoryPool));
|
||||
newPools = allocator->allocate(newCapacity * sizeof(Pool));
|
||||
if (!newPools)
|
||||
return false;
|
||||
memcpy(newPools, preallocatedPools_, sizeof(preallocatedPools_));
|
||||
} else {
|
||||
newPools =
|
||||
allocator->reallocate(pools_, newCapacity * sizeof(MemoryPool));
|
||||
newPools = allocator->reallocate(pools_, newCapacity * sizeof(Pool));
|
||||
if (!newPools)
|
||||
return false;
|
||||
}
|
||||
|
||||
pools_ = static_cast<MemoryPool*>(newPools);
|
||||
pools_ = static_cast<Pool*>(newPools);
|
||||
capacity_ = newCapacity;
|
||||
return true;
|
||||
}
|
||||
|
||||
MemoryPool preallocatedPools_[ARDUINOJSON_INITIAL_POOL_COUNT];
|
||||
MemoryPool* pools_ = preallocatedPools_;
|
||||
Pool preallocatedPools_[ARDUINOJSON_INITIAL_POOL_COUNT];
|
||||
Pool* pools_ = preallocatedPools_;
|
||||
PoolCount count_ = 0;
|
||||
PoolCount capacity_ = ARDUINOJSON_INITIAL_POOL_COUNT;
|
||||
SlotId freeList_ = NULL_SLOT;
|
||||
|
@ -10,10 +10,10 @@
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/utility.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class MemoryPool;
|
||||
class VariantData;
|
||||
class VariantWithId;
|
||||
|
||||
@ -42,16 +42,16 @@ class ResourceManager {
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return MemoryPool::slotsToBytes(variantPools_.usage()) + stringPool_.size();
|
||||
return variantPools_.size() + stringPool_.size();
|
||||
}
|
||||
|
||||
bool overflowed() const {
|
||||
return overflowed_;
|
||||
}
|
||||
|
||||
VariantWithId allocVariant();
|
||||
SlotWithId<VariantData> allocVariant();
|
||||
|
||||
void freeVariant(VariantWithId slot);
|
||||
void freeVariant(SlotWithId<VariantData> slot);
|
||||
|
||||
VariantData* getVariant(SlotId id) const;
|
||||
|
||||
@ -112,7 +112,7 @@ class ResourceManager {
|
||||
Allocator* allocator_;
|
||||
bool overflowed_;
|
||||
StringPool stringPool_;
|
||||
MemoryPoolList variantPools_;
|
||||
MemoryPoolList<VariantData> variantPools_;
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
inline VariantWithId ResourceManager::allocVariant() {
|
||||
inline SlotWithId<VariantData> ResourceManager::allocVariant() {
|
||||
auto p = variantPools_.allocSlot(allocator_);
|
||||
if (!p) {
|
||||
overflowed_ = true;
|
||||
@ -19,7 +19,7 @@ inline VariantWithId ResourceManager::allocVariant() {
|
||||
return {new (p.ptr()) VariantData, p.id()};
|
||||
}
|
||||
|
||||
inline void ResourceManager::freeVariant(VariantWithId variant) {
|
||||
inline void ResourceManager::freeVariant(SlotWithId<VariantData> variant) {
|
||||
variant->setNull(this);
|
||||
variantPools_.freeSlot(variant);
|
||||
}
|
||||
|
@ -12,8 +12,6 @@
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
class MemoryPool;
|
||||
|
||||
class StringPool {
|
||||
public:
|
||||
StringPool() = default;
|
||||
|
@ -408,14 +408,7 @@ class VariantData {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void setRawString(SerializedValue<T> value, ResourceManager* resources) {
|
||||
release(resources);
|
||||
auto dup = resources->saveString(adaptString(value.data(), value.size()));
|
||||
if (dup)
|
||||
setRawString(dup);
|
||||
else
|
||||
setNull();
|
||||
}
|
||||
void setRawString(SerializedValue<T> value, ResourceManager* resources);
|
||||
|
||||
template <typename T>
|
||||
static void setRawString(VariantData* var, SerializedValue<T> value,
|
||||
@ -426,25 +419,7 @@ class VariantData {
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
bool setString(TAdaptedString value, ResourceManager* resources) {
|
||||
setNull(resources);
|
||||
|
||||
if (value.isNull())
|
||||
return false;
|
||||
|
||||
if (value.isLinked()) {
|
||||
setLinkedString(value.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
auto dup = resources->saveString(value);
|
||||
if (dup) {
|
||||
setOwnedString(dup);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool setString(TAdaptedString value, ResourceManager* resources);
|
||||
|
||||
bool setString(StringNode* s, ResourceManager*) {
|
||||
setOwnedString(s);
|
||||
@ -524,30 +499,7 @@ class VariantData {
|
||||
}
|
||||
|
||||
private:
|
||||
void release(ResourceManager* resources) {
|
||||
if (type_ & OWNED_VALUE_BIT)
|
||||
resources->dereferenceString(content_.asOwnedString->data);
|
||||
|
||||
auto collection = asCollection();
|
||||
if (collection)
|
||||
collection->clear(resources);
|
||||
}
|
||||
};
|
||||
|
||||
class VariantWithId : public SlotWithId {
|
||||
public:
|
||||
VariantWithId() {}
|
||||
VariantWithId(VariantData* data, SlotId id)
|
||||
: SlotWithId(reinterpret_cast<VariantData*>(data), id) {}
|
||||
|
||||
VariantData* ptr() {
|
||||
return reinterpret_cast<VariantData*>(SlotWithId::ptr());
|
||||
}
|
||||
|
||||
VariantData* operator->() {
|
||||
ARDUINOJSON_ASSERT(ptr() != nullptr);
|
||||
return ptr();
|
||||
}
|
||||
void release(ResourceManager* resources);
|
||||
};
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||
|
54
src/ArduinoJson/Variant/VariantImpl.hpp
Normal file
54
src/ArduinoJson/Variant/VariantImpl.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2024, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||
|
||||
template <typename T>
|
||||
inline void VariantData::setRawString(SerializedValue<T> value,
|
||||
ResourceManager* resources) {
|
||||
release(resources);
|
||||
auto dup = resources->saveString(adaptString(value.data(), value.size()));
|
||||
if (dup)
|
||||
setRawString(dup);
|
||||
else
|
||||
setNull();
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline bool VariantData::setString(TAdaptedString value,
|
||||
ResourceManager* resources) {
|
||||
setNull(resources);
|
||||
|
||||
if (value.isNull())
|
||||
return false;
|
||||
|
||||
if (value.isLinked()) {
|
||||
setLinkedString(value.data());
|
||||
return true;
|
||||
}
|
||||
|
||||
auto dup = resources->saveString(value);
|
||||
if (dup) {
|
||||
setOwnedString(dup);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void VariantData::release(ResourceManager* resources) {
|
||||
if (type_ & OWNED_VALUE_BIT)
|
||||
resources->dereferenceString(content_.asOwnedString->data);
|
||||
|
||||
auto collection = asCollection();
|
||||
if (collection)
|
||||
collection->clear(resources);
|
||||
}
|
||||
|
||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
Reference in New Issue
Block a user