QByteArray: Add append/prepend/insert overload

Use-case is fast insertion of copies of a character,
avoiding any temporary heap allocations

Change-Id: Ie5517d88429fbd4c58dbe5729de7c468d5d9a279
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: Sérgio Martins <sergio.martins@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Kevin Funk 2015-08-13 20:58:42 +02:00
parent 526d9b52ce
commit f72cbe39e0
3 changed files with 78 additions and 10 deletions

View File

@ -1713,6 +1713,14 @@ QByteArray &QByteArray::prepend(const char *str, int len)
return *this;
}
/*! \fn QByteArray &QByteArray::prepend(int count, char ch)
\overload
\since 5.7
Prepends \a count copies of character \a ch to this byte array.
*/
/*!
\overload
@ -1825,6 +1833,17 @@ QByteArray &QByteArray::append(const char *str, int len)
return *this;
}
/*! \fn QByteArray &QByteArray::append(int count, char ch)
\overload
\since 5.7
Appends \a count copies of character \a ch to this byte
array and returns a reference to this byte array.
If \a count is negative or zero nothing is appended to the byte array.
*/
/*!
\overload
@ -1941,6 +1960,33 @@ QByteArray &QByteArray::insert(int i, char ch)
return qbytearray_insert(this, i, &ch, 1);
}
/*! \fn QByteArray &QByteArray::insert(int i, int count, char ch)
\overload
\since 5.7
Inserts \a count copies of character \a ch at index position \a i in the
byte array.
If \a i is greater than size(), the array is first extended using resize().
*/
QByteArray &QByteArray::insert(int i, int count, char ch)
{
if (i < 0 || count <= 0)
return *this;
int oldsize = size();
resize(qMax(i, oldsize) + count);
char *dst = d->data();
if (i > oldsize)
::memset(dst + oldsize, 0x20, i - oldsize);
else if (i < oldsize)
::memmove(dst + i + count, dst + i, oldsize - i);
::memset(dst + i, ch, count);
return *this;
}
/*!
Removes \a len bytes from the array, starting at index position \a
pos, and returns a reference to the array.

View File

@ -285,14 +285,17 @@ public:
QByteArray rightJustified(int width, char fill = ' ', bool truncate = false) const Q_REQUIRED_RESULT;
QByteArray &prepend(char c);
QByteArray &prepend(int count, char c);
QByteArray &prepend(const char *s);
QByteArray &prepend(const char *s, int len);
QByteArray &prepend(const QByteArray &a);
QByteArray &append(char c);
QByteArray &append(int count, char c);
QByteArray &append(const char *s);
QByteArray &append(const char *s, int len);
QByteArray &append(const QByteArray &a);
QByteArray &insert(int i, char c);
QByteArray &insert(int i, int count, char c);
QByteArray &insert(int i, const char *s);
QByteArray &insert(int i, const char *s, int len);
QByteArray &insert(int i, const QByteArray &a);
@ -568,6 +571,10 @@ inline QByteArray::const_iterator QByteArray::cend() const
{ return d->data() + d->size; }
inline QByteArray::const_iterator QByteArray::constEnd() const
{ return d->data() + d->size; }
inline QByteArray &QByteArray::append(int n, char ch)
{ return insert(d->size, n, ch); }
inline QByteArray &QByteArray::prepend(int n, char ch)
{ return insert(0, n, ch); }
inline QByteArray &QByteArray::operator+=(char c)
{ return append(c); }
inline QByteArray &QByteArray::operator+=(const char *s)

View File

@ -896,7 +896,9 @@ void tst_QByteArray::prepend()
QCOMPARE(ba.prepend("1"), QByteArray("1foo"));
QCOMPARE(ba.prepend(QByteArray("2")), QByteArray("21foo"));
QCOMPARE(ba.prepend('3'), QByteArray("321foo"));
QCOMPARE(ba.prepend("\0 ", 2), QByteArray::fromRawData("\0 321foo", 8));
QCOMPARE(ba.prepend(-1, 'x'), QByteArray("321foo"));
QCOMPARE(ba.prepend(3, 'x'), QByteArray("xxx321foo"));
QCOMPARE(ba.prepend("\0 ", 2), QByteArray::fromRawData("\0 xxx321foo", 11));
}
void tst_QByteArray::prependExtended_data()
@ -924,8 +926,10 @@ void tst_QByteArray::prependExtended()
QCOMPARE(array.prepend("1"), QByteArray("1data"));
QCOMPARE(array.prepend(QByteArray("2")), QByteArray("21data"));
QCOMPARE(array.prepend('3'), QByteArray("321data"));
QCOMPARE(array.prepend("\0 ", 2), QByteArray::fromRawData("\0 321data", 9));
QCOMPARE(array.size(), 9);
QCOMPARE(array.prepend(-1, 'x'), QByteArray("321data"));
QCOMPARE(array.prepend(3, 'x'), QByteArray("xxx321data"));
QCOMPARE(array.prepend("\0 ", 2), QByteArray::fromRawData("\0 xxx321data", 12));
QCOMPARE(array.size(), 12);
}
void tst_QByteArray::append()
@ -936,9 +940,11 @@ void tst_QByteArray::append()
QCOMPARE(ba.append("1"), QByteArray("foo1"));
QCOMPARE(ba.append(QByteArray("2")), QByteArray("foo12"));
QCOMPARE(ba.append('3'), QByteArray("foo123"));
QCOMPARE(ba.append("\0"), QByteArray("foo123"));
QCOMPARE(ba.append("\0", 1), QByteArray::fromRawData("foo123\0", 7));
QCOMPARE(ba.size(), 7);
QCOMPARE(ba.append(-1, 'x'), QByteArray("foo123"));
QCOMPARE(ba.append(3, 'x'), QByteArray("foo123xxx"));
QCOMPARE(ba.append("\0"), QByteArray("foo123xxx"));
QCOMPARE(ba.append("\0", 1), QByteArray::fromRawData("foo123xxx\0", 10));
QCOMPARE(ba.size(), 10);
}
void tst_QByteArray::appendExtended_data()
@ -958,9 +964,11 @@ void tst_QByteArray::appendExtended()
QCOMPARE(array.append("1"), QByteArray("data1"));
QCOMPARE(array.append(QByteArray("2")), QByteArray("data12"));
QCOMPARE(array.append('3'), QByteArray("data123"));
QCOMPARE(array.append("\0"), QByteArray("data123"));
QCOMPARE(array.append("\0", 1), QByteArray::fromRawData("data123\0", 8));
QCOMPARE(array.size(), 8);
QCOMPARE(array.append(-1, 'x'), QByteArray("data123"));
QCOMPARE(array.append(3, 'x'), QByteArray("data123xxx"));
QCOMPARE(array.append("\0"), QByteArray("data123xxx"));
QCOMPARE(array.append("\0", 1), QByteArray::fromRawData("data123xxx\0", 11));
QCOMPARE(array.size(), 11);
}
void tst_QByteArray::insert()
@ -976,6 +984,12 @@ void tst_QByteArray::insert()
QCOMPARE(ba.insert(1, 'b'), QByteArray("abc"));
QCOMPARE(ba.size(), 3);
ba = "ac";
QCOMPARE(ba.insert(-1, 3, 'x'), QByteArray("ac"));
QCOMPARE(ba.insert(1, 3, 'x'), QByteArray("axxxc"));
QCOMPARE(ba.insert(6, 3, 'x'), QByteArray("axxxc xxx"));
QCOMPARE(ba.size(), 9);
ba = "ikl";
QCOMPARE(ba.insert(1, "j"), QByteArray("ijkl"));
QCOMPARE(ba.size(), 4);
@ -994,7 +1008,8 @@ void tst_QByteArray::insertExtended()
{
QFETCH(QByteArray, array);
QCOMPARE(array.insert(1, "i"), QByteArray("diata"));
QCOMPARE(array.size(), 5);
QCOMPARE(array.insert(1, 3, 'x'), QByteArray("dxxxiata"));
QCOMPARE(array.size(), 8);
}
void tst_QByteArray::remove_data()