| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- // ArduinoJson - https://arduinojson.org
- // Copyright © 2014-2022, Benoit BLANCHON
- // 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(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, JsonVariantConst>::value || is_same<T, JsonArray>::value ||
- is_same<T, JsonArrayConst>::value || is_same<T, JsonObject>::value ||
- is_same<T, JsonObjectConst>::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) {
- size_t requiredSize = src.memoryUsage();
- if (requiredSize > capacity())
- reallocPool(requiredSize);
- 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 reallocPool(size_t requiredSize) {
- size_t capa = addPadding(requiredSize);
- if (capa == _pool.capacity())
- return;
- freePool();
- replacePool(allocPool(addPadding(requiredSize)));
- }
- void freePool() {
- this->deallocate(getPool()->buffer());
- }
- void copyAssignFrom(const JsonDocument& src) {
- reallocPool(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
|