DynamicJsonDocument reallocates memory pool is it's too small

This commit is contained in:
Benoit Blanchon
2018-12-07 10:38:58 +01:00
parent b77b203935
commit e20c47c57b
3 changed files with 103 additions and 60 deletions

View File

@ -13,36 +13,48 @@ namespace ARDUINOJSON_NAMESPACE {
class DynamicJsonDocument : public JsonDocument {
public:
DynamicJsonDocument(size_t capa = ARDUINOJSON_DEFAULT_POOL_SIZE)
: JsonDocument(alloc(capa), addPadding(capa)) {}
: JsonDocument(allocPool(addPadding(capa))) {}
DynamicJsonDocument(const DynamicJsonDocument& src)
: JsonDocument(alloc(src.memoryUsage()), addPadding(src.memoryUsage())) {
: JsonDocument(allocPool(src.capacity())) {
copy(src);
}
DynamicJsonDocument(const JsonDocument& src)
: JsonDocument(alloc(src.memoryUsage()), addPadding(src.memoryUsage())) {
: JsonDocument(allocPool(src.capacity())) {
copy(src);
}
~DynamicJsonDocument() {
free(memoryPool().buffer());
freePool();
}
DynamicJsonDocument& operator=(const DynamicJsonDocument& src) {
reallocPoolIfTooSmall(src.memoryUsage());
copy(src);
return *this;
}
template <typename T>
DynamicJsonDocument& operator=(const JsonDocument& src) {
reallocPoolIfTooSmall(src.memoryUsage());
copy(src);
return *this;
}
private:
static char* alloc(size_t capa) {
return reinterpret_cast<char*>(malloc(addPadding(capa)));
MemoryPool allocPool(size_t capa) {
return MemoryPool(reinterpret_cast<char*>(malloc(capa)), capa);
}
void reallocPoolIfTooSmall(size_t requiredSize) {
if (requiredSize <= capacity()) return;
freePool();
replacePool(allocPool(addPadding(requiredSize)));
}
void freePool() {
free(memoryPool().buffer());
}
};

View File

@ -63,6 +63,9 @@ class JsonDocument : public Visitable {
}
protected:
JsonDocument(MemoryPool pool)
: nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT), _pool(pool) {}
JsonDocument(char* buf, size_t capa)
: nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT), _pool(buf, capa) {}
@ -71,6 +74,10 @@ class JsonDocument : public Visitable {
to<VariantRef>().set(src.as<VariantRef>());
}
void replacePool(MemoryPool pool) {
_pool = pool;
}
private:
VariantRef getVariant() {
return VariantRef(&_pool, &_data);