summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2021-11-27 11:28:57 -0600
committerThiago Macieira <thiago.macieira@intel.com>2022-02-15 17:00:05 -0800
commitd263147921800e7b6d357d1a48f28f21a8092b84 (patch)
tree44620354627d89cfdbf4ba3b802f6d9df5a61926
parentc1780165eeca0db6c874866c3184cdaa65542b51 (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>
-rw-r--r--src/corelib/serialization/qjsonarray.h1
-rw-r--r--src/corelib/serialization/qjsonobject.cpp2
-rw-r--r--src/corelib/serialization/qjsonobject.h2
-rw-r--r--src/corelib/serialization/qjsonvalue.cpp44
-rw-r--r--src/corelib/serialization/qjsonvalue.h3
5 files changed, 42 insertions, 10 deletions
diff --git a/src/corelib/serialization/qjsonarray.h b/src/corelib/serialization/qjsonarray.h
index 0128a36470..a8c3760565 100644
--- a/src/corelib/serialization/qjsonarray.h
+++ b/src/corelib/serialization/qjsonarray.h
@@ -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;
diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp
index 014224c4db..ee4ea8ce23 100644
--- a/src/corelib/serialization/qjsonobject.cpp
+++ b/src/corelib/serialization/qjsonobject.cpp
@@ -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
diff --git a/src/corelib/serialization/qjsonobject.h b/src/corelib/serialization/qjsonobject.h
index d9f6785631..74f6905b60 100644
--- a/src/corelib/serialization/qjsonobject.h
+++ b/src/corelib/serialization/qjsonobject.h
@@ -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);
diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp
index 27cad8941e..9fecbbb626 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
diff --git a/src/corelib/serialization/qjsonvalue.h b/src/corelib/serialization/qjsonvalue.h
index 4f9c3af578..f50bb08017 100644
--- a/src/corelib/serialization/qjsonvalue.h
+++ b/src/corelib/serialization/qjsonvalue.h
@@ -263,7 +263,10 @@ public:
private:
QJsonValue toValue() const;
+#else
+private:
#endif // < Qt 7
+ void detach();
};
inline QJsonValue QCborValueConstRef::toJsonValue() const