diff options
-rw-r--r-- | src/corelib/serialization/qcborarray.cpp | 26 | ||||
-rw-r--r-- | src/corelib/serialization/qcborarray.h | 7 | ||||
-rw-r--r-- | src/corelib/serialization/qcborvalue.cpp | 17 | ||||
-rw-r--r-- | src/corelib/serialization/qcborvalue_p.h | 1 |
4 files changed, 41 insertions, 10 deletions
diff --git a/src/corelib/serialization/qcborarray.cpp b/src/corelib/serialization/qcborarray.cpp index 921fcf2fca..c56536cdb1 100644 --- a/src/corelib/serialization/qcborarray.cpp +++ b/src/corelib/serialization/qcborarray.cpp @@ -297,7 +297,8 @@ QCborValue QCborArray::at(qsizetype i) const \fn QCborValueRef QCborArray::operator[](qsizetype i) Returns a reference to the QCborValue element at position \a i in the - array. The array must have at least \a i elements. + array. Indices beyond the end of the array will grow the array, filling + with undefined entries, until it has an entry at the specified index. QCborValueRef has the exact same API as \l QCborValue, with one important difference: if you assign new values to it, this map will be updated with @@ -311,27 +312,34 @@ QCborValue QCborArray::at(qsizetype i) const \fn void QCborArray::insert(qsizetype i, const QCborValue &value) \fn void QCborArray::insert(qsizetype i, QCborValue &&value) - Inserts \a value into the array at position \a i in this array. The array - must have at least \a i elements before the insertion. + Inserts \a value into the array at position \a i in this array. If \a i is + -1, the entry is appended to the array. Pads the array with invalid entries + if \a i is greater than the prior size of the array. \sa at(), operator[](), first(), last(), prepend(), append(), removeAt(), takeAt(), extract() */ void QCborArray::insert(qsizetype i, const QCborValue &value) { - Q_ASSERT(size_t(i) <= size_t(size()) || i == -1); - if (i < 0) + if (i < 0) { + Q_ASSERT(i == -1); i = size(); - detach(qMax(i + 1, size())); + detach(i + 1); + } else { + d = QCborContainerPrivate::grow(d.data(), i); // detaches + } d->insertAt(i, value); } void QCborArray::insert(qsizetype i, QCborValue &&value) { - Q_ASSERT(size_t(i) <= size_t(size()) || i == -1); - if (i < 0) + if (i < 0) { + Q_ASSERT(i == -1); i = size(); - detach(qMax(i + 1, size())); + detach(i + 1); + } else { + d = QCborContainerPrivate::grow(d.data(), i); // detaches + } d->insertAt(i, value, QCborContainerPrivate::MoveContainer); QCborContainerPrivate::resetValue(value); } diff --git a/src/corelib/serialization/qcborarray.h b/src/corelib/serialization/qcborarray.h index f24bb41759..ae6b8c09d7 100644 --- a/src/corelib/serialization/qcborarray.h +++ b/src/corelib/serialization/qcborarray.h @@ -188,7 +188,12 @@ public: QCborValue operator[](qsizetype i) const { return at(i); } QCborValueRef first() { Q_ASSERT(!isEmpty()); return begin()[0]; } QCborValueRef last() { Q_ASSERT(!isEmpty()); return begin()[size() - 1]; } - QCborValueRef operator[](qsizetype i) { Q_ASSERT(i < size()); return begin()[i]; } + QCborValueRef operator[](qsizetype i) + { + if (i >= size()) + insert(i, QCborValue()); + return begin()[i]; + } void insert(qsizetype i, const QCborValue &value); void insert(qsizetype i, QCborValue &&value); diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp index 077a4754dc..81ea1ed3b2 100644 --- a/src/corelib/serialization/qcborvalue.cpp +++ b/src/corelib/serialization/qcborvalue.cpp @@ -859,6 +859,23 @@ QCborContainerPrivate *QCborContainerPrivate::detach(QCborContainerPrivate *d, q return d; } +/*! + Prepare for an insertion at position \a index + + Detaches and ensures there are at least index entries in the array, padding + with Undefined as needed. +*/ +QCborContainerPrivate *QCborContainerPrivate::grow(QCborContainerPrivate *d, qsizetype index) +{ + Q_ASSERT(index >= 0); + d = detach(d, index + 1); + Q_ASSERT(d); + int j = d->elements.size(); + while (j < index) + d->append(Undefined()); + return d; +} + // Copies or moves \a value into element at position \a e. If \a disp is // CopyContainer, then this function increases the reference count of the // container, but otherwise leaves it unmodified. If \a disp is MoveContainer, diff --git a/src/corelib/serialization/qcborvalue_p.h b/src/corelib/serialization/qcborvalue_p.h index 3a28707056..4050d18fa9 100644 --- a/src/corelib/serialization/qcborvalue_p.h +++ b/src/corelib/serialization/qcborvalue_p.h @@ -136,6 +136,7 @@ public: void compact(qsizetype reserved); static QCborContainerPrivate *clone(QCborContainerPrivate *d, qsizetype reserved = -1); static QCborContainerPrivate *detach(QCborContainerPrivate *d, qsizetype reserved); + static QCborContainerPrivate *grow(QCborContainerPrivate *d, qsizetype index); qptrdiff addByteData(const char *block, qsizetype len) { |