summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qbytearray.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2020-10-30 13:01:56 +0100
committerLars Knoll <lars.knoll@qt.io>2020-11-04 11:21:50 +0100
commit9ee50a14b72706334c7a26469afac3999d3bdac5 (patch)
treef244720aae86af8ae99925bd4aaa82486cd4328f /src/corelib/text/qbytearray.cpp
parentb76fbb48fba51df95d1776b8c1ff358789d78031 (diff)
Move insert() operation into QArrayDataOps
This allows us to unify and simplify the code base between QList, QString and QByteArray. Change-Id: Idc8f360d78f508a68f38eb3ef0ed6e5d37f90574 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/corelib/text/qbytearray.cpp')
-rw-r--r--src/corelib/text/qbytearray.cpp87
1 files changed, 36 insertions, 51 deletions
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
index 1b5fa8e5eb..d729667ff7 100644
--- a/src/corelib/text/qbytearray.cpp
+++ b/src/corelib/text/qbytearray.cpp
@@ -1922,39 +1922,34 @@ QByteArray& QByteArray::append(char ch)
QByteArray &QByteArray::insert(qsizetype i, QByteArrayView data)
{
const char *str = data.data();
- qsizetype len = data.size();
- if (i < 0 || str == nullptr || len <= 0)
+ qsizetype size = data.size();
+ if (i < 0 || size <= 0)
return *this;
- if (points_into_range(str, d.data(), d.data() + d.size)) {
- QVarLengthArray a(str, str + len);
- return insert(i, a);
+ // handle this specially, as QArrayDataOps::insert() doesn't handle out of
+ // bounds positions
+ if (i >= d->size) {
+ // In case when data points into the range or is == *this, we need to
+ // defer a call to free() so that it comes after we copied the data from
+ // the old memory:
+ DataPointer detached{}; // construction is free
+ if (d->needsDetach() || i + size - d->size > d.freeSpaceAtEnd()) {
+ detached = DataPointer::allocateGrow(d, i + size - d->size, Data::AllocateAtEnd);
+ detached->copyAppend(d.constBegin(), d.constEnd());
+ d.swap(detached);
+ }
+ d->copyAppend(i - d->size, ' ');
+ d->copyAppend(str, str + size);
+ d.data()[d.size] = '\0';
+ return *this;
}
- const auto oldSize = this->size();
- qsizetype sizeToGrow = len;
- if (i > oldSize)
- sizeToGrow += i - oldSize;
-
- if (d->needsDetach() || (sizeToGrow > d.freeSpaceAtBegin() && sizeToGrow > d.freeSpaceAtEnd())) {
- QArrayData::AllocationPosition pos = QArrayData::AllocateAtEnd;
- if (oldSize != 0 && i <= (oldSize >> 1))
- pos = QArrayData::AllocateAtBeginning;
-
- DataPointer detached(DataPointer::allocateGrow(d, sizeToGrow, pos));
- auto where = d.constBegin() + qMin(i, d->size);
- detached->copyAppend(d.constBegin(), where);
- if (i > oldSize)
- detached->copyAppend(i - oldSize, u' ');
- detached->copyAppend(str, str + len);
- detached->copyAppend(where, d.constEnd());
- d.swap(detached);
- } else {
- if (i > oldSize) // set spaces in the uninitialized gap
- d->copyAppend(i - oldSize, ' ');
-
- d->insert(d.begin() + i, str, str + len);
+ if (!d->needsDetach() && points_into_range(str, d.data(), d.data() + d.size)) {
+ QVarLengthArray a(str, str + size);
+ return insert(i, a);
}
+
+ d->insert(i, str, size);
d.data()[d.size] = '\0';
return *this;
}
@@ -1995,30 +1990,20 @@ QByteArray &QByteArray::insert(qsizetype i, qsizetype count, char ch)
if (i < 0 || count <= 0)
return *this;
- const auto oldSize = this->size();
- qsizetype sizeToGrow = count;
- if (i > oldSize)
- sizeToGrow += i - oldSize;
-
- if (d->needsDetach() || (sizeToGrow > d.freeSpaceAtBegin() && sizeToGrow > d.freeSpaceAtEnd())) {
- QArrayData::AllocationPosition pos = QArrayData::AllocateAtEnd;
- if (oldSize != 0 && i <= (oldSize >> 1))
- pos = QArrayData::AllocateAtBeginning;
-
- DataPointer detached(DataPointer::allocateGrow(d, sizeToGrow, pos));
- auto where = d.constBegin() + qMin(i, d->size);
- detached->copyAppend(d.constBegin(), where);
- if (i > oldSize)
- detached->copyAppend(i - oldSize, ' ');
- detached->copyAppend(count, ch);
- detached->copyAppend(where, d.constEnd());
- d.swap(detached);
- } else {
- if (i > oldSize) // set spaces in the uninitialized gap
- d->copyAppend(i - oldSize, u' ');
-
- d->insert(d.begin() + i, count, ch);
+ if (i >= d->size) {
+ // handle this specially, as QArrayDataOps::insert() doesn't handle out of bounds positions
+ if (d->needsDetach() || i + count - d->size > d.freeSpaceAtEnd()) {
+ DataPointer detached(DataPointer::allocateGrow(d, i + count - d->size, Data::AllocateAtEnd));
+ detached->copyAppend(d.constBegin(), d.constEnd());
+ d.swap(detached);
+ }
+ d->copyAppend(i - d->size, ' ');
+ d->copyAppend(count, ch);
+ d.data()[d.size] = '\0';
+ return *this;
}
+
+ d->insert(i, count, ch);
d.data()[d.size] = '\0';
return *this;
}