diff options
author | Daniel Friesel <daniel.friesel@uos.de> | 2021-05-12 09:12:09 +0200 |
---|---|---|
committer | Daniel Friesel <daniel.friesel@uos.de> | 2021-05-12 09:12:09 +0200 |
commit | 39895a677e5d370824e702cfe90ebc67737b8482 (patch) | |
tree | ff5b4cc9e373d33a795d50d9333e05549bd9f2b8 /include/lib/ArduinoJson/Array | |
parent | 42e7fdf01c3a5701bb51e93ad6c650c3dbbc5450 (diff) |
import ArduinoJson 6.18.0
Diffstat (limited to 'include/lib/ArduinoJson/Array')
-rw-r--r-- | include/lib/ArduinoJson/Array/ArrayFunctions.hpp | 31 | ||||
-rw-r--r-- | include/lib/ArduinoJson/Array/ArrayImpl.hpp | 28 | ||||
-rw-r--r-- | include/lib/ArduinoJson/Array/ArrayIterator.hpp | 121 | ||||
-rw-r--r-- | include/lib/ArduinoJson/Array/ArrayRef.hpp | 205 | ||||
-rw-r--r-- | include/lib/ArduinoJson/Array/ArrayShortcuts.hpp | 49 | ||||
-rw-r--r-- | include/lib/ArduinoJson/Array/ElementProxy.hpp | 193 | ||||
-rw-r--r-- | include/lib/ArduinoJson/Array/Utilities.hpp | 133 |
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 |