diff options
Diffstat (limited to 'include/lib/ArduinoJson/Document')
4 files changed, 593 insertions, 0 deletions
diff --git a/include/lib/ArduinoJson/Document/BasicJsonDocument.hpp b/include/lib/ArduinoJson/Document/BasicJsonDocument.hpp new file mode 100644 index 0000000..5c85d8a --- /dev/null +++ b/include/lib/ArduinoJson/Document/BasicJsonDocument.hpp @@ -0,0 +1,164 @@ +// ArduinoJson - https://arduinojson.org +// Copyright Benoit Blanchon 2014-2021 +// MIT License + +#pragma once + +#include <ArduinoJson/Document/JsonDocument.hpp> + +namespace ARDUINOJSON_NAMESPACE { + +// Helper to implement the "base-from-member" idiom +// (we need to store the allocator before constructing JsonDocument) +template <typename TAllocator> +class AllocatorOwner { + public: + AllocatorOwner() {} + AllocatorOwner(const AllocatorOwner& src) : _allocator(src._allocator) {} + AllocatorOwner(TAllocator a) : _allocator(a) {} + + void* allocate(size_t size) { + return _allocator.allocate(size); + } + + void deallocate(void* ptr) { + if (ptr) + _allocator.deallocate(ptr); + } + + void* reallocate(void* ptr, size_t new_size) { + return _allocator.reallocate(ptr, new_size); + } + + TAllocator& allocator() { + return _allocator; + } + + private: + TAllocator _allocator; +}; + +template <typename TAllocator> +class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument { + public: + explicit BasicJsonDocument(size_t capa, TAllocator alloc = TAllocator()) + : AllocatorOwner<TAllocator>(alloc), JsonDocument(allocPool(capa)) {} + + // Copy-constructor + BasicJsonDocument(const BasicJsonDocument& src) + : AllocatorOwner<TAllocator>(src), JsonDocument() { + copyAssignFrom(src); + } + + // Move-constructor +#if ARDUINOJSON_HAS_RVALUE_REFERENCES + BasicJsonDocument(BasicJsonDocument&& src) : AllocatorOwner<TAllocator>(src) { + moveAssignFrom(src); + } +#endif + + BasicJsonDocument(const JsonDocument& src) { + copyAssignFrom(src); + } + + // Construct from variant, array, or object + template <typename T> + BasicJsonDocument( + const T& src, + typename enable_if< + is_same<T, VariantRef>::value || is_same<T, VariantConstRef>::value || + is_same<T, ArrayRef>::value || is_same<T, ArrayConstRef>::value || + is_same<T, ObjectRef>::value || + is_same<T, ObjectConstRef>::value>::type* = 0) + : JsonDocument(allocPool(src.memoryUsage())) { + set(src); + } + + // disambiguate + BasicJsonDocument(VariantRef src) + : JsonDocument(allocPool(src.memoryUsage())) { + set(src); + } + + ~BasicJsonDocument() { + freePool(); + } + + BasicJsonDocument& operator=(const BasicJsonDocument& src) { + copyAssignFrom(src); + return *this; + } + +#if ARDUINOJSON_HAS_RVALUE_REFERENCES + BasicJsonDocument& operator=(BasicJsonDocument&& src) { + moveAssignFrom(src); + return *this; + } +#endif + + template <typename T> + BasicJsonDocument& operator=(const T& src) { + reallocPoolIfTooSmall(src.memoryUsage()); + set(src); + return *this; + } + + void shrinkToFit() { + ptrdiff_t bytes_reclaimed = _pool.squash(); + if (bytes_reclaimed == 0) + return; + + void* old_ptr = _pool.buffer(); + void* new_ptr = this->reallocate(old_ptr, _pool.capacity()); + + ptrdiff_t ptr_offset = + static_cast<char*>(new_ptr) - static_cast<char*>(old_ptr); + + _pool.movePointers(ptr_offset); + _data.movePointers(ptr_offset, ptr_offset - bytes_reclaimed); + } + + bool garbageCollect() { + // make a temporary clone and move assign + BasicJsonDocument tmp(*this); + if (!tmp.capacity()) + return false; + tmp.set(*this); + moveAssignFrom(tmp); + return true; + } + + using AllocatorOwner<TAllocator>::allocator; + + private: + MemoryPool allocPool(size_t requiredSize) { + size_t capa = addPadding(requiredSize); + return MemoryPool(reinterpret_cast<char*>(this->allocate(capa)), capa); + } + + void reallocPoolIfTooSmall(size_t requiredSize) { + if (requiredSize <= capacity()) + return; + freePool(); + replacePool(allocPool(addPadding(requiredSize))); + } + + void freePool() { + this->deallocate(memoryPool().buffer()); + } + + void copyAssignFrom(const JsonDocument& src) { + reallocPoolIfTooSmall(src.capacity()); + set(src); + } + + void moveAssignFrom(BasicJsonDocument& src) { + freePool(); + _data = src._data; + _pool = src._pool; + src._data.setNull(); + src._pool = MemoryPool(0, 0); + } +}; + +} // namespace ARDUINOJSON_NAMESPACE diff --git a/include/lib/ArduinoJson/Document/DynamicJsonDocument.hpp b/include/lib/ArduinoJson/Document/DynamicJsonDocument.hpp new file mode 100644 index 0000000..de6f411 --- /dev/null +++ b/include/lib/ArduinoJson/Document/DynamicJsonDocument.hpp @@ -0,0 +1,29 @@ +// ArduinoJson - https://arduinojson.org +// Copyright Benoit Blanchon 2014-2021 +// MIT License + +#pragma once + +#include <ArduinoJson/Document/BasicJsonDocument.hpp> + +#include <stdlib.h> // malloc, free + +namespace ARDUINOJSON_NAMESPACE { + +struct DefaultAllocator { + void* allocate(size_t size) { + return malloc(size); + } + + void deallocate(void* ptr) { + free(ptr); + } + + void* reallocate(void* ptr, size_t new_size) { + return realloc(ptr, new_size); + } +}; + +typedef BasicJsonDocument<DefaultAllocator> DynamicJsonDocument; + +} // namespace ARDUINOJSON_NAMESPACE diff --git a/include/lib/ArduinoJson/Document/JsonDocument.hpp b/include/lib/ArduinoJson/Document/JsonDocument.hpp new file mode 100644 index 0000000..d67d934 --- /dev/null +++ b/include/lib/ArduinoJson/Document/JsonDocument.hpp @@ -0,0 +1,344 @@ +// ArduinoJson - https://arduinojson.org +// Copyright Benoit Blanchon 2014-2021 +// MIT License + +#pragma once + +#include <ArduinoJson/Array/ElementProxy.hpp> +#include <ArduinoJson/Memory/MemoryPool.hpp> +#include <ArduinoJson/Object/MemberProxy.hpp> +#include <ArduinoJson/Object/ObjectRef.hpp> +#include <ArduinoJson/Variant/VariantRef.hpp> +#include <ArduinoJson/Variant/VariantTo.hpp> + +namespace ARDUINOJSON_NAMESPACE { + +class JsonDocument : public Visitable { + public: + template <typename TVisitor> + typename TVisitor::result_type accept(TVisitor& visitor) const { + return getVariant().accept(visitor); + } + + template <typename T> + T as() { + return getVariant().template as<T>(); + } + + template <typename T> + T as() const { + return getVariant().template as<T>(); + } + + void clear() { + _pool.clear(); + _data.setNull(); + } + + template <typename T> + bool is() { + return getVariant().template is<T>(); + } + + template <typename T> + bool is() const { + return getVariant().template is<T>(); + } + + bool isNull() const { + return getVariant().isNull(); + } + + size_t memoryUsage() const { + return _pool.size(); + } + + bool overflowed() const { + return _pool.overflowed(); + } + + size_t nesting() const { + return _data.nesting(); + } + + size_t capacity() const { + return _pool.capacity(); + } + + size_t size() const { + return _data.size(); + } + + bool set(const JsonDocument& src) { + return to<VariantRef>().set(src.as<VariantConstRef>()); + } + + template <typename T> + typename enable_if<!is_base_of<JsonDocument, T>::value, bool>::type set( + const T& src) { + return to<VariantRef>().set(src); + } + + template <typename T> + typename VariantTo<T>::type to() { + clear(); + return getVariant().template to<T>(); + } + + // for internal use only + MemoryPool& memoryPool() { + return _pool; + } + + // for internal use only + VariantData& data() { + return _data; + } + + ArrayRef createNestedArray() { + return addElement().to<ArrayRef>(); + } + + // createNestedArray(char*) + // createNestedArray(const char*) + // createNestedArray(const __FlashStringHelper*) + template <typename TChar> + ArrayRef createNestedArray(TChar* key) { + return getOrAddMember(key).template to<ArrayRef>(); + } + + // createNestedArray(const std::string&) + // createNestedArray(const String&) + template <typename TString> + ArrayRef createNestedArray(const TString& key) { + return getOrAddMember(key).template to<ArrayRef>(); + } + + ObjectRef createNestedObject() { + return addElement().to<ObjectRef>(); + } + + // createNestedObject(char*) + // createNestedObject(const char*) + // createNestedObject(const __FlashStringHelper*) + template <typename TChar> + ObjectRef createNestedObject(TChar* key) { + return getOrAddMember(key).template to<ObjectRef>(); + } + + // createNestedObject(const std::string&) + // createNestedObject(const String&) + template <typename TString> + ObjectRef createNestedObject(const TString& key) { + return getOrAddMember(key).template to<ObjectRef>(); + } + + // containsKey(char*) const + // containsKey(const char*) const + // containsKey(const __FlashStringHelper*) const + template <typename TChar> + bool containsKey(TChar* key) const { + return !getMember(key).isUndefined(); + } + + // containsKey(const std::string&) const + // containsKey(const String&) const + template <typename TString> + bool containsKey(const TString& key) const { + return !getMember(key).isUndefined(); + } + + // operator[](const std::string&) + // operator[](const String&) + template <typename TString> + FORCE_INLINE typename enable_if<IsString<TString>::value, + MemberProxy<JsonDocument&, TString> >::type + operator[](const TString& key) { + return MemberProxy<JsonDocument&, TString>(*this, key); + } + + // operator[](char*) + // operator[](const char*) + // operator[](const __FlashStringHelper*) + template <typename TChar> + FORCE_INLINE typename enable_if<IsString<TChar*>::value, + MemberProxy<JsonDocument&, TChar*> >::type + operator[](TChar* key) { + return MemberProxy<JsonDocument&, TChar*>(*this, key); + } + + // operator[](const std::string&) const + // operator[](const String&) const + template <typename TString> + FORCE_INLINE + typename enable_if<IsString<TString>::value, VariantConstRef>::type + operator[](const TString& key) const { + return getMember(key); + } + + // operator[](char*) const + // operator[](const char*) const + // operator[](const __FlashStringHelper*) const + template <typename TChar> + FORCE_INLINE + typename enable_if<IsString<TChar*>::value, VariantConstRef>::type + operator[](TChar* key) const { + return getMember(key); + } + + FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) { + return ElementProxy<JsonDocument&>(*this, index); + } + + FORCE_INLINE VariantConstRef operator[](size_t index) const { + return getElement(index); + } + + FORCE_INLINE VariantRef getElement(size_t index) { + return VariantRef(&_pool, _data.getElement(index)); + } + + FORCE_INLINE VariantConstRef getElement(size_t index) const { + return VariantConstRef(_data.getElement(index)); + } + + FORCE_INLINE VariantRef getOrAddElement(size_t index) { + return VariantRef(&_pool, _data.getOrAddElement(index, &_pool)); + } + + // JsonVariantConst getMember(char*) const + // JsonVariantConst getMember(const char*) const + // JsonVariantConst getMember(const __FlashStringHelper*) const + template <typename TChar> + FORCE_INLINE VariantConstRef getMember(TChar* key) const { + return VariantConstRef(_data.getMember(adaptString(key))); + } + + // JsonVariantConst getMember(const std::string&) const + // JsonVariantConst getMember(const String&) const + template <typename TString> + FORCE_INLINE + typename enable_if<IsString<TString>::value, VariantConstRef>::type + getMember(const TString& key) const { + return VariantConstRef(_data.getMember(adaptString(key))); + } + + // JsonVariant getMember(char*) + // JsonVariant getMember(const char*) + // JsonVariant getMember(const __FlashStringHelper*) + template <typename TChar> + FORCE_INLINE VariantRef getMember(TChar* key) { + return VariantRef(&_pool, _data.getMember(adaptString(key))); + } + + // JsonVariant getMember(const std::string&) + // JsonVariant getMember(const String&) + template <typename TString> + FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type + getMember(const TString& key) { + return VariantRef(&_pool, _data.getMember(adaptString(key))); + } + + // getOrAddMember(char*) + // getOrAddMember(const char*) + // getOrAddMember(const __FlashStringHelper*) + template <typename TChar> + FORCE_INLINE VariantRef getOrAddMember(TChar* key) { + return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool)); + } + + // getOrAddMember(const std::string&) + // getOrAddMember(const String&) + template <typename TString> + FORCE_INLINE VariantRef getOrAddMember(const TString& key) { + return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool)); + } + + FORCE_INLINE VariantRef addElement() { + return VariantRef(&_pool, _data.addElement(&_pool)); + } + + template <typename TValue> + FORCE_INLINE bool add(const TValue& value) { + return addElement().set(value); + } + + // add(char*) const + // add(const char*) const + // add(const __FlashStringHelper*) const + template <typename TChar> + FORCE_INLINE bool add(TChar* value) { + return addElement().set(value); + } + + FORCE_INLINE void remove(size_t index) { + _data.remove(index); + } + // remove(char*) + // remove(const char*) + // remove(const __FlashStringHelper*) + template <typename TChar> + FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove( + TChar* key) { + _data.remove(adaptString(key)); + } + // remove(const std::string&) + // remove(const String&) + template <typename TString> + FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove( + const TString& key) { + _data.remove(adaptString(key)); + } + + FORCE_INLINE operator VariantConstRef() const { + return VariantConstRef(&_data); + } + + bool operator==(VariantConstRef rhs) const { + return getVariant() == rhs; + } + + bool operator!=(VariantConstRef rhs) const { + return getVariant() != rhs; + } + + protected: + JsonDocument() : _pool(0, 0) { + _data.setNull(); + } + + JsonDocument(MemoryPool pool) : _pool(pool) { + _data.setNull(); + } + + JsonDocument(char* buf, size_t capa) : _pool(buf, capa) { + _data.setNull(); + } + + ~JsonDocument() {} + + void replacePool(MemoryPool pool) { + _pool = pool; + } + + VariantRef getVariant() { + return VariantRef(&_pool, &_data); + } + + VariantConstRef getVariant() const { + return VariantConstRef(&_data); + } + + MemoryPool _pool; + VariantData _data; + + private: + JsonDocument(const JsonDocument&); + JsonDocument& operator=(const JsonDocument&); +}; + +inline bool convertToJson(const JsonDocument& src, VariantRef dst) { + return dst.set(src.as<VariantConstRef>()); +} + +} // namespace ARDUINOJSON_NAMESPACE diff --git a/include/lib/ArduinoJson/Document/StaticJsonDocument.hpp b/include/lib/ArduinoJson/Document/StaticJsonDocument.hpp new file mode 100644 index 0000000..fbbadd4 --- /dev/null +++ b/include/lib/ArduinoJson/Document/StaticJsonDocument.hpp @@ -0,0 +1,56 @@ +// ArduinoJson - https://arduinojson.org +// Copyright Benoit Blanchon 2014-2021 +// MIT License + +#pragma once + +#include <ArduinoJson/Document/JsonDocument.hpp> + +namespace ARDUINOJSON_NAMESPACE { + +template <size_t desiredCapacity> +class StaticJsonDocument : public JsonDocument { + static const size_t _capacity = + AddPadding<Max<1, desiredCapacity>::value>::value; + + public: + StaticJsonDocument() : JsonDocument(_buffer, _capacity) {} + + StaticJsonDocument(const StaticJsonDocument& src) + : JsonDocument(_buffer, _capacity) { + set(src); + } + + template <typename T> + StaticJsonDocument(const T& src, + typename enable_if<IsVisitable<T>::value>::type* = 0) + : JsonDocument(_buffer, _capacity) { + set(src); + } + + // disambiguate + StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, _capacity) { + set(src); + } + + StaticJsonDocument operator=(const StaticJsonDocument& src) { + set(src); + return *this; + } + + template <typename T> + StaticJsonDocument operator=(const T& src) { + set(src); + return *this; + } + + void garbageCollect() { + StaticJsonDocument tmp(*this); + set(tmp); + } + + private: + char _buffer[_capacity]; +}; + +} // namespace ARDUINOJSON_NAMESPACE |