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>
This commit is contained in:
parent
c1780165ee
commit
d263147921
@ -263,6 +263,7 @@ public:
|
||||
private:
|
||||
friend class QJsonValue;
|
||||
friend class QJsonValueConstRef;
|
||||
friend class QJsonValueRef;
|
||||
friend class QJsonPrivate::Value;
|
||||
friend class QJsonDocument;
|
||||
friend class QCborArray;
|
||||
|
@ -1428,6 +1428,7 @@ QString QJsonObject::keyAt(qsizetype i) const
|
||||
return o->stringAt(i * 2);
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||
/*!
|
||||
\internal
|
||||
*/
|
||||
@ -1452,6 +1453,7 @@ void QJsonObject::setValueAt(qsizetype i, const QJsonValue &val)
|
||||
o->replaceAt(2 * i + 1, QCborValue::fromJsonValue(val));
|
||||
}
|
||||
}
|
||||
#endif // Qt 7
|
||||
|
||||
/*!
|
||||
\internal
|
||||
|
@ -303,8 +303,10 @@ private:
|
||||
template <typename T> iterator insertImpl(T key, const QJsonValue &value);
|
||||
|
||||
QString keyAt(qsizetype i) const;
|
||||
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) && !defined(QT_BOOTSTRAPPED)
|
||||
QJsonValue valueAt(qsizetype i) const;
|
||||
void setValueAt(qsizetype i, const QJsonValue &val);
|
||||
#endif
|
||||
void removeAt(qsizetype i);
|
||||
template <typename T> iterator insertAt(qsizetype i, T key, const QJsonValue &val, bool exists);
|
||||
|
||||
|
@ -919,25 +919,49 @@ bool QJsonValue::operator!=(const QJsonValue &other) const
|
||||
However, they are not explicitly documented here.
|
||||
*/
|
||||
|
||||
void QJsonValueRef::detach()
|
||||
{
|
||||
QCborContainerPrivate *d = QJsonPrivate::Value::container(*this);
|
||||
d = QCborContainerPrivate::detach(d, d->elements.size());
|
||||
|
||||
if (is_object)
|
||||
o->o.reset(d);
|
||||
else
|
||||
a->a.reset(d);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (is_object)
|
||||
o->setValueAt(index, val);
|
||||
else
|
||||
a->replace(index, val);
|
||||
|
||||
return *this;
|
||||
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
|
||||
|
@ -263,7 +263,10 @@ public:
|
||||
|
||||
private:
|
||||
QJsonValue toValue() const;
|
||||
#else
|
||||
private:
|
||||
#endif // < Qt 7
|
||||
void detach();
|
||||
};
|
||||
|
||||
inline QJsonValue QCborValueConstRef::toJsonValue() const
|
||||
|
Loading…
Reference in New Issue
Block a user