From 296fe79bfd97442713dab0244c9140996f358070 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 1 Feb 2024 10:24:00 +0100 Subject: [PATCH] Stop using `CollectionIterator` in `JsonSerializer` This reduces stack consumption and code size. See #2046 --- CHANGELOG.md | 1 + src/ArduinoJson/Collection/CollectionData.hpp | 4 +++ src/ArduinoJson/Json/JsonSerializer.hpp | 32 ++++++++++--------- 3 files changed, 22 insertions(+), 15 deletions(-) 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('}');