Call shrinkToFit() in deserializeJson() and deserializeMsgPack()

This commit is contained in:
Benoit Blanchon
2023-07-31 17:34:17 +02:00
parent 752d01a7f1
commit 218a12ca46
14 changed files with 209 additions and 67 deletions
+11
View File
@@ -110,6 +110,17 @@
# define ARDUINOJSON_INITIAL_POOL_COUNT 4
#endif
// Automatically call shrinkToFit() from deserializeXxx()
// Disabled by default on 8-bit platforms because it's not worth the increase in
// code size
#ifndef ARDUINOJSON_AUTO_SHRINK
# if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ <= 2
# define ARDUINOJSON_AUTO_SHRINK 0
# else
# define ARDUINOJSON_AUTO_SHRINK 1
# endif
#endif
#ifdef ARDUINO
// Enable support for Arduino's String class
+9 -2
View File
@@ -4,14 +4,21 @@
#pragma once
#include <ArduinoJson/Namespace.hpp>
#include <ArduinoJson/Variant/JsonVariant.hpp>
#include <ArduinoJson/Variant/VariantAttorney.hpp>
ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
namespace DeserializationOption {
class Filter {
public:
explicit Filter(JsonVariantConst v) : variant_(v) {}
#if ARDUINOJSON_AUTO_SHRINK
explicit Filter(JsonDocument& doc) : variant_(doc) {
doc.shrinkToFit();
}
#endif
explicit Filter(JsonVariantConst variant) : variant_(variant) {}
bool allow() const {
return variant_;
@@ -43,8 +43,12 @@ DeserializationError doDeserialize(TDestination&& dst, TReader reader,
return DeserializationError::NoMemory;
auto resources = VariantAttorney::getResourceManager(dst);
dst.clear();
return TDeserializer<TReader>(resources, reader)
.parse(*data, options.filter, options.nestingLimit);
auto err = TDeserializer<TReader>(resources, reader)
.parse(*data, options.filter, options.nestingLimit);
#if ARDUINOJSON_AUTO_SHRINK
resources->shrinkToFit();
#endif
return err;
}
template <template <typename> class TDeserializer, typename TDestination,
+5 -2
View File
@@ -26,9 +26,12 @@ inline void VariantPool::destroy(Allocator* allocator) {
}
inline void VariantPool::shrinkToFit(Allocator* allocator) {
slots_ = reinterpret_cast<VariantSlot*>(
auto newSlots = reinterpret_cast<VariantSlot*>(
allocator->reallocate(slots_, slotsToBytes(usage_)));
capacity_ = usage_;
if (newSlots) {
slots_ = newSlots;
capacity_ = usage_;
}
}
inline SlotWithId VariantPool::allocSlot() {