summaryrefslogtreecommitdiff
path: root/include/lib/ArduinoJson/Array
diff options
context:
space:
mode:
authorDaniel Friesel <daniel.friesel@uos.de>2021-05-12 09:12:09 +0200
committerDaniel Friesel <daniel.friesel@uos.de>2021-05-12 09:12:09 +0200
commit39895a677e5d370824e702cfe90ebc67737b8482 (patch)
treeff5b4cc9e373d33a795d50d9333e05549bd9f2b8 /include/lib/ArduinoJson/Array
parent42e7fdf01c3a5701bb51e93ad6c650c3dbbc5450 (diff)
import ArduinoJson 6.18.0
Diffstat (limited to 'include/lib/ArduinoJson/Array')
-rw-r--r--include/lib/ArduinoJson/Array/ArrayFunctions.hpp31
-rw-r--r--include/lib/ArduinoJson/Array/ArrayImpl.hpp28
-rw-r--r--include/lib/ArduinoJson/Array/ArrayIterator.hpp121
-rw-r--r--include/lib/ArduinoJson/Array/ArrayRef.hpp205
-rw-r--r--include/lib/ArduinoJson/Array/ArrayShortcuts.hpp49
-rw-r--r--include/lib/ArduinoJson/Array/ElementProxy.hpp193
-rw-r--r--include/lib/ArduinoJson/Array/Utilities.hpp133
7 files changed, 760 insertions, 0 deletions
diff --git a/include/lib/ArduinoJson/Array/ArrayFunctions.hpp b/include/lib/ArduinoJson/Array/ArrayFunctions.hpp
new file mode 100644
index 0000000..e7cdc4c
--- /dev/null
+++ b/include/lib/ArduinoJson/Array/ArrayFunctions.hpp
@@ -0,0 +1,31 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Collection/CollectionData.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) {
+ return arr ? arr->addElement(pool) : 0;
+}
+
+template <typename TVisitor>
+inline typename TVisitor::result_type arrayAccept(const CollectionData *arr,
+ TVisitor &visitor) {
+ if (arr)
+ return visitor.visitArray(*arr);
+ else
+ return visitor.visitNull();
+}
+
+inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) {
+ if (lhs == rhs)
+ return true;
+ if (!lhs || !rhs)
+ return false;
+ return lhs->equalsArray(*rhs);
+}
+} // namespace ARDUINOJSON_NAMESPACE
diff --git a/include/lib/ArduinoJson/Array/ArrayImpl.hpp b/include/lib/ArduinoJson/Array/ArrayImpl.hpp
new file mode 100644
index 0000000..ae06b20
--- /dev/null
+++ b/include/lib/ArduinoJson/Array/ArrayImpl.hpp
@@ -0,0 +1,28 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Array/ArrayRef.hpp>
+#include <ArduinoJson/Object/ObjectRef.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+template <typename TArray>
+inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const {
+ return impl()->addElement().template to<ArrayRef>();
+}
+
+template <typename TArray>
+inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const {
+ return impl()->addElement().template to<ObjectRef>();
+}
+
+template <typename TArray>
+inline ElementProxy<TArray> ArrayShortcuts<TArray>::operator[](
+ size_t index) const {
+ return ElementProxy<TArray>(*impl(), index);
+}
+
+} // namespace ARDUINOJSON_NAMESPACE
diff --git a/include/lib/ArduinoJson/Array/ArrayIterator.hpp b/include/lib/ArduinoJson/Array/ArrayIterator.hpp
new file mode 100644
index 0000000..fcacc6b
--- /dev/null
+++ b/include/lib/ArduinoJson/Array/ArrayIterator.hpp
@@ -0,0 +1,121 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Variant/SlotFunctions.hpp>
+#include <ArduinoJson/Variant/VariantRef.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+class VariantPtr {
+ public:
+ VariantPtr(MemoryPool *pool, VariantData *data) : _variant(pool, data) {}
+
+ VariantRef *operator->() {
+ return &_variant;
+ }
+
+ VariantRef &operator*() {
+ return _variant;
+ }
+
+ private:
+ VariantRef _variant;
+};
+
+class ArrayIterator {
+ public:
+ ArrayIterator() : _slot(0) {}
+ explicit ArrayIterator(MemoryPool *pool, VariantSlot *slot)
+ : _pool(pool), _slot(slot) {}
+
+ VariantRef operator*() const {
+ return VariantRef(_pool, _slot->data());
+ }
+ VariantPtr operator->() {
+ return VariantPtr(_pool, _slot->data());
+ }
+
+ bool operator==(const ArrayIterator &other) const {
+ return _slot == other._slot;
+ }
+
+ bool operator!=(const ArrayIterator &other) const {
+ return _slot != other._slot;
+ }
+
+ ArrayIterator &operator++() {
+ _slot = _slot->next();
+ return *this;
+ }
+
+ ArrayIterator &operator+=(size_t distance) {
+ _slot = _slot->next(distance);
+ return *this;
+ }
+
+ VariantSlot *internal() {
+ return _slot;
+ }
+
+ private:
+ MemoryPool *_pool;
+ VariantSlot *_slot;
+};
+
+class VariantConstPtr {
+ public:
+ VariantConstPtr(const VariantData *data) : _variant(data) {}
+
+ VariantConstRef *operator->() {
+ return &_variant;
+ }
+
+ VariantConstRef &operator*() {
+ return _variant;
+ }
+
+ private:
+ VariantConstRef _variant;
+};
+
+class ArrayConstRefIterator {
+ public:
+ ArrayConstRefIterator() : _slot(0) {}
+ explicit ArrayConstRefIterator(const VariantSlot *slot) : _slot(slot) {}
+
+ VariantConstRef operator*() const {
+ return VariantConstRef(_slot->data());
+ }
+ VariantConstPtr operator->() {
+ return VariantConstPtr(_slot->data());
+ }
+
+ bool operator==(const ArrayConstRefIterator &other) const {
+ return _slot == other._slot;
+ }
+
+ bool operator!=(const ArrayConstRefIterator &other) const {
+ return _slot != other._slot;
+ }
+
+ ArrayConstRefIterator &operator++() {
+ _slot = _slot->next();
+ return *this;
+ }
+
+ ArrayConstRefIterator &operator+=(size_t distance) {
+ _slot = _slot->next(distance);
+ return *this;
+ }
+
+ const VariantSlot *internal() {
+ return _slot;
+ }
+
+ private:
+ const VariantSlot *_slot;
+};
+} // namespace ARDUINOJSON_NAMESPACE
diff --git a/include/lib/ArduinoJson/Array/ArrayRef.hpp b/include/lib/ArduinoJson/Array/ArrayRef.hpp
new file mode 100644
index 0000000..a991db0
--- /dev/null
+++ b/include/lib/ArduinoJson/Array/ArrayRef.hpp
@@ -0,0 +1,205 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Array/ArrayFunctions.hpp>
+#include <ArduinoJson/Array/ArrayIterator.hpp>
+#include <ArduinoJson/Variant/VariantData.hpp>
+
+// Returns the size (in bytes) of an array with n elements.
+// Can be very handy to determine the size of a StaticMemoryPool.
+#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
+ ((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
+
+namespace ARDUINOJSON_NAMESPACE {
+
+class ObjectRef;
+template <typename>
+class ElementProxy;
+
+template <typename TData>
+class ArrayRefBase {
+ public:
+ operator VariantConstRef() const {
+ const void* data = _data; // prevent warning cast-align
+ return VariantConstRef(reinterpret_cast<const VariantData*>(data));
+ }
+
+ template <typename TVisitor>
+ FORCE_INLINE typename TVisitor::result_type accept(TVisitor& visitor) const {
+ return arrayAccept(_data, visitor);
+ }
+
+ FORCE_INLINE bool isNull() const {
+ return _data == 0;
+ }
+
+ FORCE_INLINE operator bool() const {
+ return _data != 0;
+ }
+
+ FORCE_INLINE size_t memoryUsage() const {
+ return _data ? _data->memoryUsage() : 0;
+ }
+
+ FORCE_INLINE size_t nesting() const {
+ return _data ? _data->nesting() : 0;
+ }
+
+ FORCE_INLINE size_t size() const {
+ return _data ? _data->size() : 0;
+ }
+
+ protected:
+ ArrayRefBase(TData* data) : _data(data) {}
+ TData* _data;
+};
+
+class ArrayConstRef : public ArrayRefBase<const CollectionData>,
+ public Visitable {
+ friend class ArrayRef;
+ typedef ArrayRefBase<const CollectionData> base_type;
+
+ public:
+ typedef ArrayConstRefIterator iterator;
+
+ FORCE_INLINE iterator begin() const {
+ if (!_data)
+ return iterator();
+ return iterator(_data->head());
+ }
+
+ FORCE_INLINE iterator end() const {
+ return iterator();
+ }
+
+ FORCE_INLINE ArrayConstRef() : base_type(0) {}
+ FORCE_INLINE ArrayConstRef(const CollectionData* data) : base_type(data) {}
+
+ FORCE_INLINE bool operator==(ArrayConstRef rhs) const {
+ return arrayEquals(_data, rhs._data);
+ }
+
+ FORCE_INLINE VariantConstRef operator[](size_t index) const {
+ return getElement(index);
+ }
+
+ FORCE_INLINE VariantConstRef getElement(size_t index) const {
+ return VariantConstRef(_data ? _data->getElement(index) : 0);
+ }
+};
+
+class ArrayRef : public ArrayRefBase<CollectionData>,
+ public ArrayShortcuts<ArrayRef>,
+ public Visitable {
+ typedef ArrayRefBase<CollectionData> base_type;
+
+ public:
+ typedef ArrayIterator iterator;
+
+ FORCE_INLINE ArrayRef() : base_type(0), _pool(0) {}
+ FORCE_INLINE ArrayRef(MemoryPool* pool, CollectionData* data)
+ : base_type(data), _pool(pool) {}
+
+ operator VariantRef() {
+ void* data = _data; // prevent warning cast-align
+ return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
+ }
+
+ operator ArrayConstRef() const {
+ return ArrayConstRef(_data);
+ }
+
+ VariantRef addElement() const {
+ return VariantRef(_pool, arrayAdd(_data, _pool));
+ }
+
+ FORCE_INLINE iterator begin() const {
+ if (!_data)
+ return iterator();
+ return iterator(_pool, _data->head());
+ }
+
+ FORCE_INLINE iterator end() const {
+ return iterator();
+ }
+
+ // Copy a ArrayRef
+ FORCE_INLINE bool set(ArrayConstRef src) const {
+ if (!_data || !src._data)
+ return false;
+ return _data->copyFrom(*src._data, _pool);
+ }
+
+ FORCE_INLINE bool operator==(ArrayRef rhs) const {
+ return arrayEquals(_data, rhs._data);
+ }
+
+ // Internal use
+ FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
+ return VariantRef(_pool, _data ? _data->getOrAddElement(index, _pool) : 0);
+ }
+
+ // Gets the value at the specified index.
+ FORCE_INLINE VariantRef getElement(size_t index) const {
+ return VariantRef(_pool, _data ? _data->getElement(index) : 0);
+ }
+
+ // Removes element at specified position.
+ FORCE_INLINE void remove(iterator it) const {
+ if (!_data)
+ return;
+ _data->removeSlot(it.internal());
+ }
+
+ // Removes element at specified index.
+ FORCE_INLINE void remove(size_t index) const {
+ if (!_data)
+ return;
+ _data->removeElement(index);
+ }
+
+ private:
+ MemoryPool* _pool;
+};
+
+template <>
+struct Converter<ArrayConstRef> {
+ static bool toJson(VariantConstRef src, VariantRef dst) {
+ return variantCopyFrom(getData(dst), getData(src), getPool(dst));
+ }
+
+ static ArrayConstRef fromJson(VariantConstRef src) {
+ return ArrayConstRef(variantAsArray(getData(src)));
+ }
+
+ static bool checkJson(VariantConstRef src) {
+ const VariantData* data = getData(src);
+ return data && data->isArray();
+ }
+};
+
+template <>
+struct Converter<ArrayRef> {
+ static bool toJson(VariantConstRef src, VariantRef dst) {
+ return variantCopyFrom(getData(dst), getData(src), getPool(dst));
+ }
+
+ static ArrayRef fromJson(VariantRef src) {
+ VariantData* data = getData(src);
+ MemoryPool* pool = getPool(src);
+ return ArrayRef(pool, data != 0 ? data->asArray() : 0);
+ }
+
+ static bool checkJson(VariantConstRef) {
+ return false;
+ }
+
+ static bool checkJson(VariantRef src) {
+ VariantData* data = getData(src);
+ return data && data->isArray();
+ }
+};
+} // namespace ARDUINOJSON_NAMESPACE
diff --git a/include/lib/ArduinoJson/Array/ArrayShortcuts.hpp b/include/lib/ArduinoJson/Array/ArrayShortcuts.hpp
new file mode 100644
index 0000000..fd26d04
--- /dev/null
+++ b/include/lib/ArduinoJson/Array/ArrayShortcuts.hpp
@@ -0,0 +1,49 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Polyfills/attributes.hpp>
+#include <ArduinoJson/Polyfills/type_traits.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+// Forward declarations.
+class ArrayRef;
+class ObjectRef;
+template <typename>
+class ElementProxy;
+
+template <typename TArray>
+class ArrayShortcuts {
+ public:
+ // Returns the element at specified index if the variant is an array.
+ FORCE_INLINE ElementProxy<TArray> operator[](size_t index) const;
+
+ FORCE_INLINE ObjectRef createNestedObject() const;
+
+ FORCE_INLINE ArrayRef createNestedArray() const;
+
+ // Adds the specified value at the end of the array.
+ //
+ // bool add(TValue);
+ // TValue = bool, long, int, short, float, double, serialized, VariantRef,
+ // std::string, String, ObjectRef
+ template <typename T>
+ FORCE_INLINE bool add(const T &value) const {
+ return impl()->addElement().set(value);
+ }
+ //
+ // bool add(TValue);
+ // TValue = char*, const char*, const __FlashStringHelper*
+ template <typename T>
+ FORCE_INLINE bool add(T *value) const {
+ return impl()->addElement().set(value);
+ }
+
+ private:
+ const TArray *impl() const {
+ return static_cast<const TArray *>(this);
+ }
+};
+} // namespace ARDUINOJSON_NAMESPACE
diff --git a/include/lib/ArduinoJson/Array/ElementProxy.hpp b/include/lib/ArduinoJson/Array/ElementProxy.hpp
new file mode 100644
index 0000000..c6062e4
--- /dev/null
+++ b/include/lib/ArduinoJson/Array/ElementProxy.hpp
@@ -0,0 +1,193 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Configuration.hpp>
+#include <ArduinoJson/Variant/VariantOperators.hpp>
+#include <ArduinoJson/Variant/VariantShortcuts.hpp>
+#include <ArduinoJson/Variant/VariantTo.hpp>
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4522)
+#endif
+
+namespace ARDUINOJSON_NAMESPACE {
+
+template <typename TArray>
+class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
+ public VariantShortcuts<ElementProxy<TArray> >,
+ public Visitable,
+ public VariantTag {
+ typedef ElementProxy<TArray> this_type;
+
+ public:
+ typedef VariantRef variant_type;
+
+ FORCE_INLINE ElementProxy(TArray array, size_t index)
+ : _array(array), _index(index) {}
+
+ FORCE_INLINE ElementProxy(const ElementProxy& src)
+ : _array(src._array), _index(src._index) {}
+
+ FORCE_INLINE this_type& operator=(const this_type& src) {
+ getOrAddUpstreamElement().set(src.as<VariantConstRef>());
+ return *this;
+ }
+
+ // Replaces the value
+ //
+ // operator=(const TValue&)
+ // TValue = bool, long, int, short, float, double, serialized, VariantRef,
+ // std::string, String, ArrayRef, ObjectRef
+ template <typename T>
+ FORCE_INLINE this_type& operator=(const T& src) {
+ getOrAddUpstreamElement().set(src);
+ return *this;
+ }
+ //
+ // operator=(TValue)
+ // TValue = char*, const char*, const __FlashStringHelper*
+ template <typename T>
+ FORCE_INLINE this_type& operator=(T* src) {
+ getOrAddUpstreamElement().set(src);
+ return *this;
+ }
+
+ FORCE_INLINE void clear() const {
+ getUpstreamElement().clear();
+ }
+
+ FORCE_INLINE bool isNull() const {
+ return getUpstreamElement().isNull();
+ }
+
+ template <typename T>
+ FORCE_INLINE typename enable_if<!is_same<T, char*>::value, T>::type as()
+ const {
+ return getUpstreamElement().template as<T>();
+ }
+
+ template <typename T>
+ FORCE_INLINE typename enable_if<is_same<T, char*>::value, const char*>::type
+ ARDUINOJSON_DEPRECATED("Replace as<char*>() with as<const char*>()")
+ as() const {
+ return as<const char*>();
+ }
+
+ template <typename T>
+ FORCE_INLINE operator T() const {
+ return getUpstreamElement();
+ }
+
+ template <typename T>
+ FORCE_INLINE bool is() const {
+ return getUpstreamElement().template is<T>();
+ }
+
+ template <typename T>
+ FORCE_INLINE typename VariantTo<T>::type to() const {
+ return getOrAddUpstreamElement().template to<T>();
+ }
+
+ // Replaces the value
+ //
+ // bool set(const TValue&)
+ // TValue = bool, long, int, short, float, double, serialized, VariantRef,
+ // std::string, String, ArrayRef, ObjectRef
+ template <typename TValue>
+ FORCE_INLINE bool set(const TValue& value) const {
+ return getOrAddUpstreamElement().set(value);
+ }
+ //
+ // bool set(TValue)
+ // TValue = char*, const char*, const __FlashStringHelper*
+ template <typename TValue>
+ FORCE_INLINE bool set(TValue* value) const {
+ return getOrAddUpstreamElement().set(value);
+ }
+
+ template <typename TVisitor>
+ typename TVisitor::result_type accept(TVisitor& visitor) const {
+ return getUpstreamElement().accept(visitor);
+ }
+
+ FORCE_INLINE size_t size() const {
+ return getUpstreamElement().size();
+ }
+
+ template <typename TNestedKey>
+ VariantRef getMember(TNestedKey* key) const {
+ return getUpstreamElement().getMember(key);
+ }
+
+ template <typename TNestedKey>
+ VariantRef getMember(const TNestedKey& key) const {
+ return getUpstreamElement().getMember(key);
+ }
+
+ template <typename TNestedKey>
+ VariantRef getOrAddMember(TNestedKey* key) const {
+ return getOrAddUpstreamElement().getOrAddMember(key);
+ }
+
+ template <typename TNestedKey>
+ VariantRef getOrAddMember(const TNestedKey& key) const {
+ return getOrAddUpstreamElement().getOrAddMember(key);
+ }
+
+ VariantRef addElement() const {
+ return getOrAddUpstreamElement().addElement();
+ }
+
+ VariantRef getElement(size_t index) const {
+ return getOrAddUpstreamElement().getElement(index);
+ }
+
+ VariantRef getOrAddElement(size_t index) const {
+ return getOrAddUpstreamElement().getOrAddElement(index);
+ }
+
+ FORCE_INLINE void remove(size_t index) const {
+ getUpstreamElement().remove(index);
+ }
+ // remove(char*) const
+ // remove(const char*) const
+ // remove(const __FlashStringHelper*) const
+ template <typename TChar>
+ FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
+ TChar* key) const {
+ getUpstreamElement().remove(key);
+ }
+ // remove(const std::string&) const
+ // remove(const String&) const
+ template <typename TString>
+ FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
+ const TString& key) const {
+ getUpstreamElement().remove(key);
+ }
+
+ private:
+ FORCE_INLINE VariantRef getUpstreamElement() const {
+ return _array.getElement(_index);
+ }
+
+ FORCE_INLINE VariantRef getOrAddUpstreamElement() const {
+ return _array.getOrAddElement(_index);
+ }
+
+ friend bool convertToJson(const this_type& src, VariantRef dst) {
+ return dst.set(src.getUpstreamElement());
+ }
+
+ TArray _array;
+ const size_t _index;
+};
+
+} // namespace ARDUINOJSON_NAMESPACE
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
diff --git a/include/lib/ArduinoJson/Array/Utilities.hpp b/include/lib/ArduinoJson/Array/Utilities.hpp
new file mode 100644
index 0000000..619b91d
--- /dev/null
+++ b/include/lib/ArduinoJson/Array/Utilities.hpp
@@ -0,0 +1,133 @@
+// ArduinoJson - https://arduinojson.org
+// Copyright Benoit Blanchon 2014-2021
+// MIT License
+
+#pragma once
+
+#include <ArduinoJson/Array/ArrayRef.hpp>
+#include <ArduinoJson/Document/JsonDocument.hpp>
+#include <ArduinoJson/Variant/Visitor.hpp>
+
+namespace ARDUINOJSON_NAMESPACE {
+
+// Copy a 1D array to a JsonArray
+template <typename T, size_t N, typename TDestination>
+inline typename enable_if<!is_array<T>::value &&
+ !is_base_of<JsonDocument, TDestination>::value,
+ bool>::type
+copyArray(T (&src)[N], const TDestination& dst) {
+ return copyArray(src, N, dst);
+}
+
+// Copy a 1D array to a JsonDocument
+template <typename T, size_t N>
+inline bool copyArray(T (&src)[N], JsonDocument& dst) {
+ return copyArray(src, dst.to<ArrayRef>());
+}
+
+// Copy a 1D array to a JsonArray
+template <typename T, typename TDestination>
+inline typename enable_if<!is_array<T>::value &&
+ !is_base_of<JsonDocument, TDestination>::value,
+ bool>::type
+copyArray(T* src, size_t len, const TDestination& dst) {
+ bool ok = true;
+ for (size_t i = 0; i < len; i++) {
+ ok &= dst.add(src[i]);
+ }
+ return ok;
+}
+
+// Copy a 1D array to a JsonDocument
+template <typename T>
+inline bool copyArray(T* src, size_t len, JsonDocument& dst) {
+ return copyArray(src, len, dst.to<ArrayRef>());
+}
+
+// Copy a 2D array to a JsonArray
+template <typename T, size_t N1, size_t N2, typename TDestination>
+inline typename enable_if<!is_base_of<JsonDocument, TDestination>::value,
+ bool>::type
+copyArray(T (&src)[N1][N2], const TDestination& dst) {
+ bool ok = true;
+ for (size_t i = 0; i < N1; i++) {
+ ArrayRef nestedArray = dst.createNestedArray();
+ for (size_t j = 0; j < N2; j++) {
+ ok &= nestedArray.add(src[i][j]);
+ }
+ }
+ return ok;
+}
+
+// Copy a 2D array to a JsonDocument
+template <typename T, size_t N1, size_t N2>
+inline bool copyArray(T (&src)[N1][N2], JsonDocument& dst) {
+ return copyArray(src, dst.to<ArrayRef>());
+}
+
+template <typename T>
+class ArrayCopier1D : public Visitor<size_t> {
+ public:
+ ArrayCopier1D(T* destination, size_t capacity)
+ : _destination(destination), _capacity(capacity) {}
+
+ size_t visitArray(const CollectionData& array) {
+ size_t size = 0;
+ VariantSlot* slot = array.head();
+
+ while (slot != 0 && size < _capacity) {
+ _destination[size++] =
+ Converter<T>::fromJson(VariantConstRef(slot->data()));
+ slot = slot->next();
+ }
+ return size;
+ }
+
+ private:
+ T* _destination;
+ size_t _capacity;
+};
+
+template <typename T, size_t N1, size_t N2>
+class ArrayCopier2D : public Visitor<void> {
+ public:
+ ArrayCopier2D(T (*destination)[N1][N2]) : _destination(destination) {}
+
+ void visitArray(const CollectionData& array) {
+ VariantSlot* slot = array.head();
+ size_t n = 0;
+ while (slot != 0 && n < N1) {
+ ArrayCopier1D<T> copier((*_destination)[n++], N2);
+ variantAccept(slot->data(), copier);
+ slot = slot->next();
+ }
+ }
+
+ private:
+ T (*_destination)[N1][N2];
+ size_t _capacity1, _capacity2;
+};
+
+// Copy a JsonArray to a 1D array
+template <typename TSource, typename T, size_t N>
+inline typename enable_if<!is_array<T>::value, size_t>::type copyArray(
+ const TSource& src, T (&dst)[N]) {
+ return copyArray(src, dst, N);
+}
+
+// Copy a JsonArray to a 1D array
+template <typename TSource, typename T>
+inline size_t copyArray(const TSource& src, T* dst, size_t len) {
+ ArrayCopier1D<T> copier(dst, len);
+
+ return src.accept(copier);
+}
+
+// Copy a JsonArray to a 2D array
+template <typename TSource, typename T, size_t N1, size_t N2>
+inline void copyArray(const TSource& src, T (&dst)[N1][N2]) {
+ ArrayCopier2D<T, N1, N2> copier(&dst);
+ src.accept(copier);
+}
+
+} // namespace ARDUINOJSON_NAMESPACE