summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization/qcborvalue_p.h
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2018-05-19 14:58:43 -0700
committerThiago Macieira <thiago.macieira@intel.com>2018-07-04 03:04:21 +0000
commit2bb44414ff456873c885391e4a03afb67e7306da (patch)
tree9d6f7d1b2912cd494073c10e23fd61543535a022 /src/corelib/serialization/qcborvalue_p.h
parentfcb0f68e77bb69544f0ae310baffd3ceff8a9e5d (diff)
QCborArray & Map: implement efficient take() / extract()
Questions: 1) should QCborMap::extract return value_type (a pair) instead of just the value? 2) should the both return the iterator to the next element too, like erase()? Change-Id: I052407b777ec43f78378fffd15302a9c14468db3 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/serialization/qcborvalue_p.h')
-rw-r--r--src/corelib/serialization/qcborvalue_p.h25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/corelib/serialization/qcborvalue_p.h b/src/corelib/serialization/qcborvalue_p.h
index c80abd68f5..eb6fe09147 100644
--- a/src/corelib/serialization/qcborvalue_p.h
+++ b/src/corelib/serialization/qcborvalue_p.h
@@ -124,6 +124,8 @@ class QCborContainerPrivate : public QSharedData
~QCborContainerPrivate();
public:
+ enum ContainerDisposition { CopyContainer, MoveContainer };
+
QByteArray::size_type usedData = 0;
QByteArray data;
QVector<QtCbor::Element> elements;
@@ -275,12 +277,13 @@ public:
return data->toUtf8String();
}
- static QCborValue makeValue(QCborValue::Type type, qint64 n, QCborContainerPrivate *d = nullptr)
+ static QCborValue makeValue(QCborValue::Type type, qint64 n, QCborContainerPrivate *d = nullptr,
+ ContainerDisposition disp = CopyContainer)
{
QCborValue result(type);
result.n = n;
result.container = d;
- if (d)
+ if (d && disp == CopyContainer)
d->ref.ref();
return result;
}
@@ -300,6 +303,24 @@ public:
}
return makeValue(e.type, e.value);
}
+ QCborValue extractAt_complex(QtCbor::Element e);
+ QCborValue extractAt(qsizetype idx)
+ {
+ QtCbor::Element e;
+ qSwap(e, elements[idx]);
+
+ if (e.flags & QtCbor::Element::IsContainer) {
+ if (e.type == QCborValue::Tag && e.container->elements.size() != 2) {
+ // invalid tags can be created due to incomplete parsing
+ e.container->deref();
+ return makeValue(QCborValue::Invalid, 0, nullptr);
+ }
+ return makeValue(e.type, -1, e.container, MoveContainer);
+ } else if (e.flags & QtCbor::Element::HasByteData) {
+ return extractAt_complex(e);
+ }
+ return makeValue(e.type, e.value);
+ }
static QtCbor::Element elementFromValue(const QCborValue &value)
{