QCborValue: apply a simple optimization to avoid unnecessary allocations
If the map or array is known to be empty, we don't need to allocate a QCborContainerPrivate. Change-Id: Ief61acdfbe4d4b5ba1f0fffd15fe212b6a6e77c3 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
02d595946f
commit
f581b04119
@ -1445,9 +1445,35 @@ static inline QCborContainerPrivate *createContainerFromCbor(QCborStreamReader &
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto d = new QCborContainerPrivate;
|
||||
d->ref.storeRelaxed(1);
|
||||
d->decodeContainerFromCbor(reader, remainingRecursionDepth - 1);
|
||||
QCborContainerPrivate *d = nullptr;
|
||||
int mapShift = reader.isMap() ? 1 : 0;
|
||||
if (reader.isLengthKnown()) {
|
||||
quint64 len = reader.length();
|
||||
|
||||
// Clamp allocation to 1M elements (avoids crashing due to corrupt
|
||||
// stream or loss of precision when converting from quint64 to
|
||||
// QVector::size_type).
|
||||
len = qMin(len, quint64(1024 * 1024 - 1));
|
||||
if (len) {
|
||||
d = new QCborContainerPrivate;
|
||||
d->ref.storeRelaxed(1);
|
||||
d->elements.reserve(qsizetype(len) << mapShift);
|
||||
}
|
||||
} else {
|
||||
d = new QCborContainerPrivate;
|
||||
d->ref.storeRelaxed(1);
|
||||
}
|
||||
|
||||
reader.enterContainer();
|
||||
if (reader.lastError() != QCborError::NoError)
|
||||
return d;
|
||||
|
||||
while (reader.hasNext() && reader.lastError() == QCborError::NoError)
|
||||
d->decodeValueFromCbor(reader, remainingRecursionDepth - 1);
|
||||
|
||||
if (reader.lastError() == QCborError::NoError)
|
||||
reader.leaveContainer();
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
@ -1637,30 +1663,6 @@ void QCborContainerPrivate::decodeValueFromCbor(QCborStreamReader &reader, int r
|
||||
}
|
||||
}
|
||||
|
||||
void QCborContainerPrivate::decodeContainerFromCbor(QCborStreamReader &reader, int remainingRecursionDepth)
|
||||
{
|
||||
int mapShift = reader.isMap() ? 1 : 0;
|
||||
if (reader.isLengthKnown()) {
|
||||
quint64 len = reader.length();
|
||||
|
||||
// Clamp allocation to 1M elements (avoids crashing due to corrupt
|
||||
// stream or loss of precision when converting from quint64 to
|
||||
// QVector::size_type).
|
||||
len = qMin(len, quint64(1024 * 1024 - 1));
|
||||
elements.reserve(qsizetype(len) << mapShift);
|
||||
}
|
||||
|
||||
reader.enterContainer();
|
||||
if (reader.lastError() != QCborError::NoError)
|
||||
return;
|
||||
|
||||
while (reader.hasNext() && reader.lastError() == QCborError::NoError)
|
||||
decodeValueFromCbor(reader, remainingRecursionDepth);
|
||||
|
||||
if (reader.lastError() == QCborError::NoError)
|
||||
reader.leaveContainer();
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a QCborValue with byte array value \a ba. The value can later be
|
||||
retrieved using toByteArray().
|
||||
|
@ -406,7 +406,6 @@ public:
|
||||
}
|
||||
|
||||
void decodeValueFromCbor(QCborStreamReader &reader, int remainiingStackDepth);
|
||||
void decodeContainerFromCbor(QCborStreamReader &reader, int remainingStackDepth);
|
||||
void decodeStringFromCbor(QCborStreamReader &reader);
|
||||
static inline void setErrorInReader(QCborStreamReader &reader, QCborError error);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user