Skip to content

Commit

Permalink
Stop using CollectionIterator in JsonSerializer
Browse files Browse the repository at this point in the history
This reduces stack consumption and code size.
See  #2046
  • Loading branch information
bblanchon committed Feb 1, 2024
1 parent 650d537 commit 296fe79
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 15 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
------
Expand Down
4 changes: 4 additions & 0 deletions src/ArduinoJson/Collection/CollectionData.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ class CollectionData {
return collection->remove(it, resources);
}

SlotId head() const {
return head_;
}

protected:
iterator addSlot(ResourceManager*);

Expand Down
32 changes: 17 additions & 15 deletions src/ArduinoJson/Json/JsonSerializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
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(']');
Expand All @@ -41,18 +42,19 @@ class JsonSerializer : public VariantDataVisitor<size_t> {
size_t visit(const ObjectData& object) {
write('{');

auto it = object.createIterator(resources_);
auto slotId = object.head();

while (slotId != NULL_SLOT) {
auto slot = resources_->getSlot(slotId);

while (!it.done()) {
formatter_.writeString(it.key());
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('}');
Expand Down

0 comments on commit 296fe79

Please sign in to comment.