diff --git a/CHANGELOG.md b/CHANGELOG.md index b28b8301..1d3b5d6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ HEAD ---- * Improve error messages when using `char` or `char*` (issue #2043) +* Reduce `serializeJson()`'s size and stack usage (issue #2046) v7.0.2 (2024-01-19) ------ diff --git a/src/ArduinoJson/Collection/CollectionData.hpp b/src/ArduinoJson/Collection/CollectionData.hpp index 1010795c..07fe7e04 100644 --- a/src/ArduinoJson/Collection/CollectionData.hpp +++ b/src/ArduinoJson/Collection/CollectionData.hpp @@ -107,6 +107,10 @@ class CollectionData { return collection->remove(it, resources); } + SlotId head() const { + return head_; + } + protected: iterator addSlot(ResourceManager*); diff --git a/src/ArduinoJson/Json/JsonSerializer.hpp b/src/ArduinoJson/Json/JsonSerializer.hpp index f4751f0c..6c84b3e1 100644 --- a/src/ArduinoJson/Json/JsonSerializer.hpp +++ b/src/ArduinoJson/Json/JsonSerializer.hpp @@ -22,16 +22,17 @@ class JsonSerializer : public VariantDataVisitor { FORCE_INLINE size_t visit(const ArrayData& array) { write('['); - auto it = array.createIterator(resources_); + auto slotId = array.head(); - while (!it.done()) { - it->accept(*this); + while (slotId != NULL_SLOT) { + auto slot = resources_->getSlot(slotId); - it.next(resources_); - if (it.done()) - break; + slot->data()->accept(*this); - write(','); + slotId = slot->next(); + + if (slotId != NULL_SLOT) + write(','); } write(']'); @@ -41,18 +42,19 @@ class JsonSerializer : public VariantDataVisitor { size_t visit(const ObjectData& object) { write('{'); - auto it = object.createIterator(resources_); + auto slotId = object.head(); - while (!it.done()) { - formatter_.writeString(it.key()); + while (slotId != NULL_SLOT) { + auto slot = resources_->getSlot(slotId); + + formatter_.writeString(slot->key()); write(':'); - it->accept(*this); + slot->data()->accept(*this); - it.next(resources_); - if (it.done()) - break; + slotId = slot->next(); - write(','); + if (slotId != NULL_SLOT) + write(','); } write('}');