summaryrefslogtreecommitdiff
path: root/include/lib/ArduinoJson/Collection/CollectionImpl.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/lib/ArduinoJson/Collection/CollectionImpl.hpp')
-rw-r--r--include/lib/ArduinoJson/Collection/CollectionImpl.hpp234
1 files changed, 234 insertions, 0 deletions
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