diff options
| author | Thiago Macieira <thiago.macieira@intel.com> | 2021-11-27 11:28:57 -0600 |
|---|---|---|
| committer | Thiago Macieira <thiago.macieira@intel.com> | 2022-02-15 17:00:05 -0800 |
| commit | d263147921800e7b6d357d1a48f28f21a8092b84 (patch) | |
| tree | 44620354627d89cfdbf4ba3b802f6d9df5a61926 /src/corelib/serialization/qjsonvalue.cpp | |
| parent | c1780165eeca0db6c874866c3184cdaa65542b51 (diff) | |
QJsonValueRef: optimize the assignment
Inline some content to avoid unnecessary round-trips through
qcborvalue.cpp, qjsonarray.cpp and qjsonobject.cpp.
Unlike the CBOR counterparts, JSON support has this extra functionality
that assigning Undefined causes the item to be removed from the object
(arrays don't have that behavior, they just become null).
And unlike QCborValueRef, we detach on assignment, not on the obtention
of the QJsonValueRef. This is more dangerous, so we may want to revise.
Change-Id: I89446ea06b5742efb194fffd16bb775e9566ca1a
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
Diffstat (limited to 'src/corelib/serialization/qjsonvalue.cpp')
| -rw-r--r-- | src/corelib/serialization/qjsonvalue.cpp | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp index 27cad8941ed..9fecbbb6266 100644 --- a/src/corelib/serialization/qjsonvalue.cpp +++ b/src/corelib/serialization/qjsonvalue.cpp @@ -919,25 +919,49 @@ bool QJsonValue::operator!=(const QJsonValue &other) const However, they are not explicitly documented here. */ - -QJsonValueRef &QJsonValueRef::operator =(const QJsonValue &val) +void QJsonValueRef::detach() { + QCborContainerPrivate *d = QJsonPrivate::Value::container(*this); + d = QCborContainerPrivate::detach(d, d->elements.size()); + if (is_object) - o->setValueAt(index, val); + o->o.reset(d); else - a->replace(index, val); + a->a.reset(d); +} - return *this; +static QJsonValueRef &assignToRef(QJsonValueRef &ref, const QCborValue &value, bool is_object) +{ + QCborContainerPrivate *d = QJsonPrivate::Value::container(ref); + qsizetype index = QJsonPrivate::Value::indexHelper(ref); + if (is_object && value.isUndefined()) { + d->removeAt(index); + d->removeAt(index - 1); + } else { + d->replaceAt(index, value); + } + + return ref; +} + +QJsonValueRef &QJsonValueRef::operator =(const QJsonValue &val) +{ + detach(); + return assignToRef(*this, QCborValue::fromJsonValue(val), is_object); } QJsonValueRef &QJsonValueRef::operator =(const QJsonValueRef &ref) { - if (is_object) - o->setValueAt(index, ref); - else - a->replace(index, ref); + // ### optimize more? + const QCborContainerPrivate *d = QJsonPrivate::Value::container(ref); + qsizetype index = QJsonPrivate::Value::indexHelper(ref); - return *this; + if (d == QJsonPrivate::Value::container(*this) && + index == QJsonPrivate::Value::indexHelper(*this)) + return *this; // self assignment + + detach(); + return assignToRef(*this, d->valueAt(index), is_object); } QVariant QJsonValueConstRef::toVariant() const |
