Stop using CollectionIterator in JsonSerializer

This reduces stack consumption and code size.
See  #2046
This commit is contained in:
Benoit Blanchon
2024-02-01 10:24:00 +01:00
parent 650d537b5d
commit 296fe79bfd
3 changed files with 22 additions and 15 deletions

View File

@ -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)
------

View File

@ -107,6 +107,10 @@ class CollectionData {
return collection->remove(it, resources);
}
SlotId head() const {
return head_;
}
protected:
iterator addSlot(ResourceManager*);

View File

@ -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(']');
@ -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 (!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('}');