summaryrefslogtreecommitdiff
path: root/include/lib/ArduinoJson/Collection
diff options
context:
space:
mode:
Diffstat (limited to 'include/lib/ArduinoJson/Collection')
-rw-r--r--include/lib/ArduinoJson/Collection/CollectionData.hpp88
-rw-r--r--include/lib/ArduinoJson/Collection/CollectionImpl.hpp234
2 files changed, 322 insertions, 0 deletions
diff --git a/include/lib/ArduinoJson/Collection/CollectionData.hpp b/include/lib/ArduinoJson/Collection/CollectionData.hpp
new file mode 100644
index 0000000..d2bca45
--- /dev/null
+++ b/include/lib/ArduinoJson/Collection/CollectionData.hpp
@@ -0,0 +1,88 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Namespace.hpp>
+#include <ArduinoJson/Polyfills/assert.hpp>
+
+#include <stddef.h> // size_t
+
+namespace ARDUINOJSON_NAMESPACE {
+
+class MemoryPool;
+class VariantData;
+class VariantSlot;
+
+class CollectionData {
+ VariantSlot *_head;
+ VariantSlot *_tail;
+
+ public:
+ // Must be a POD!
+ // - no constructor
+ // - no destructor
+ // - no virtual
+ // - no inheritance
+
+ // Array only
+
+ VariantData *addElement(MemoryPool *pool);
+
+ VariantData *getElement(size_t index) const;
+
+ VariantData *getOrAddElement(size_t index, MemoryPool *pool);
+
+ void removeElement(size_t index);
+
+ bool equalsArray(const CollectionData &other) const;
+
+ // Object only
+
+ template <typename TAdaptedString>
+ VariantData *addMember(TAdaptedString key, MemoryPool *pool);
+
+ template <typename TAdaptedString>
+ VariantData *getMember(TAdaptedString key) const;
+
+ template <typename TAdaptedString>
+ VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool);
+
+ template <typename TAdaptedString>
+ void removeMember(TAdaptedString key) {
+ removeSlot(getSlot(key));
+ }
+
+ template <typename TAdaptedString>
+ bool containsKey(const TAdaptedString &key) const;
+
+ bool equalsObject(const CollectionData &other) const;
+
+ // Generic
+
+ void clear();
+ size_t memoryUsage() const;
+ size_t nesting() const;
+ size_t size() const;
+
+ VariantSlot *addSlot(MemoryPool *);
+ void removeSlot(VariantSlot *slot);
+
+ bool copyFrom(const CollectionData &src, MemoryPool *pool);
+
+ VariantSlot *head() const {
+ return _head;
+ }
+
+ void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance);
+
+ private:
+ VariantSlot *getSlot(size_t index) const;
+
+ template <typename TAdaptedString>
+ VariantSlot *getSlot(TAdaptedString key) const;
+
+ VariantSlot *getPreviousSlot(VariantSlot *) const;
+};
+} // namespace ARDUINOJSON_NAMESPACE
diff --git a/include/lib/ArduinoJson/Collection/CollectionImpl.hpp b/include/lib/ArduinoJson/Collection/CollectionImpl.hpp
new file mode 100644
index 0000000..49a24be
--- /dev/null
+++ b/include/lib/ArduinoJson/Collection/CollectionImpl.hpp
@@ -0,0 +1,234 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Collection/CollectionData.hpp>
+#include <ArduinoJson/Variant/VariantData.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+inline bool variantEquals(const VariantData* a, const VariantData* b) {
+ return variantCompare(a, b) == COMPARE_RESULT_EQUAL;
+}
+
+inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) {
+ VariantSlot* slot = pool->allocVariant();
+ if (!slot)
+ return 0;
+
+ if (_tail) {
+ _tail->setNextNotNull(slot);
+ _tail = slot;
+ } else {
+ _head = slot;
+ _tail = slot;
+ }
+
+ slot->clear();
+ return slot;
+}
+
+inline VariantData* CollectionData::addElement(MemoryPool* pool) {
+ return slotData(addSlot(pool));
+}
+
+template <typename TAdaptedString>
+inline VariantData* CollectionData::addMember(TAdaptedString key,
+ MemoryPool* pool) {
+ VariantSlot* slot = addSlot(pool);
+ if (!slotSetKey(slot, key, pool)) {
+ removeSlot(slot);
+ return 0;
+ }
+ return slot->data();
+}
+
+inline void CollectionData::clear() {
+ _head = 0;
+ _tail = 0;
+}
+
+template <typename TAdaptedString>
+inline bool CollectionData::containsKey(const TAdaptedString& key) const {
+ return getSlot(key) != 0;
+}
+
+inline bool CollectionData::copyFrom(const CollectionData& src,
+ MemoryPool* pool) {
+ clear();
+ for (VariantSlot* s = src._head; s; s = s->next()) {
+ VariantData* var;
+ if (s->key() != 0) {
+ if (s->ownsKey())
+ var = addMember(RamStringAdapter(s->key()), pool);
+ else
+ var = addMember(ConstRamStringAdapter(s->key()), pool);
+ } else {
+ var = addElement(pool);
+ }
+ if (!var)
+ return false;
+ if (!var->copyFrom(*s->data(), pool))
+ return false;
+ }
+ return true;
+}
+
+inline bool CollectionData::equalsObject(const CollectionData& other) const {
+ size_t count = 0;
+ for (VariantSlot* slot = _head; slot; slot = slot->next()) {
+ VariantData* v1 = slot->data();
+ VariantData* v2 = other.getMember(adaptString(slot->key()));
+ if (!variantEquals(v1, v2))
+ return false;
+ count++;
+ }
+ return count == other.size();
+}
+
+inline bool CollectionData::equalsArray(const CollectionData& other) const {
+ VariantSlot* s1 = _head;
+ VariantSlot* s2 = other._head;
+ for (;;) {
+ if (s1 == s2)
+ return true;
+ if (!s1 || !s2)
+ return false;
+ if (!variantEquals(s1->data(), s2->data()))
+ return false;
+ s1 = s1->next();
+ s2 = s2->next();
+ }
+}
+
+template <typename TAdaptedString>
+inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
+ VariantSlot* slot = _head;
+ while (slot) {
+ if (key.equals(slot->key()))
+ break;
+ slot = slot->next();
+ }
+ return slot;
+}
+
+inline VariantSlot* CollectionData::getSlot(size_t index) const {
+ if (!_head)
+ return 0;
+ return _head->next(index);
+}
+
+inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
+ VariantSlot* current = _head;
+ while (current) {
+ VariantSlot* next = current->next();
+ if (next == target)
+ return current;
+ current = next;
+ }
+ return 0;
+}
+
+template <typename TAdaptedString>
+inline VariantData* CollectionData::getMember(TAdaptedString key) const {
+ VariantSlot* slot = getSlot(key);
+ return slot ? slot->data() : 0;
+}
+
+template <typename TAdaptedString>
+inline VariantData* CollectionData::getOrAddMember(TAdaptedString key,
+ MemoryPool* pool) {
+ // ignore null key
+ if (key.isNull())
+ return 0;
+
+ // search a matching key
+ VariantSlot* slot = getSlot(key);
+ if (slot)
+ return slot->data();
+
+ return addMember(key, pool);
+}
+
+inline VariantData* CollectionData::getElement(size_t index) const {
+ VariantSlot* slot = getSlot(index);
+ return slot ? slot->data() : 0;
+}
+
+inline VariantData* CollectionData::getOrAddElement(size_t index,
+ MemoryPool* pool) {
+ VariantSlot* slot = _head;
+ while (slot && index > 0) {
+ slot = slot->next();
+ index--;
+ }
+ if (!slot)
+ index++;
+ while (index > 0) {
+ slot = addSlot(pool);
+ index--;
+ }
+ return slotData(slot);
+}
+
+inline void CollectionData::removeSlot(VariantSlot* slot) {
+ if (!slot)
+ return;
+ VariantSlot* prev = getPreviousSlot(slot);
+ VariantSlot* next = slot->next();
+ if (prev)
+ prev->setNext(next);
+ else
+ _head = next;
+ if (!next)
+ _tail = prev;
+}
+
+inline void CollectionData::removeElement(size_t index) {
+ removeSlot(getSlot(index));
+}
+
+inline size_t CollectionData::memoryUsage() const {
+ size_t total = 0;
+ for (VariantSlot* s = _head; s; s = s->next()) {
+ total += sizeof(VariantSlot) + s->data()->memoryUsage();
+ if (s->ownsKey())
+ total += strlen(s->key()) + 1;
+ }
+ return total;
+}
+
+inline size_t CollectionData::nesting() const {
+ size_t maxChildNesting = 0;
+ for (VariantSlot* s = _head; s; s = s->next()) {
+ size_t childNesting = s->data()->nesting();
+ if (childNesting > maxChildNesting)
+ maxChildNesting = childNesting;
+ }
+ return maxChildNesting + 1;
+}
+
+inline size_t CollectionData::size() const {
+ return slotSize(_head);
+}
+
+template <typename T>
+inline void movePointer(T*& p, ptrdiff_t offset) {
+ if (!p)
+ return;
+ p = reinterpret_cast<T*>(
+ reinterpret_cast<void*>(reinterpret_cast<char*>(p) + offset));
+ ARDUINOJSON_ASSERT(isAligned(p));
+}
+
+inline void CollectionData::movePointers(ptrdiff_t stringDistance,
+ ptrdiff_t variantDistance) {
+ movePointer(_head, variantDistance);
+ movePointer(_tail, variantDistance);
+ for (VariantSlot* slot = _head; slot; slot = slot->next())
+ slot->movePointers(stringDistance, variantDistance);
+}
+
+} // namespace ARDUINOJSON_NAMESPACE