Rename MemoryPool to ResourceManager

This commit is contained in:
Benoit Blanchon
2023-06-17 16:10:56 +02:00
parent 2a663db3c7
commit 4871380060
36 changed files with 473 additions and 453 deletions

View File

@ -20,7 +20,7 @@ add_subdirectory(JsonDocument)
add_subdirectory(JsonObject)
add_subdirectory(JsonSerializer)
add_subdirectory(JsonVariant)
add_subdirectory(MemoryPool)
add_subdirectory(ResourceManager)
add_subdirectory(Misc)
add_subdirectory(MixedConfiguration)
add_subdirectory(MsgPackDeserializer)

View File

@ -308,8 +308,6 @@ TEST_CASE("deserialize JSON array under memory constraints") {
deserializeJson(doc, " [ \"1234567\" ] ");
REQUIRE(sizeofArray(1) + sizeofString(7) == doc.memoryUsage());
// note: we use a string of 8 bytes to be sure that the MemoryPool
// will not insert bytes to enforce alignement
}
SECTION("Should clear the JsonArray") {

View File

@ -1,51 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Variant/VariantSlot.hpp>
#include <catch.hpp>
#include "Allocators.hpp"
using namespace ArduinoJson::detail;
TEST_CASE("new (pool) VariantSlot()") {
SECTION("Returns different pointer") {
MemoryPool pool(4096);
VariantSlot* s1 = new (&pool) VariantSlot();
REQUIRE(s1 != 0);
VariantSlot* s2 = new (&pool) VariantSlot();
REQUIRE(s2 != 0);
REQUIRE(s1 != s2);
}
SECTION("Returns aligned pointers") {
MemoryPool pool(4096);
REQUIRE(isAligned(new (&pool) VariantSlot()));
REQUIRE(isAligned(new (&pool) VariantSlot()));
}
SECTION("Returns zero if capacity is 0") {
MemoryPool pool(0);
REQUIRE(new (&pool) VariantSlot() == 0);
}
SECTION("Returns zero if buffer is null") {
MemoryPool pool(4096, FailingAllocator::instance());
REQUIRE(new (&pool) VariantSlot() == 0);
}
SECTION("Returns zero if capacity is insufficient") {
MemoryPool pool(sizeof(VariantSlot));
new (&pool) VariantSlot();
REQUIRE(new (&pool) VariantSlot() == 0);
}
}

View File

@ -1,68 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Strings/StringAdapters.hpp>
#include <catch.hpp>
#include "Allocators.hpp"
using namespace ArduinoJson::detail;
static StringNode* saveString(MemoryPool& pool, const char* s) {
return pool.saveString(adaptString(s));
}
static StringNode* saveString(MemoryPool& pool, const char* s, size_t n) {
return pool.saveString(adaptString(s, n));
}
TEST_CASE("MemoryPool::saveString()") {
MemoryPool pool(32);
SECTION("Duplicates different strings") {
auto a = saveString(pool, "hello");
auto b = saveString(pool, "world");
REQUIRE(a->data != b->data);
REQUIRE(a->length == 5);
REQUIRE(b->length == 5);
REQUIRE(a->references == 1);
REQUIRE(b->references == 1);
REQUIRE(pool.size() == 2 * sizeofString(5));
}
SECTION("Deduplicates identical strings") {
auto a = saveString(pool, "hello");
auto b = saveString(pool, "hello");
REQUIRE(a == b);
REQUIRE(a->length == 5);
REQUIRE(a->references == 2);
REQUIRE(pool.size() == sizeofString(5));
}
SECTION("Deduplicates identical strings that contain NUL") {
auto a = saveString(pool, "hello\0world", 11);
auto b = saveString(pool, "hello\0world", 11);
REQUIRE(a == b);
REQUIRE(a->length == 11);
REQUIRE(a->references == 2);
REQUIRE(pool.size() == sizeofString(11));
}
SECTION("Don't stop on first NUL") {
auto a = saveString(pool, "hello");
auto b = saveString(pool, "hello\0world", 11);
REQUIRE(a != b);
REQUIRE(a->length == 5);
REQUIRE(b->length == 11);
REQUIRE(a->references == 1);
REQUIRE(b->references == 1);
REQUIRE(pool.size() == sizeofString(5) + sizeofString(11));
}
SECTION("Returns NULL when allocation fails") {
MemoryPool pool2(32, FailingAllocator::instance());
REQUIRE(saveString(pool2, "a") == nullptr);
}
}

View File

@ -1,35 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Variant/VariantSlot.hpp>
#include <catch.hpp>
using namespace ArduinoJson::detail;
TEST_CASE("MemoryPool::capacity()") {
const size_t capacity = 64;
MemoryPool pool(capacity);
REQUIRE(capacity == pool.capacity());
}
TEST_CASE("MemoryPool::size()") {
MemoryPool pool(4096);
SECTION("Initial size is 0") {
REQUIRE(0 == pool.size());
}
SECTION("Doesn't grow when memory pool is full") {
const size_t variantCount = pool.capacity() / sizeof(VariantSlot);
for (size_t i = 0; i < variantCount; i++)
new (&pool) VariantSlot();
size_t size = pool.size();
new (&pool) VariantSlot();
REQUIRE(size == pool.size());
}
}

View File

@ -10,8 +10,8 @@
using namespace ArduinoJson::detail;
static void testCodepoint(uint32_t codepoint, std::string expected) {
MemoryPool pool(4096);
StringBuilder str(&pool);
ResourceManager resources(4096);
StringBuilder str(&resources);
str.startString();
CAPTURE(codepoint);

View File

@ -2,7 +2,7 @@
# Copyright © 2014-2023, Benoit BLANCHON
# MIT License
add_executable(MemoryPoolTests
add_executable(ResourceManagerTests
allocVariant.cpp
clear.cpp
saveString.cpp
@ -10,9 +10,9 @@ add_executable(MemoryPoolTests
StringBuilder.cpp
)
add_test(MemoryPool MemoryPoolTests)
add_test(ResourceManager ResourceManagerTests)
set_tests_properties(MemoryPool
set_tests_properties(ResourceManager
PROPERTIES
LABELS "Catch"
)

View File

@ -12,16 +12,16 @@ using namespace ArduinoJson::detail;
TEST_CASE("StringBuilder") {
ControllableAllocator controllableAllocator;
SpyingAllocator spyingAllocator(&controllableAllocator);
MemoryPool pool(0, &spyingAllocator);
ResourceManager resources(0, &spyingAllocator);
SECTION("Empty string") {
StringBuilder str(&pool);
StringBuilder str(&resources);
str.startString();
str.save();
REQUIRE(pool.size() == sizeofString(0));
REQUIRE(pool.overflowed() == false);
REQUIRE(resources.size() == sizeofString(0));
REQUIRE(resources.overflowed() == false);
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
<< AllocatorLog::Reallocate(sizeofString(31),
@ -29,20 +29,20 @@ TEST_CASE("StringBuilder") {
}
SECTION("Short string fits in first allocation") {
StringBuilder str(&pool);
StringBuilder str(&resources);
str.startString();
str.append("hello");
REQUIRE(str.isValid() == true);
REQUIRE(str.str() == "hello");
REQUIRE(pool.overflowed() == false);
REQUIRE(resources.overflowed() == false);
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31)));
}
SECTION("Long string needs reallocation") {
StringBuilder str(&pool);
StringBuilder str(&resources);
str.startString();
str.append(
@ -53,7 +53,7 @@ TEST_CASE("StringBuilder") {
REQUIRE(str.str() ==
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
"eiusmod tempor incididunt ut labore et dolore magna aliqua.");
REQUIRE(pool.overflowed() == false);
REQUIRE(resources.overflowed() == false);
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::Allocate(sizeofString(31))
<< AllocatorLog::Reallocate(sizeofString(31),
@ -63,7 +63,7 @@ TEST_CASE("StringBuilder") {
}
SECTION("Realloc fails") {
StringBuilder str(&pool);
StringBuilder str(&resources);
str.startString();
controllableAllocator.disable();
@ -77,62 +77,62 @@ TEST_CASE("StringBuilder") {
sizeofString(63))
<< AllocatorLog::Deallocate(sizeofString(31)));
REQUIRE(str.isValid() == false);
REQUIRE(pool.overflowed() == true);
REQUIRE(resources.overflowed() == true);
}
SECTION("Initial allocation fails") {
StringBuilder str(&pool);
StringBuilder str(&resources);
controllableAllocator.disable();
str.startString();
REQUIRE(str.isValid() == false);
REQUIRE(pool.overflowed() == true);
REQUIRE(resources.overflowed() == true);
REQUIRE(spyingAllocator.log() ==
AllocatorLog() << AllocatorLog::AllocateFail(sizeofString(31)));
}
}
static StringNode* addStringToPool(MemoryPool& pool, const char* s) {
StringBuilder str(&pool);
static StringNode* addStringToPool(ResourceManager& resources, const char* s) {
StringBuilder str(&resources);
str.startString();
str.append(s);
return str.save();
}
TEST_CASE("StringBuilder::save() deduplicates strings") {
MemoryPool pool(4096);
ResourceManager resources(4096);
SECTION("Basic") {
auto s1 = addStringToPool(pool, "hello");
auto s2 = addStringToPool(pool, "world");
auto s3 = addStringToPool(pool, "hello");
auto s1 = addStringToPool(resources, "hello");
auto s2 = addStringToPool(resources, "world");
auto s3 = addStringToPool(resources, "hello");
REQUIRE(s1 == s3);
REQUIRE(s2 != s3);
REQUIRE(s1->references == 2);
REQUIRE(s2->references == 1);
REQUIRE(s3->references == 2);
REQUIRE(pool.size() == 2 * sizeofString(5));
REQUIRE(resources.size() == 2 * sizeofString(5));
}
SECTION("Requires terminator") {
auto s1 = addStringToPool(pool, "hello world");
auto s2 = addStringToPool(pool, "hello");
auto s1 = addStringToPool(resources, "hello world");
auto s2 = addStringToPool(resources, "hello");
REQUIRE(s2 != s1);
REQUIRE(s1->references == 1);
REQUIRE(s2->references == 1);
REQUIRE(pool.size() == sizeofString(11) + sizeofString(5));
REQUIRE(resources.size() == sizeofString(11) + sizeofString(5));
}
SECTION("Don't overrun") {
auto s1 = addStringToPool(pool, "hello world");
auto s2 = addStringToPool(pool, "wor");
auto s1 = addStringToPool(resources, "hello world");
auto s2 = addStringToPool(resources, "wor");
REQUIRE(s2 != s1);
REQUIRE(s1->references == 1);
REQUIRE(s2->references == 1);
REQUIRE(pool.size() == sizeofString(11) + sizeofString(3));
REQUIRE(resources.size() == sizeofString(11) + sizeofString(3));
}
}

View File

@ -0,0 +1,51 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Variant/VariantSlot.hpp>
#include <catch.hpp>
#include "Allocators.hpp"
using namespace ArduinoJson::detail;
TEST_CASE("new (resources) VariantSlot()") {
SECTION("Returns different pointer") {
ResourceManager resources(4096);
VariantSlot* s1 = new (&resources) VariantSlot();
REQUIRE(s1 != 0);
VariantSlot* s2 = new (&resources) VariantSlot();
REQUIRE(s2 != 0);
REQUIRE(s1 != s2);
}
SECTION("Returns aligned pointers") {
ResourceManager resources(4096);
REQUIRE(isAligned(new (&resources) VariantSlot()));
REQUIRE(isAligned(new (&resources) VariantSlot()));
}
SECTION("Returns zero if capacity is 0") {
ResourceManager resources(0);
REQUIRE(new (&resources) VariantSlot() == 0);
}
SECTION("Returns zero if buffer is null") {
ResourceManager resources(4096, FailingAllocator::instance());
REQUIRE(new (&resources) VariantSlot() == 0);
}
SECTION("Returns zero if capacity is insufficient") {
ResourceManager resources(sizeof(VariantSlot));
new (&resources) VariantSlot();
REQUIRE(new (&resources) VariantSlot() == 0);
}
}

View File

@ -2,7 +2,7 @@
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Strings/StringAdapters.hpp>
#include <ArduinoJson/Variant/VariantSlot.hpp>
#include <catch.hpp>
@ -11,22 +11,22 @@ using namespace ArduinoJson::detail;
static const size_t poolCapacity = 512;
TEST_CASE("MemoryPool::clear()") {
MemoryPool pool(poolCapacity);
TEST_CASE("ResourceManager::clear()") {
ResourceManager resources(poolCapacity);
SECTION("Discards allocated variants") {
new (&pool) VariantSlot();
new (&resources) VariantSlot();
pool.clear();
REQUIRE(pool.size() == 0);
resources.clear();
REQUIRE(resources.size() == 0);
}
SECTION("Discards allocated strings") {
pool.saveString(adaptString("123456789"));
REQUIRE(pool.size() == sizeofString(9));
resources.saveString(adaptString("123456789"));
REQUIRE(resources.size() == sizeofString(9));
pool.clear();
resources.clear();
REQUIRE(pool.size() == 0);
REQUIRE(resources.size() == 0);
}
}

View File

@ -0,0 +1,69 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Strings/StringAdapters.hpp>
#include <catch.hpp>
#include "Allocators.hpp"
using namespace ArduinoJson::detail;
static StringNode* saveString(ResourceManager& resources, const char* s) {
return resources.saveString(adaptString(s));
}
static StringNode* saveString(ResourceManager& resources, const char* s,
size_t n) {
return resources.saveString(adaptString(s, n));
}
TEST_CASE("ResourceManager::saveString()") {
ResourceManager resources(32);
SECTION("Duplicates different strings") {
auto a = saveString(resources, "hello");
auto b = saveString(resources, "world");
REQUIRE(a->data != b->data);
REQUIRE(a->length == 5);
REQUIRE(b->length == 5);
REQUIRE(a->references == 1);
REQUIRE(b->references == 1);
REQUIRE(resources.size() == 2 * sizeofString(5));
}
SECTION("Deduplicates identical strings") {
auto a = saveString(resources, "hello");
auto b = saveString(resources, "hello");
REQUIRE(a == b);
REQUIRE(a->length == 5);
REQUIRE(a->references == 2);
REQUIRE(resources.size() == sizeofString(5));
}
SECTION("Deduplicates identical strings that contain NUL") {
auto a = saveString(resources, "hello\0world", 11);
auto b = saveString(resources, "hello\0world", 11);
REQUIRE(a == b);
REQUIRE(a->length == 11);
REQUIRE(a->references == 2);
REQUIRE(resources.size() == sizeofString(11));
}
SECTION("Don't stop on first NUL") {
auto a = saveString(resources, "hello");
auto b = saveString(resources, "hello\0world", 11);
REQUIRE(a != b);
REQUIRE(a->length == 5);
REQUIRE(b->length == 11);
REQUIRE(a->references == 1);
REQUIRE(b->references == 1);
REQUIRE(resources.size() == sizeofString(5) + sizeofString(11));
}
SECTION("Returns NULL when allocation fails") {
ResourceManager pool2(32, FailingAllocator::instance());
REQUIRE(saveString(pool2, "a") == nullptr);
}
}

View File

@ -0,0 +1,35 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Variant/VariantSlot.hpp>
#include <catch.hpp>
using namespace ArduinoJson::detail;
TEST_CASE("ResourceManager::capacity()") {
const size_t capacity = 64;
ResourceManager resources(capacity);
REQUIRE(capacity == resources.capacity());
}
TEST_CASE("ResourceManager::size()") {
ResourceManager resources(4096);
SECTION("Initial size is 0") {
REQUIRE(0 == resources.size());
}
SECTION("Doesn't grow when memory pool is full") {
const size_t variantCount = resources.capacity() / sizeof(VariantSlot);
for (size_t i = 0; i < variantCount; i++)
new (&resources) VariantSlot();
size_t size = resources.size();
new (&resources) VariantSlot();
REQUIRE(size == resources.size());
}
}

View File

@ -40,8 +40,8 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
}
private:
FORCE_INLINE MemoryPool* getPool() const {
return VariantAttorney::getPool(upstream_);
FORCE_INLINE ResourceManager* getResourceManager() const {
return VariantAttorney::getResourceManager(upstream_);
}
FORCE_INLINE VariantData* getData() const {
@ -49,8 +49,9 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
}
FORCE_INLINE VariantData* getOrCreateData() const {
return variantGetOrAddElement(VariantAttorney::getOrCreateData(upstream_),
index_, VariantAttorney::getPool(upstream_));
return variantGetOrAddElement(
VariantAttorney::getOrCreateData(upstream_), index_,
VariantAttorney::getResourceManager(upstream_));
}
TUpstream upstream_;

View File

@ -21,17 +21,19 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
typedef JsonArrayIterator iterator;
// Constructs an unbound reference.
FORCE_INLINE JsonArray() : data_(0), pool_(0) {}
FORCE_INLINE JsonArray() : data_(0), resources_(0) {}
// INTERNAL USE ONLY
FORCE_INLINE JsonArray(detail::MemoryPool* pool, detail::CollectionData* data)
: data_(data), pool_(pool) {}
FORCE_INLINE JsonArray(detail::ResourceManager* resources,
detail::CollectionData* data)
: data_(data), resources_(resources) {}
// Returns a JsonVariant pointing to the array.
// https://arduinojson.org/v6/api/jsonvariant/
operator JsonVariant() {
void* data = data_; // prevent warning cast-align
return JsonVariant(pool_, reinterpret_cast<detail::VariantData*>(data));
return JsonVariant(resources_,
reinterpret_cast<detail::VariantData*>(data));
}
// Returns a read-only reference to the array.
@ -44,7 +46,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsonarray/add/
JsonVariant add() const {
return JsonVariant(pool_, collectionAddElement(data_, pool_));
return JsonVariant(resources_, collectionAddElement(data_, resources_));
}
// Appends a value to the array.
@ -66,7 +68,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
FORCE_INLINE iterator begin() const {
if (!data_)
return iterator();
return iterator(pool_, data_->head());
return iterator(resources_, data_->head());
}
// Returns an iterator following the last element of the array.
@ -78,7 +80,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Copies an array.
// https://arduinojson.org/v6/api/jsonarray/set/
FORCE_INLINE bool set(JsonArrayConst src) const {
return collectionCopy(data_, src.data_, pool_);
return collectionCopy(data_, src.data_, resources_);
}
// Compares the content of two arrays.
@ -90,21 +92,21 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// ⚠️ Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsonarray/remove/
FORCE_INLINE void remove(iterator it) const {
collectionRemove(data_, it.slot_, pool_);
collectionRemove(data_, it.slot_, resources_);
}
// Removes the element at the specified index.
// ⚠️ Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsonarray/remove/
FORCE_INLINE void remove(size_t index) const {
collectionRemoveElement(data_, index, pool_);
collectionRemoveElement(data_, index, resources_);
}
// Removes all the elements of the array.
// ⚠️ Doesn't release the memory associated with the removed elements.
// https://arduinojson.org/v6/api/jsonarray/clear/
void clear() const {
collectionClear(data_, pool_);
collectionClear(data_, resources_);
}
// Gets or sets the element at the specified index.
@ -158,8 +160,8 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
}
private:
detail::MemoryPool* getPool() const {
return pool_;
detail::ResourceManager* getResourceManager() const {
return resources_;
}
detail::VariantData* getData() const {
@ -171,19 +173,19 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
}
detail::CollectionData* data_;
detail::MemoryPool* pool_;
detail::ResourceManager* resources_;
};
template <>
struct Converter<JsonArray> : private detail::VariantAttorney {
static void toJson(JsonVariantConst src, JsonVariant dst) {
variantCopyFrom(getData(dst), getData(src), getPool(dst));
variantCopyFrom(getData(dst), getData(src), getResourceManager(dst));
}
static JsonArray fromJson(JsonVariant src) {
auto data = getData(src);
auto pool = getPool(src);
return JsonArray(pool, data != 0 ? data->asArray() : 0);
auto resources = getResourceManager(src);
return JsonArray(resources, data != 0 ? data->asArray() : 0);
}
static detail::InvalidConversion<JsonVariantConst, JsonArray> fromJson(
@ -207,7 +209,8 @@ template <typename TDerived>
template <typename T>
inline typename enable_if<is_same<T, JsonArray>::value, JsonArray>::type
VariantRefBase<TDerived>::to() const {
return JsonArray(getPool(), variantToArray(getOrCreateData(), getPool()));
return JsonArray(getResourceManager(),
variantToArray(getOrCreateData(), getResourceManager()));
}
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -118,7 +118,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
template <>
struct Converter<JsonArrayConst> : private detail::VariantAttorney {
static void toJson(JsonVariantConst src, JsonVariant dst) {
variantCopyFrom(getData(dst), getData(src), getPool(dst));
variantCopyFrom(getData(dst), getData(src), getResourceManager(dst));
}
static JsonArrayConst fromJson(JsonVariantConst src) {

View File

@ -11,8 +11,8 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
class VariantPtr {
public:
VariantPtr(detail::MemoryPool* pool, detail::VariantData* data)
: variant_(pool, data) {}
VariantPtr(detail::ResourceManager* resources, detail::VariantData* data)
: variant_(resources, data) {}
JsonVariant* operator->() {
return &variant_;
@ -31,15 +31,15 @@ class JsonArrayIterator {
public:
JsonArrayIterator() : slot_(0) {}
explicit JsonArrayIterator(detail::MemoryPool* pool,
explicit JsonArrayIterator(detail::ResourceManager* resources,
detail::VariantSlot* slot)
: pool_(pool), slot_(slot) {}
: resources_(resources), slot_(slot) {}
JsonVariant operator*() const {
return JsonVariant(pool_, slot_->data());
return JsonVariant(resources_, slot_->data());
}
VariantPtr operator->() {
return VariantPtr(pool_, slot_->data());
return VariantPtr(resources_, slot_->data());
}
bool operator==(const JsonArrayIterator& other) const {
@ -61,7 +61,7 @@ class JsonArrayIterator {
}
private:
detail::MemoryPool* pool_;
detail::ResourceManager* resources_;
detail::VariantSlot* slot_;
};

View File

@ -9,10 +9,10 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
inline VariantData* collectionAddElement(CollectionData* array,
MemoryPool* pool) {
ResourceManager* resources) {
if (!array)
return nullptr;
auto slot = new (pool) VariantSlot();
auto slot = new (resources) VariantSlot();
if (!slot)
return nullptr;
array->add(slot);
@ -21,16 +21,16 @@ inline VariantData* collectionAddElement(CollectionData* array,
template <typename TAdaptedString>
inline VariantData* collectionAddMember(CollectionData* obj, TAdaptedString key,
MemoryPool* pool) {
ResourceManager* resources) {
ARDUINOJSON_ASSERT(!key.isNull());
ARDUINOJSON_ASSERT(obj != nullptr);
auto slot = new (pool) VariantSlot();
auto slot = new (resources) VariantSlot();
if (!slot)
return nullptr;
if (key.isLinked())
slot->setKey(key.data());
else {
auto storedKey = pool->saveString(key);
auto storedKey = resources->saveString(key);
if (!storedKey)
return nullptr;
slot->setKey(storedKey);
@ -39,31 +39,31 @@ inline VariantData* collectionAddMember(CollectionData* obj, TAdaptedString key,
return slot->data();
}
inline void collectionClear(CollectionData* c, MemoryPool* pool) {
inline void collectionClear(CollectionData* c, ResourceManager* resources) {
if (!c)
return;
for (auto slot = c->head(); slot; slot = slot->next())
slotRelease(slot, pool);
slotRelease(slot, resources);
c->clear();
}
inline bool collectionCopy(CollectionData* dst, const CollectionData* src,
MemoryPool* pool) {
ResourceManager* resources) {
if (!dst || !src)
return false;
collectionClear(dst, pool);
collectionClear(dst, resources);
for (VariantSlot* s = src->head(); s; s = s->next()) {
VariantData* var;
if (s->key() != 0) {
JsonString key(s->key(),
s->ownsKey() ? JsonString::Copied : JsonString::Linked);
var = collectionAddMember(dst, adaptString(key), pool);
var = collectionAddMember(dst, adaptString(key), resources);
} else {
var = collectionAddElement(dst, pool);
var = collectionAddElement(dst, resources);
}
if (!variantCopyFrom(var, s->data(), pool))
if (!variantCopyFrom(var, s->data(), resources))
return false;
}
return true;
@ -78,26 +78,26 @@ inline VariantData* collectionGetMember(const CollectionData* obj,
}
inline void collectionRemove(CollectionData* data, VariantSlot* slot,
MemoryPool* pool) {
ResourceManager* resources) {
if (!data || !slot)
return;
data->remove(slot);
slotRelease(slot, pool);
slotRelease(slot, resources);
}
inline void collectionRemoveElement(CollectionData* array, size_t index,
MemoryPool* pool) {
ResourceManager* resources) {
if (!array)
return;
collectionRemove(array, array->get(index), pool);
collectionRemove(array, array->get(index), resources);
}
template <typename TAdaptedString>
inline void collectionRemoveMember(CollectionData* obj, TAdaptedString key,
MemoryPool* pool) {
ResourceManager* resources) {
if (!obj)
return;
collectionRemove(obj, obj->get(key), pool);
collectionRemove(obj, obj->get(key), resources);
}
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -23,9 +23,10 @@ struct first_or_void<T, Rest...> {
};
template <template <typename> class TDeserializer, typename TReader>
TDeserializer<TReader> makeDeserializer(MemoryPool* pool, TReader reader) {
ARDUINOJSON_ASSERT(pool != 0);
return TDeserializer<TReader>(pool, reader);
TDeserializer<TReader> makeDeserializer(ResourceManager* resources,
TReader reader) {
ARDUINOJSON_ASSERT(resources != 0);
return TDeserializer<TReader>(resources, reader);
}
template <template <typename> class TDeserializer, typename TStream,
@ -36,10 +37,10 @@ DeserializationError deserialize(JsonDocument& doc, TStream&& input,
Args... args) {
auto reader = makeReader(detail::forward<TStream>(input));
auto data = VariantAttorney::getData(doc);
auto pool = VariantAttorney::getPool(doc);
auto resources = VariantAttorney::getResourceManager(doc);
auto options = makeDeserializationOptions(args...);
doc.clear();
return makeDeserializer<TDeserializer>(pool, reader)
return makeDeserializer<TDeserializer>(resources, reader)
.parse(*data, options.filter, options.nestingLimit);
}
@ -50,10 +51,10 @@ DeserializationError deserialize(JsonDocument& doc, TChar* input,
Size inputSize, Args... args) {
auto reader = makeReader(input, size_t(inputSize));
auto data = VariantAttorney::getData(doc);
auto pool = VariantAttorney::getPool(doc);
auto resources = VariantAttorney::getResourceManager(doc);
auto options = makeDeserializationOptions(args...);
doc.clear();
return makeDeserializer<TDeserializer>(pool, reader)
return makeDeserializer<TDeserializer>(resources, reader)
.parse(*data, options.filter, options.nestingLimit);
}

View File

@ -6,7 +6,7 @@
#include <ArduinoJson/Array/ElementProxy.hpp>
#include <ArduinoJson/Memory/Allocator.hpp>
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Object/JsonObject.hpp>
#include <ArduinoJson/Object/MemberProxy.hpp>
#include <ArduinoJson/Polyfills/utility.hpp>
@ -23,16 +23,16 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
public:
explicit JsonDocument(size_t capa,
Allocator* alloc = detail::DefaultAllocator::instance())
: pool_(capa, alloc) {}
: resources_(capa, alloc) {}
// Copy-constructor
JsonDocument(const JsonDocument& src)
: JsonDocument(src.pool_.capacity(), src.allocator()) {
: JsonDocument(src.resources_.capacity(), src.allocator()) {
set(src);
}
// Move-constructor
JsonDocument(JsonDocument&& src) : pool_(0, src.allocator()) {
JsonDocument(JsonDocument&& src) : resources_(0, src.allocator()) {
// TODO: use the copy and swap idiom
moveAssignFrom(src);
}
@ -73,20 +73,20 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename T>
JsonDocument& operator=(const T& src) {
size_t requiredSize = src.memoryUsage();
if (requiredSize > pool_.capacity())
pool_.reallocPool(requiredSize);
if (requiredSize > resources_.capacity())
resources_.reallocPool(requiredSize);
set(src);
return *this;
}
Allocator* allocator() const {
return pool_.allocator();
return resources_.allocator();
}
// Reduces the capacity of the memory pool to match the current usage.
// https://arduinojson.org/v6/api/JsonDocument/shrinktofit/
void shrinkToFit() {
auto offset = pool_.shrinkToFit();
auto offset = resources_.shrinkToFit();
data_.movePointers(offset);
}
@ -95,7 +95,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
bool garbageCollect() {
// make a temporary clone and move assign
JsonDocument tmp(*this);
if (!tmp.pool_.capacity())
if (!tmp.resources_.capacity())
return false;
moveAssignFrom(tmp);
return true;
@ -118,7 +118,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Empties the document and resets the memory pool
// https://arduinojson.org/v6/api/jsondocument/clear/
void clear() {
pool_.clear();
resources_.clear();
data_.reset();
}
@ -145,13 +145,13 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Returns the number of used bytes in the memory pool.
// https://arduinojson.org/v6/api/jsondocument/memoryusage/
size_t memoryUsage() const {
return pool_.size();
return resources_.size();
}
// Returns trues if the memory pool was too small.
// https://arduinojson.org/v6/api/jsondocument/overflowed/
bool overflowed() const {
return pool_.overflowed();
return resources_.overflowed();
}
// Returns the depth (nesting level) of the array.
@ -297,7 +297,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsondocument/add/
FORCE_INLINE JsonVariant add() {
return JsonVariant(&pool_, data_.addElement(&pool_));
return JsonVariant(&resources_, data_.addElement(&resources_));
}
// Appends a value to the root array.
@ -318,7 +318,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// ⚠️ Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsondocument/remove/
FORCE_INLINE void remove(size_t index) {
variantRemoveElement(getData(), index, getPool());
variantRemoveElement(getData(), index, getResourceManager());
}
// Removes a member of the root object.
@ -327,7 +327,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename TChar>
FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value>::type
remove(TChar* key) {
variantRemoveMember(getData(), detail::adaptString(key), getPool());
variantRemoveMember(getData(), detail::adaptString(key),
getResourceManager());
}
// Removes a member of the root object.
@ -337,7 +338,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
FORCE_INLINE
typename detail::enable_if<detail::IsString<TString>::value>::type
remove(const TString& key) {
variantRemoveMember(getData(), detail::adaptString(key), getPool());
variantRemoveMember(getData(), detail::adaptString(key),
getResourceManager());
}
FORCE_INLINE operator JsonVariant() {
@ -350,7 +352,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
private:
JsonVariant getVariant() {
return JsonVariant(&pool_, &data_);
return JsonVariant(&resources_, &data_);
}
JsonVariantConst getVariant() const {
@ -358,18 +360,18 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
}
void copyAssignFrom(const JsonDocument& src) {
pool_.reallocPool(src.pool_.capacity());
resources_.reallocPool(src.resources_.capacity());
set(src);
}
void moveAssignFrom(JsonDocument& src) {
data_ = src.data_;
src.data_.reset();
pool_ = move(src.pool_);
resources_ = move(src.resources_);
}
detail::MemoryPool* getPool() {
return &pool_;
detail::ResourceManager* getResourceManager() {
return &resources_;
}
detail::VariantData* getData() {
@ -384,7 +386,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
return &data_;
}
detail::MemoryPool pool_;
detail::ResourceManager resources_;
detail::VariantData data_;
};

View File

@ -9,7 +9,7 @@
#include <ArduinoJson/Json/Latch.hpp>
#include <ArduinoJson/Json/Utf16.hpp>
#include <ArduinoJson/Json/Utf8.hpp>
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Numbers/parseNumber.hpp>
#include <ArduinoJson/Polyfills/assert.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
@ -21,11 +21,11 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TReader>
class JsonDeserializer {
public:
JsonDeserializer(MemoryPool* pool, TReader reader)
: stringBuilder_(pool),
JsonDeserializer(ResourceManager* resources, TReader reader)
: stringBuilder_(resources),
foundSomething_(false),
latch_(reader),
pool_(pool) {}
resources_(resources) {}
template <typename TFilter>
DeserializationError parse(VariantData& variant, TFilter filter,
@ -172,7 +172,7 @@ class JsonDeserializer {
for (;;) {
if (elementFilter.allow()) {
// Allocate slot in array
VariantData* value = collectionAddElement(&array, pool_);
VariantData* value = collectionAddElement(&array, resources_);
if (!value)
return DeserializationError::NoMemory;
@ -279,14 +279,14 @@ class JsonDeserializer {
auto savedKey = stringBuilder_.save();
// Allocate slot in object
slot = new (pool_) VariantSlot();
slot = new (resources_) VariantSlot();
if (!slot)
return DeserializationError::NoMemory;
slot->setKey(savedKey);
object.add(slot);
} else {
slot->data()->setNull(pool_);
slot->data()->setNull(resources_);
}
// Parse value
@ -662,7 +662,7 @@ class JsonDeserializer {
StringBuilder stringBuilder_;
bool foundSomething_;
Latch<TReader> latch_;
MemoryPool* pool_;
ResourceManager* resources_;
char buffer_[64]; // using a member instead of a local variable because it
// ended in the recursive path after compiler inlined the
// code

View File

@ -15,22 +15,23 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class MemoryPool {
class ResourceManager {
public:
MemoryPool(size_t capa, Allocator* allocator = DefaultAllocator::instance())
ResourceManager(size_t capa,
Allocator* allocator = DefaultAllocator::instance())
: allocator_(allocator), overflowed_(false) {
allocPool(addPadding(capa));
}
~MemoryPool() {
~ResourceManager() {
deallocAllStrings();
deallocPool();
}
MemoryPool(const MemoryPool&) = delete;
MemoryPool& operator=(const MemoryPool& src) = delete;
ResourceManager(const ResourceManager&) = delete;
ResourceManager& operator=(const ResourceManager& src) = delete;
MemoryPool& operator=(MemoryPool&& src) {
ResourceManager& operator=(ResourceManager&& src) {
deallocAllStrings();
deallocPool();
allocator_ = src.allocator_;

View File

@ -4,7 +4,7 @@
#pragma once
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Memory/ResourceManager.hpp>
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
@ -12,26 +12,26 @@ class StringBuilder {
public:
static const size_t initialCapacity = 31;
StringBuilder(MemoryPool* pool) : pool_(pool) {}
StringBuilder(ResourceManager* resources) : resources_(resources) {}
~StringBuilder() {
if (node_)
pool_->deallocString(node_);
resources_->deallocString(node_);
}
void startString() {
size_ = 0;
if (!node_)
node_ = pool_->allocString(initialCapacity);
node_ = resources_->allocString(initialCapacity);
}
StringNode* save() {
ARDUINOJSON_ASSERT(node_ != nullptr);
node_->data[size_] = 0;
StringNode* node = pool_->findString(adaptString(node_->data, size_));
StringNode* node = resources_->findString(adaptString(node_->data, size_));
if (!node) {
node = pool_->reallocString(node_, size_);
pool_->addStringToList(node);
node = resources_->reallocString(node_, size_);
resources_->addStringToList(node);
node_ = nullptr; // next time we need a new string
} else {
node->references++;
@ -51,7 +51,7 @@ class StringBuilder {
void append(char c) {
if (node_ && size_ == node_->length)
node_ = pool_->reallocString(node_, size_ * 2U + 1);
node_ = resources_->reallocString(node_, size_ * 2U + 1);
if (node_)
node_->data[size_++] = c;
}
@ -71,7 +71,7 @@ class StringBuilder {
}
private:
MemoryPool* pool_;
ResourceManager* resources_;
StringNode* node_ = nullptr;
size_t size_ = 0;
};

View File

@ -5,7 +5,7 @@
#pragma once
#include <ArduinoJson/Deserialization/deserialize.hpp>
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/MsgPack/endianess.hpp>
#include <ArduinoJson/MsgPack/ieee754.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
@ -16,10 +16,10 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TReader>
class MsgPackDeserializer {
public:
MsgPackDeserializer(MemoryPool* pool, TReader reader)
: pool_(pool),
MsgPackDeserializer(ResourceManager* resources, TReader reader)
: resources_(resources),
reader_(reader),
stringBuilder_(pool),
stringBuilder_(resources),
foundSomething_(false) {}
template <typename TFilter>
@ -434,7 +434,7 @@ class MsgPackDeserializer {
if (elementFilter.allow()) {
ARDUINOJSON_ASSERT(array != 0);
value = collectionAddElement(array, pool_);
value = collectionAddElement(array, resources_);
if (!value)
return DeserializationError::NoMemory;
} else {
@ -495,7 +495,7 @@ class MsgPackDeserializer {
// Save key in memory pool.
auto savedKey = stringBuilder_.save();
VariantSlot* slot = new (pool_) VariantSlot();
VariantSlot* slot = new (resources_) VariantSlot();
if (!slot)
return DeserializationError::NoMemory;
@ -553,7 +553,7 @@ class MsgPackDeserializer {
return skipBytes(size + 1U);
}
MemoryPool* pool_;
ResourceManager* resources_;
TReader reader_;
StringBuilder stringBuilder_;
bool foundSomething_;

View File

@ -20,15 +20,17 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
typedef JsonObjectIterator iterator;
// Creates an unbound reference.
FORCE_INLINE JsonObject() : data_(0), pool_(0) {}
FORCE_INLINE JsonObject() : data_(0), resources_(0) {}
// INTERNAL USE ONLY
FORCE_INLINE JsonObject(detail::MemoryPool* buf, detail::CollectionData* data)
: data_(data), pool_(buf) {}
FORCE_INLINE JsonObject(detail::ResourceManager* buf,
detail::CollectionData* data)
: data_(data), resources_(buf) {}
operator JsonVariant() const {
void* data = data_; // prevent warning cast-align
return JsonVariant(pool_, reinterpret_cast<detail::VariantData*>(data));
return JsonVariant(resources_,
reinterpret_cast<detail::VariantData*>(data));
}
operator JsonObjectConst() const {
@ -74,7 +76,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
FORCE_INLINE iterator begin() const {
if (!data_)
return iterator();
return iterator(pool_, data_->head());
return iterator(resources_, data_->head());
}
// Returns an iterator following the last key-value pair of the object.
@ -87,13 +89,13 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// ⚠️ Doesn't release the memory associated with the removed members.
// https://arduinojson.org/v6/api/jsonobject/clear/
void clear() const {
collectionClear(data_, pool_);
collectionClear(data_, resources_);
}
// Copies an object.
// https://arduinojson.org/v6/api/jsonobject/set/
FORCE_INLINE bool set(JsonObjectConst src) {
return collectionCopy(data_, src.data_, pool_);
return collectionCopy(data_, src.data_, resources_);
}
// Compares the content of two objects.
@ -125,7 +127,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// ⚠️ Doesn't release the memory associated with the removed member.
// https://arduinojson.org/v6/api/jsonobject/remove/
FORCE_INLINE void remove(iterator it) const {
collectionRemove(data_, it.slot_, pool_);
collectionRemove(data_, it.slot_, resources_);
}
// Removes the member with the specified key.
@ -133,7 +135,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// https://arduinojson.org/v6/api/jsonobject/remove/
template <typename TString>
FORCE_INLINE void remove(const TString& key) const {
collectionRemoveMember(data_, detail::adaptString(key), pool_);
collectionRemoveMember(data_, detail::adaptString(key), resources_);
}
// Removes the member with the specified key.
@ -141,7 +143,7 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// https://arduinojson.org/v6/api/jsonobject/remove/
template <typename TChar>
FORCE_INLINE void remove(TChar* key) const {
collectionRemoveMember(data_, detail::adaptString(key), pool_);
collectionRemoveMember(data_, detail::adaptString(key), resources_);
}
// Returns true if the object contains the specified key.
@ -187,8 +189,8 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
}
private:
detail::MemoryPool* getPool() const {
return pool_;
detail::ResourceManager* getResourceManager() const {
return resources_;
}
detail::VariantData* getData() const {
@ -201,23 +203,23 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
template <typename TAdaptedString>
void removeMember(TAdaptedString key) const {
collectionRemove(data_, data_->get(key), pool_);
collectionRemove(data_, data_->get(key), resources_);
}
detail::CollectionData* data_;
detail::MemoryPool* pool_;
detail::ResourceManager* resources_;
};
template <>
struct Converter<JsonObject> : private detail::VariantAttorney {
static void toJson(JsonVariantConst src, JsonVariant dst) {
variantCopyFrom(getData(dst), getData(src), getPool(dst));
variantCopyFrom(getData(dst), getData(src), getResourceManager(dst));
}
static JsonObject fromJson(JsonVariant src) {
auto data = getData(src);
auto pool = getPool(src);
return JsonObject(pool, data != 0 ? data->asObject() : 0);
auto resources = getResourceManager(src);
return JsonObject(resources, data != 0 ? data->asObject() : 0);
}
static detail::InvalidConversion<JsonVariantConst, JsonObject> fromJson(
@ -241,7 +243,8 @@ template <typename TDerived>
template <typename T>
typename enable_if<is_same<T, JsonObject>::value, JsonObject>::type
VariantRefBase<TDerived>::to() const {
return JsonObject(getPool(), variantToObject(getOrCreateData(), getPool()));
return JsonObject(getResourceManager(),
variantToObject(getOrCreateData(), getResourceManager()));
}
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -134,7 +134,7 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
template <>
struct Converter<JsonObjectConst> : private detail::VariantAttorney {
static void toJson(JsonVariantConst src, JsonVariant dst) {
variantCopyFrom(getData(dst), getData(src), getPool(dst));
variantCopyFrom(getData(dst), getData(src), getResourceManager(dst));
}
static JsonObjectConst fromJson(JsonVariantConst src) {

View File

@ -11,8 +11,8 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
class JsonPairPtr {
public:
JsonPairPtr(detail::MemoryPool* pool, detail::VariantSlot* slot)
: pair_(pool, slot) {}
JsonPairPtr(detail::ResourceManager* resources, detail::VariantSlot* slot)
: pair_(resources, slot) {}
const JsonPair* operator->() const {
return &pair_;
@ -32,15 +32,15 @@ class JsonObjectIterator {
public:
JsonObjectIterator() : slot_(0) {}
explicit JsonObjectIterator(detail::MemoryPool* pool,
explicit JsonObjectIterator(detail::ResourceManager* resources,
detail::VariantSlot* slot)
: pool_(pool), slot_(slot) {}
: resources_(resources), slot_(slot) {}
JsonPair operator*() const {
return JsonPair(pool_, slot_);
return JsonPair(resources_, slot_);
}
JsonPairPtr operator->() {
return JsonPairPtr(pool_, slot_);
return JsonPairPtr(resources_, slot_);
}
bool operator==(const JsonObjectIterator& other) const {
@ -62,7 +62,7 @@ class JsonObjectIterator {
}
private:
detail::MemoryPool* pool_;
detail::ResourceManager* resources_;
detail::VariantSlot* slot_;
};

View File

@ -15,11 +15,11 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
class JsonPair {
public:
// INTERNAL USE ONLY
JsonPair(detail::MemoryPool* pool, detail::VariantSlot* slot) {
JsonPair(detail::ResourceManager* resources, detail::VariantSlot* slot) {
if (slot) {
key_ = JsonString(slot->key(), slot->ownsKey() ? JsonString::Copied
: JsonString::Linked);
value_ = JsonVariant(pool, slot->data());
value_ = JsonVariant(resources, slot->data());
}
}

View File

@ -41,8 +41,8 @@ class MemberProxy
}
private:
FORCE_INLINE MemoryPool* getPool() const {
return VariantAttorney::getPool(upstream_);
FORCE_INLINE ResourceManager* getResourceManager() const {
return VariantAttorney::getResourceManager(upstream_);
}
FORCE_INLINE VariantData* getData() const {
@ -51,9 +51,9 @@ class MemberProxy
}
FORCE_INLINE VariantData* getOrCreateData() const {
return variantGetOrAddMember(VariantAttorney::getOrCreateData(upstream_),
adaptString(key_),
VariantAttorney::getPool(upstream_));
return variantGetOrAddMember(
VariantAttorney::getOrCreateData(upstream_), adaptString(key_),
VariantAttorney::getResourceManager(upstream_));
}
private:

View File

@ -42,7 +42,7 @@ struct Converter<
: private detail::VariantAttorney {
static void toJson(T src, JsonVariant dst) {
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
variantSetInteger(getData(dst), src, getPool(dst));
variantSetInteger(getData(dst), src, getResourceManager(dst));
}
static T fromJson(JsonVariantConst src) {
@ -78,7 +78,7 @@ struct Converter<T, typename detail::enable_if<detail::is_enum<T>::value>::type>
template <>
struct Converter<bool> : private detail::VariantAttorney {
static void toJson(bool src, JsonVariant dst) {
variantSetBoolean(getData(dst), src, getPool(dst));
variantSetBoolean(getData(dst), src, getResourceManager(dst));
}
static bool fromJson(JsonVariantConst src) {
@ -97,7 +97,8 @@ struct Converter<
T, typename detail::enable_if<detail::is_floating_point<T>::value>::type>
: private detail::VariantAttorney {
static void toJson(T src, JsonVariant dst) {
variantSetFloat(getData(dst), static_cast<JsonFloat>(src), getPool(dst));
variantSetFloat(getData(dst), static_cast<JsonFloat>(src),
getResourceManager(dst));
}
static T fromJson(JsonVariantConst src) {
@ -114,7 +115,8 @@ struct Converter<
template <>
struct Converter<const char*> : private detail::VariantAttorney {
static void toJson(const char* src, JsonVariant dst) {
variantSetString(getData(dst), detail::adaptString(src), getPool(dst));
variantSetString(getData(dst), detail::adaptString(src),
getResourceManager(dst));
}
static const char* fromJson(JsonVariantConst src) {
@ -131,7 +133,8 @@ struct Converter<const char*> : private detail::VariantAttorney {
template <>
struct Converter<JsonString> : private detail::VariantAttorney {
static void toJson(JsonString src, JsonVariant dst) {
variantSetString(getData(dst), detail::adaptString(src), getPool(dst));
variantSetString(getData(dst), detail::adaptString(src),
getResourceManager(dst));
}
static JsonString fromJson(JsonVariantConst src) {
@ -150,8 +153,8 @@ inline typename detail::enable_if<detail::IsString<T>::value>::type
convertToJson(const T& src, JsonVariant dst) {
using namespace detail;
auto data = VariantAttorney::getData(dst);
auto pool = VariantAttorney::getPool(dst);
variantSetString(data, adaptString(src), pool);
auto resources = VariantAttorney::getResourceManager(dst);
variantSetString(data, adaptString(src), resources);
}
// SerializedValue<std::string>
@ -160,14 +163,14 @@ convertToJson(const T& src, JsonVariant dst) {
template <typename T>
struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
static void toJson(SerializedValue<T> src, JsonVariant dst) {
variantSetRawString(getData(dst), src, getPool(dst));
variantSetRawString(getData(dst), src, getResourceManager(dst));
}
};
template <>
struct Converter<decltype(nullptr)> : private detail::VariantAttorney {
static void toJson(decltype(nullptr), JsonVariant dst) {
variantSetNull(getData(dst), getPool(dst));
variantSetNull(getData(dst), getResourceManager(dst));
}
static decltype(nullptr) fromJson(JsonVariantConst) {
return nullptr;
@ -181,9 +184,9 @@ struct Converter<decltype(nullptr)> : private detail::VariantAttorney {
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
namespace detail {
class MemoryPoolPrint : public Print {
class StringBuilderPrint : public Print {
public:
MemoryPoolPrint(MemoryPool* pool) : copier_(pool) {
StringBuilderPrint(ResourceManager* resources) : copier_(resources) {
copier_.startString();
}
@ -216,11 +219,11 @@ class MemoryPoolPrint : public Print {
} // namespace detail
inline void convertToJson(const ::Printable& src, JsonVariant dst) {
auto pool = detail::VariantAttorney::getPool(dst);
auto resources = detail::VariantAttorney::getResourceManager(dst);
auto data = detail::VariantAttorney::getData(dst);
if (!pool || !data)
if (!resources || !data)
return;
detail::MemoryPoolPrint print(pool);
detail::StringBuilderPrint print(resources);
src.printTo(print);
if (print.overflowed()) {
data->setNull();

View File

@ -16,15 +16,15 @@ class JsonVariant : public detail::VariantRefBase<JsonVariant>,
public:
// Creates an unbound reference.
JsonVariant() : data_(0), pool_(0) {}
JsonVariant() : data_(0), resources_(0) {}
// INTERNAL USE ONLY
JsonVariant(detail::MemoryPool* pool, detail::VariantData* data)
: data_(data), pool_(pool) {}
JsonVariant(detail::ResourceManager* resources, detail::VariantData* data)
: data_(data), resources_(resources) {}
private:
FORCE_INLINE detail::MemoryPool* getPool() const {
return pool_;
FORCE_INLINE detail::ResourceManager* getResourceManager() const {
return resources_;
}
FORCE_INLINE detail::VariantData* getData() const {
@ -36,13 +36,14 @@ class JsonVariant : public detail::VariantRefBase<JsonVariant>,
}
detail::VariantData* data_;
detail::MemoryPool* pool_;
detail::ResourceManager* resources_;
};
template <>
struct Converter<JsonVariant> : private detail::VariantAttorney {
static void toJson(JsonVariant src, JsonVariant dst) {
detail::variantCopyFrom(getData(dst), getData(src), getPool(dst));
detail::variantCopyFrom(getData(dst), getData(src),
getResourceManager(dst));
}
static JsonVariant fromJson(JsonVariant src) {
@ -65,7 +66,7 @@ struct Converter<JsonVariant> : private detail::VariantAttorney {
template <>
struct Converter<JsonVariantConst> : private detail::VariantAttorney {
static void toJson(JsonVariantConst src, JsonVariant dst) {
variantCopyFrom(getData(dst), getData(src), getPool(dst));
variantCopyFrom(getData(dst), getData(src), getResourceManager(dst));
}
static JsonVariantConst fromJson(JsonVariantConst src) {
@ -84,25 +85,26 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TDerived>
inline JsonVariant VariantRefBase<TDerived>::add() const {
return JsonVariant(getPool(),
variantAddElement(getOrCreateData(), getPool()));
return JsonVariant(
getResourceManager(),
variantAddElement(getOrCreateData(), getResourceManager()));
}
template <typename TDerived>
inline JsonVariant VariantRefBase<TDerived>::getVariant() const {
return JsonVariant(getPool(), getData());
return JsonVariant(getResourceManager(), getData());
}
template <typename TDerived>
inline JsonVariant VariantRefBase<TDerived>::getOrCreateVariant() const {
return JsonVariant(getPool(), getOrCreateData());
return JsonVariant(getResourceManager(), getOrCreateData());
}
template <typename TDerived>
template <typename T>
typename enable_if<is_same<T, JsonVariant>::value, JsonVariant>::type
VariantRefBase<TDerived>::to() const {
variantSetNull(getOrCreateData(), getPool());
variantSetNull(getOrCreateData(), getResourceManager());
return *this;
}

View File

@ -7,7 +7,7 @@
#include <stddef.h>
#include <stdint.h> // for uint8_t
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
#include <ArduinoJson/Strings/IsString.hpp>
#include <ArduinoJson/Strings/StringAdapters.hpp>

View File

@ -18,11 +18,11 @@ inline size_t slotSize(const VariantSlot* var) {
return n;
}
inline void slotRelease(VariantSlot* slot, MemoryPool* pool) {
inline void slotRelease(VariantSlot* slot, ResourceManager* resources) {
ARDUINOJSON_ASSERT(slot != nullptr);
if (slot->ownsKey())
pool->dereferenceString(slot->key());
slot->data()->setNull(pool);
resources->dereferenceString(slot->key());
slot->data()->setNull(resources);
}
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -30,8 +30,8 @@ class VariantAttorney {
public:
template <typename TClient>
FORCE_INLINE static MemoryPool* getPool(TClient& client) {
return client.getPool();
FORCE_INLINE static ResourceManager* getResourceManager(TClient& client) {
return client.getResourceManager();
}
template <typename TClient>

View File

@ -14,14 +14,15 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
VariantData* collectionAddElement(CollectionData* array, MemoryPool* pool);
VariantData* collectionAddElement(CollectionData* array,
ResourceManager* resources);
bool collectionCopy(CollectionData* dst, const CollectionData* src,
MemoryPool* pool);
ResourceManager* resources);
void collectionRemoveElement(CollectionData* data, size_t index,
MemoryPool* pool);
ResourceManager* resources);
template <typename T>
T parseNumber(const char* s);
void slotRelease(VariantSlot* slot, MemoryPool* pool);
void slotRelease(VariantSlot* slot, ResourceManager* resources);
class VariantData {
VariantContent content_; // must be first to allow cast from array to variant
@ -68,9 +69,9 @@ class VariantData {
}
}
VariantData* addElement(MemoryPool* pool) {
VariantData* addElement(ResourceManager* resources) {
auto array = isNull() ? &toArray() : asArray();
return collectionAddElement(array, pool);
return collectionAddElement(array, resources);
}
bool asBoolean() const {
@ -172,20 +173,20 @@ class VariantData {
}
}
bool copyFrom(const VariantData* src, MemoryPool* pool) {
release(pool);
bool copyFrom(const VariantData* src, ResourceManager* resources) {
release(resources);
if (!src) {
setNull();
return true;
}
switch (src->type()) {
case VALUE_IS_ARRAY:
return collectionCopy(&toArray(), src->asArray(), pool);
return collectionCopy(&toArray(), src->asArray(), resources);
case VALUE_IS_OBJECT:
return collectionCopy(&toObject(), src->asObject(), pool);
return collectionCopy(&toObject(), src->asObject(), resources);
case VALUE_IS_OWNED_STRING: {
auto str = adaptString(src->asString());
auto dup = pool->saveString(str);
auto dup = resources->saveString(str);
if (!dup)
return false;
setOwnedString(dup);
@ -193,7 +194,7 @@ class VariantData {
}
case VALUE_IS_RAW_STRING: {
auto str = adaptString(src->asRawString());
auto dup = pool->saveString(str);
auto dup = resources->saveString(str);
if (!dup)
return false;
setRawString(dup);
@ -221,7 +222,7 @@ class VariantData {
return slotData(object->get(key));
}
VariantData* getOrAddElement(size_t index, MemoryPool* pool) {
VariantData* getOrAddElement(size_t index, ResourceManager* resources) {
auto array = isNull() ? &toArray() : asArray();
if (!array)
return nullptr;
@ -233,7 +234,7 @@ class VariantData {
if (!slot)
index++;
while (index > 0) {
slot = new (pool) VariantSlot();
slot = new (resources) VariantSlot();
if (!slot)
return nullptr;
array->add(slot);
@ -243,7 +244,7 @@ class VariantData {
}
template <typename TAdaptedString>
VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool) {
VariantData* getOrAddMember(TAdaptedString key, ResourceManager* resources) {
if (key.isNull())
return nullptr;
auto obj = isNull() ? &toObject() : asObject();
@ -252,7 +253,7 @@ class VariantData {
auto slot = obj->get(key);
if (slot)
return slot->data();
return collectionAddMember(obj, key, pool);
return collectionAddMember(obj, key, resources);
}
bool isArray() const {
@ -334,13 +335,13 @@ class VariantData {
flags_ = uint8_t((flags_ & OWNED_KEY_BIT) | (src.flags_ & ~OWNED_KEY_BIT));
}
void removeElement(size_t index, MemoryPool* pool) {
collectionRemoveElement(asArray(), index, pool);
void removeElement(size_t index, ResourceManager* resources) {
collectionRemoveElement(asArray(), index, resources);
}
template <typename TAdaptedString>
void removeMember(TAdaptedString key, MemoryPool* pool) {
collectionRemoveMember(asObject(), key, pool);
void removeMember(TAdaptedString key, ResourceManager* resources) {
collectionRemoveMember(asObject(), key, resources);
}
void reset() {
@ -352,8 +353,8 @@ class VariantData {
content_.asBoolean = value;
}
void setBoolean(bool value, MemoryPool* pool) {
release(pool);
void setBoolean(bool value, ResourceManager* resources) {
release(resources);
setBoolean(value);
}
@ -362,8 +363,8 @@ class VariantData {
content_.asFloat = value;
}
void setFloat(JsonFloat value, MemoryPool* pool) {
release(pool);
void setFloat(JsonFloat value, ResourceManager* resources) {
release(resources);
setFloat(value);
}
@ -380,8 +381,8 @@ class VariantData {
}
template <typename T>
void setInteger(T value, MemoryPool* pool) {
release(pool);
void setInteger(T value, ResourceManager* resources) {
release(resources);
setInteger(value);
}
@ -389,8 +390,8 @@ class VariantData {
setType(VALUE_IS_NULL);
}
void setNull(MemoryPool* pool) {
release(pool);
void setNull(ResourceManager* resources) {
release(resources);
setNull();
}
@ -401,9 +402,9 @@ class VariantData {
}
template <typename T>
void setRawString(SerializedValue<T> value, MemoryPool* pool) {
release(pool);
auto dup = pool->saveString(adaptString(value.data(), value.size()));
void setRawString(SerializedValue<T> value, ResourceManager* resources) {
release(resources);
auto dup = resources->saveString(adaptString(value.data(), value.size()));
if (dup)
setRawString(dup);
else
@ -411,8 +412,8 @@ class VariantData {
}
template <typename TAdaptedString>
void setString(TAdaptedString value, MemoryPool* pool) {
setNull(pool);
void setString(TAdaptedString value, ResourceManager* resources) {
setNull(resources);
if (value.isNull())
return;
@ -422,7 +423,7 @@ class VariantData {
return;
}
auto dup = pool->saveString(value);
auto dup = resources->saveString(value);
if (dup)
setOwnedString(dup);
}
@ -449,8 +450,8 @@ class VariantData {
return content_.asCollection;
}
CollectionData& toArray(MemoryPool* pool) {
release(pool);
CollectionData& toArray(ResourceManager* resources) {
release(resources);
return toArray();
}
@ -460,8 +461,8 @@ class VariantData {
return content_.asCollection;
}
CollectionData& toObject(MemoryPool* pool) {
release(pool);
CollectionData& toObject(ResourceManager* resources) {
release(resources);
return toObject();
}
@ -470,14 +471,14 @@ class VariantData {
}
private:
void release(MemoryPool* pool) {
void release(ResourceManager* resources) {
if (flags_ & OWNED_VALUE_BIT)
pool->dereferenceString(content_.asOwnedString->data);
resources->dereferenceString(content_.asOwnedString->data);
auto c = asCollection();
if (c) {
for (auto slot = c->head(); slot; slot = slot->next())
slotRelease(slot, pool);
slotRelease(slot, resources);
}
}
@ -497,16 +498,17 @@ typename TVisitor::result_type variantAccept(const VariantData* var,
}
inline bool variantCopyFrom(VariantData* dst, const VariantData* src,
MemoryPool* pool) {
ResourceManager* resources) {
if (!dst)
return false;
return dst->copyFrom(src, pool);
return dst->copyFrom(src, resources);
}
inline VariantData* variantAddElement(VariantData* var, MemoryPool* pool) {
inline VariantData* variantAddElement(VariantData* var,
ResourceManager* resources) {
if (!var)
return nullptr;
return var->addElement(pool);
return var->addElement(resources);
}
inline VariantData* variantGetElement(const VariantData* var, size_t index) {
@ -521,18 +523,18 @@ VariantData* variantGetMember(const VariantData* var, TAdaptedString key) {
}
inline VariantData* variantGetOrAddElement(VariantData* var, size_t index,
MemoryPool* pool) {
ResourceManager* resources) {
if (!var)
return nullptr;
return var->getOrAddElement(index, pool);
return var->getOrAddElement(index, resources);
}
template <typename TAdaptedString>
VariantData* variantGetOrAddMember(VariantData* var, TAdaptedString key,
MemoryPool* pool) {
ResourceManager* resources) {
if (!var)
return nullptr;
return var->getOrAddMember(key, pool);
return var->getOrAddMember(key, resources);
}
inline bool variantIsNull(const VariantData* var) {
@ -548,76 +550,79 @@ inline size_t variantNesting(const VariantData* var) {
}
inline void variantRemoveElement(VariantData* var, size_t index,
MemoryPool* pool) {
ResourceManager* resources) {
if (!var)
return;
var->removeElement(index, pool);
var->removeElement(index, resources);
}
template <typename TAdaptedString>
void variantRemoveMember(VariantData* var, TAdaptedString key,
MemoryPool* pool) {
ResourceManager* resources) {
if (!var)
return;
var->removeMember(key, pool);
var->removeMember(key, resources);
}
inline void variantSetBoolean(VariantData* var, bool value, MemoryPool* pool) {
inline void variantSetBoolean(VariantData* var, bool value,
ResourceManager* resources) {
if (!var)
return;
var->setBoolean(value, pool);
var->setBoolean(value, resources);
}
inline void variantSetFloat(VariantData* var, JsonFloat value,
MemoryPool* pool) {
ResourceManager* resources) {
if (!var)
return;
var->setFloat(value, pool);
var->setFloat(value, resources);
}
template <typename T>
void variantSetInteger(VariantData* var, T value, MemoryPool* pool) {
void variantSetInteger(VariantData* var, T value, ResourceManager* resources) {
if (!var)
return;
var->setInteger(value, pool);
var->setInteger(value, resources);
}
inline void variantSetNull(VariantData* var, MemoryPool* pool) {
inline void variantSetNull(VariantData* var, ResourceManager* resources) {
if (!var)
return;
var->setNull(pool);
var->setNull(resources);
}
template <typename T>
void variantSetRawString(VariantData* var, SerializedValue<T> value,
MemoryPool* pool) {
ResourceManager* resources) {
if (!var)
return;
var->setRawString(value, pool);
var->setRawString(value, resources);
}
template <typename TAdaptedString>
void variantSetString(VariantData* var, TAdaptedString value,
MemoryPool* pool) {
ResourceManager* resources) {
if (!var)
return;
var->setString(value, pool);
var->setString(value, resources);
}
inline size_t variantSize(const VariantData* var) {
return var != 0 ? var->size() : 0;
}
inline CollectionData* variantToArray(VariantData* var, MemoryPool* pool) {
inline CollectionData* variantToArray(VariantData* var,
ResourceManager* resources) {
if (!var)
return 0;
return &var->toArray(pool);
return &var->toArray(resources);
}
inline CollectionData* variantToObject(VariantData* var, MemoryPool* pool) {
inline CollectionData* variantToObject(VariantData* var,
ResourceManager* resources) {
if (!var)
return 0;
return &var->toObject(pool);
return &var->toObject(resources);
}
ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@ -30,7 +30,7 @@ class VariantRefBase : public VariantTag {
// ⚠️ Doesn't release the memory associated with the previous value.
// https://arduinojson.org/v6/api/jsonvariant/clear/
FORCE_INLINE void clear() const {
variantSetNull(getOrCreateData(), getPool());
variantSetNull(getOrCreateData(), getResourceManager());
}
// Returns true if the value is null or the reference is unbound.
@ -112,7 +112,7 @@ class VariantRefBase : public VariantTag {
VariantData* data = getOrCreateData();
if (!data)
return;
variantSetNull(data, getPool());
variantSetNull(data, getResourceManager());
const VariantData* targetData = VariantAttorney::getData(target);
if (targetData)
*data = *targetData;
@ -123,8 +123,8 @@ class VariantRefBase : public VariantTag {
template <typename T>
FORCE_INLINE bool set(const T& value) const {
Converter<T>::toJson(value, getOrCreateVariant());
MemoryPool* pool = getPool();
return pool && !pool->overflowed();
auto resources = getResourceManager();
return resources && !resources->overflowed();
}
// Copies the specified value.
@ -132,8 +132,8 @@ class VariantRefBase : public VariantTag {
template <typename T>
FORCE_INLINE bool set(T* value) const {
Converter<T*>::toJson(value, getOrCreateVariant());
MemoryPool* pool = getPool();
return pool && !pool->overflowed();
auto resources = getResourceManager();
return resources && !resources->overflowed();
}
// Returns the size of the array or object.
@ -178,7 +178,7 @@ class VariantRefBase : public VariantTag {
// ⚠️ Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsonvariant/remove/
FORCE_INLINE void remove(size_t index) const {
variantRemoveElement(getData(), index, getPool());
variantRemoveElement(getData(), index, getResourceManager());
}
// Removes a member of the object.
@ -187,7 +187,7 @@ class VariantRefBase : public VariantTag {
template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
TChar* key) const {
variantRemoveMember(getData(), adaptString(key), getPool());
variantRemoveMember(getData(), adaptString(key), getResourceManager());
}
// Removes a member of the object.
@ -196,7 +196,7 @@ class VariantRefBase : public VariantTag {
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString& key) const {
variantRemoveMember(getData(), adaptString(key), getPool());
variantRemoveMember(getData(), adaptString(key), getResourceManager());
}
// Creates an array and appends it to the array.
@ -266,8 +266,8 @@ class VariantRefBase : public VariantTag {
return static_cast<const TDerived&>(*this);
}
FORCE_INLINE MemoryPool* getPool() const {
return VariantAttorney::getPool(derived());
FORCE_INLINE ResourceManager* getResourceManager() const {
return VariantAttorney::getResourceManager(derived());
}
FORCE_INLINE VariantData* getData() const {

View File

@ -4,7 +4,7 @@
#pragma once
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Memory/ResourceManager.hpp>
#include <ArduinoJson/Polyfills/integer.hpp>
#include <ArduinoJson/Polyfills/limits.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
@ -26,11 +26,11 @@ class VariantSlot {
const char* key_;
public:
static void* operator new(size_t size, MemoryPool* pool) noexcept {
return pool->allocFromPool(size);
static void* operator new(size_t size, ResourceManager* resources) noexcept {
return resources->allocFromPool(size);
}
static void operator delete(void*, MemoryPool*) noexcept {
static void operator delete(void*, ResourceManager*) noexcept {
// we cannot release memory from the pool
}