QByteArray: don't detach in remove()

- If this bytearray isn't shared call d->erase() as needed
- if it's shared, instead of detaching, create a new bytearray, and copy
  all characters except for the ones that would be removed

See task for details.

Adjust unittest to test both code paths.

Task-number: QTBUG-106182
Change-Id: I806e4d1707004345a2472e056905fbf675f765ab
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Ahmad Samir 2022-10-29 14:43:47 +02:00
parent 71c3aab7ba
commit 358b7a9e74
2 changed files with 20 additions and 4 deletions

View File

@ -2253,11 +2253,20 @@ QByteArray &QByteArray::remove(qsizetype pos, qsizetype len)
{
if (len <= 0 || pos < 0 || size_t(pos) >= size_t(size()))
return *this;
detach();
if (pos + len > d->size)
len = d->size - pos;
d->erase(d.begin() + pos, len);
d.data()[d.size] = '\0';
auto begin = d.begin();
if (!d->isShared()) {
d->erase(begin + pos, len);
d.data()[d.size] = '\0';
} else {
QByteArray copy{size() - len, Qt::Uninitialized};
const auto toRemove_start = d.begin() + pos;
copy.d->copyRanges({{d.begin(), toRemove_start},
{toRemove_start + len, d.end()}});
swap(copy);
}
return *this;
}

View File

@ -1258,7 +1258,14 @@ void tst_QByteArray::remove()
QFETCH(int, position);
QFETCH(int, length);
QFETCH(QByteArray, expected);
QCOMPARE(src.remove(position, length), expected);
// Test when it's shared
QByteArray ba1 = src;
QCOMPARE(ba1.remove(position, length), expected);
// Test when it's not shared
QByteArray ba2 = src;
ba2.detach();
QCOMPARE(ba2.remove(position, length), expected);
}
void tst_QByteArray::removeIf()