Skip to content

Commit

Permalink
Add VariantId (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
bblanchon committed Jul 12, 2023
1 parent 373cbc2 commit 7c9af03
Show file tree
Hide file tree
Showing 35 changed files with 273 additions and 238 deletions.
3 changes: 3 additions & 0 deletions extras/tests/MsgPackSerializer/serializeArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License

#define ARDUINOJSON_SLOT_ID_SIZE 4 // required to reach 65536 elements

#include <ArduinoJson.h>
#include <catch.hpp>

Expand Down Expand Up @@ -55,6 +57,7 @@ TEST_CASE("serialize MsgPack array") {
const char* nil = 0;
for (int i = 0; i < 65536; i++)
array.add(nil);
REQUIRE(array.size() == 65536);

check(array,
std::string("\xDD\x00\x01\x00\x00", 5) + std::string(65536, '\xc0'));
Expand Down
16 changes: 11 additions & 5 deletions extras/tests/ResourceManager/allocVariant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,33 @@ TEST_CASE("ResourceManager::allocVariant()") {
SECTION("Returns aligned pointers") {
ResourceManager resources(4096);

REQUIRE(isAligned(resources.allocVariant()));
REQUIRE(isAligned(resources.allocVariant()));
REQUIRE(isAligned(resources.allocVariant().operator VariantSlot*()));
REQUIRE(isAligned(resources.allocVariant().operator VariantSlot*()));
}

SECTION("Returns zero if capacity is 0") {
ResourceManager resources(0);

REQUIRE(resources.allocVariant() == 0);
auto variant = resources.allocVariant();
REQUIRE(variant.id() == 0);
REQUIRE(static_cast<VariantSlot*>(variant) == nullptr);
}

SECTION("Returns zero if buffer is null") {
ResourceManager resources(4096, FailingAllocator::instance());

REQUIRE(resources.allocVariant() == 0);
auto variant = resources.allocVariant();
REQUIRE(variant.id() == 0);
REQUIRE(static_cast<VariantSlot*>(variant) == nullptr);
}

SECTION("Returns zero if capacity is insufficient") {
ResourceManager resources(sizeof(VariantSlot));

resources.allocVariant();

REQUIRE(resources.allocVariant() == 0);
auto variant = resources.allocVariant();
REQUIRE(variant.id() == 0);
REQUIRE(static_cast<VariantSlot*>(variant) == nullptr);
}
}
9 changes: 5 additions & 4 deletions src/ArduinoJson/Array/ArrayData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ class ArrayData : public CollectionData {

VariantData* getOrAddElement(size_t index, ResourceManager* resources);

VariantData* getElement(size_t index) const;
VariantData* getElement(size_t index, const ResourceManager* resources) const;

static VariantData* getElement(const ArrayData* array, size_t index) {
static VariantData* getElement(const ArrayData* array, size_t index,
const ResourceManager* resources) {
if (!array)
return nullptr;
return array->getElement(index);
return array->getElement(index, resources);
}

void removeElement(size_t index, ResourceManager* resources);
Expand All @@ -50,7 +51,7 @@ class ArrayData : public CollectionData {
}

private:
iterator at(size_t index) const;
iterator at(size_t index, const ResourceManager* resources) const;
};

ARDUINOJSON_END_PRIVATE_NAMESPACE
18 changes: 10 additions & 8 deletions src/ArduinoJson/Array/ArrayImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@

ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE

inline ArrayData::iterator ArrayData::at(size_t index) const {
auto it = createIterator();
inline ArrayData::iterator ArrayData::at(
size_t index, const ResourceManager* resources) const {
auto it = createIterator(resources);
while (!it.done() && index) {
it.next();
it.next(resources);
--index;
}
return it;
}

inline VariantData* ArrayData::getOrAddElement(size_t index,
ResourceManager* resources) {
auto it = createIterator();
auto it = createIterator(resources);
while (!it.done() && index > 0) {
it.next();
it.next(resources);
index--;
}
if (it.done())
Expand All @@ -37,12 +38,13 @@ inline VariantData* ArrayData::getOrAddElement(size_t index,
return element;
}

inline VariantData* ArrayData::getElement(size_t index) const {
return at(index).data();
inline VariantData* ArrayData::getElement(
size_t index, const ResourceManager* resources) const {
return at(index, resources).data();
}

inline void ArrayData::removeElement(size_t index, ResourceManager* resources) {
remove(at(index), resources);
remove(at(index, resources), resources);
}

ARDUINOJSON_END_PRIVATE_NAMESPACE
4 changes: 3 additions & 1 deletion src/ArduinoJson/Array/ElementProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
}

FORCE_INLINE VariantData* getData() const {
return VariantData::getElement(VariantAttorney::getData(upstream_), index_);
return VariantData::getElement(
VariantAttorney::getData(upstream_), index_,
VariantAttorney::getResourceManager(upstream_));
}

FORCE_INLINE VariantData* getOrCreateData() const {
Expand Down
8 changes: 4 additions & 4 deletions src/ArduinoJson/Array/JsonArray.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
FORCE_INLINE iterator begin() const {
if (!data_)
return iterator();
return iterator(data_->createIterator(), resources_);
return iterator(data_->createIterator(resources_), resources_);
}

// Returns an iterator following the last element of the array.
Expand Down Expand Up @@ -148,19 +148,19 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Returns the number of bytes occupied by the array.
// https://arduinojson.org/v6/api/jsonarray/memoryusage/
FORCE_INLINE size_t memoryUsage() const {
return data_ ? data_->memoryUsage() : 0;
return data_ ? data_->memoryUsage(resources_) : 0;
}

// Returns the depth (nesting level) of the array.
// https://arduinojson.org/v6/api/jsonarray/nesting/
FORCE_INLINE size_t nesting() const {
return detail::VariantData::nesting(collectionToVariant(data_));
return detail::VariantData::nesting(collectionToVariant(data_), resources_);
}

// Returns the number of elements in the array.
// https://arduinojson.org/v6/api/jsonarray/size/
FORCE_INLINE size_t size() const {
return data_ ? data_->size() : 0;
return data_ ? data_->size(resources_) : 0;
}

private:
Expand Down
12 changes: 6 additions & 6 deletions src/ArduinoJson/Array/JsonArrayConst.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
FORCE_INLINE iterator begin() const {
if (!data_)
return iterator();
return iterator(data_->createIterator(), resources_);
return iterator(data_->createIterator(resources_), resources_);
}

// Returns an iterator to the element following the last element of the array.
Expand All @@ -46,8 +46,8 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns the element at the specified index.
// https://arduinojson.org/v6/api/jsonarrayconst/subscript/
FORCE_INLINE JsonVariantConst operator[](size_t index) const {
return JsonVariantConst(detail::ArrayData::getElement(data_, index),
resources_);
return JsonVariantConst(
detail::ArrayData::getElement(data_, index, resources_), resources_);
}

operator JsonVariantConst() const {
Expand All @@ -69,19 +69,19 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns the number of bytes occupied by the array.
// https://arduinojson.org/v6/api/jsonarrayconst/memoryusage/
FORCE_INLINE size_t memoryUsage() const {
return data_ ? data_->memoryUsage() : 0;
return data_ ? data_->memoryUsage(resources_) : 0;
}

// Returns the depth (nesting level) of the array.
// https://arduinojson.org/v6/api/jsonarrayconst/nesting/
FORCE_INLINE size_t nesting() const {
return detail::VariantData::nesting(collectionToVariant(data_));
return detail::VariantData::nesting(collectionToVariant(data_), resources_);
}

// Returns the number of elements in the array.
// https://arduinojson.org/v6/api/jsonarrayconst/size/
FORCE_INLINE size_t size() const {
return data_ ? data_->size() : 0;
return data_ ? data_->size(resources_) : 0;
}

private:
Expand Down
4 changes: 2 additions & 2 deletions src/ArduinoJson/Array/JsonArrayIterator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class JsonArrayIterator {
}

JsonArrayIterator& operator++() {
iterator_.next();
iterator_.next(resources_);
return *this;
}

Expand Down Expand Up @@ -84,7 +84,7 @@ class JsonArrayConstIterator {
}

JsonArrayConstIterator& operator++() {
iterator_.next();
iterator_.next(resources_);
return *this;
}

Expand Down
20 changes: 9 additions & 11 deletions src/ArduinoJson/Collection/CollectionData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CollectionIterator {
public:
CollectionIterator() : slot_(nullptr) {}

void next();
void next(const ResourceManager* resources);

bool done() const {
return slot_ == nullptr;
Expand Down Expand Up @@ -70,8 +70,8 @@ class CollectionIterator {
};

class CollectionData {
VariantSlot* head_ = 0;
VariantSlot* tail_ = 0;
VariantId head_ = 0;
VariantId tail_ = 0;

public:
// Placement new
Expand All @@ -83,13 +83,13 @@ class CollectionData {

using iterator = CollectionIterator;

iterator createIterator() const {
return iterator(head_);
iterator createIterator(const ResourceManager* resources) const {
return iterator(resources->getVariant(head_));
}

size_t memoryUsage() const;
size_t size() const;
size_t nesting() const;
size_t memoryUsage(const ResourceManager*) const;
size_t size(const ResourceManager*) const;
size_t nesting(const ResourceManager*) const;

void clear(ResourceManager* resources);

Expand All @@ -99,8 +99,6 @@ class CollectionData {
collection->clear(resources);
}

void movePointers(ptrdiff_t variantDistance);

void remove(iterator it, ResourceManager* resources);

static void remove(CollectionData* collection, iterator it,
Expand All @@ -113,7 +111,7 @@ class CollectionData {
iterator addSlot(ResourceManager*);

private:
VariantSlot* getPreviousSlot(VariantSlot*) const;
VariantWithId getPreviousSlot(VariantSlot*, const ResourceManager*) const;
static void releaseSlot(VariantSlot*, ResourceManager*);
};

Expand Down
Loading

0 comments on commit 7c9af03

Please sign in to comment.