Move growth computation to re-allocation function

Callers of QByteArray/QString::realloc() are still responsible for the
heuristics and decide whether to provide the "grow" hint, but
computation is centralized there.

With this change we also ensure growth takes into account the
terminating null. Previously, calls to qAllocMore took into account
header and string size, for left out the null, meaning we ended up
allocating ("nice-size" + Null).

Change-Id: Iad1536e7706cd2d446daee96859db9b01c5f9680
Reviewed-by: Marius Storm-Olsen <marius.storm-olsen@nokia.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
João Abecasis 2012-04-04 13:50:21 +02:00 committed by Qt by Nokia
parent 7488b79652
commit e5d10b2a3b
4 changed files with 22 additions and 22 deletions

View File

@ -1432,7 +1432,7 @@ void QByteArray::resize(int size)
} else {
if (d->ref.isShared() || size > int(d->alloc)
|| (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
realloc(qAllocMore(size, sizeof(Data)));
realloc(size, true);
if (int(d->alloc) >= size) {
d->size = size;
d->data()[size] = '\0';
@ -1459,8 +1459,11 @@ QByteArray &QByteArray::fill(char ch, int size)
return *this;
}
void QByteArray::realloc(int alloc)
void QByteArray::realloc(int alloc, bool grow)
{
if (grow)
alloc = qAllocMore(alloc + 1, sizeof(Data)) - 1;
if (d->ref.isShared() || IS_RAW_DATA(d)) {
Data *x = static_cast<Data *>(malloc(sizeof(Data) + alloc + 1));
Q_CHECK_PTR(x);
@ -1563,7 +1566,7 @@ QByteArray &QByteArray::prepend(const char *str, int len)
{
if (str) {
if (d->ref.isShared() || d->size + len > int(d->alloc))
realloc(qAllocMore(d->size + len, sizeof(Data)));
realloc(d->size + len, true);
memmove(d->data()+len, d->data(), d->size);
memcpy(d->data(), str, len);
d->size += len;
@ -1581,7 +1584,7 @@ QByteArray &QByteArray::prepend(const char *str, int len)
QByteArray &QByteArray::prepend(char ch)
{
if (d->ref.isShared() || d->size + 1 > int(d->alloc))
realloc(qAllocMore(d->size + 1, sizeof(Data)));
realloc(d->size + 1, true);
memmove(d->data()+1, d->data(), d->size);
d->data()[0] = ch;
++d->size;
@ -1619,7 +1622,7 @@ QByteArray &QByteArray::append(const QByteArray &ba)
*this = ba;
} else if (ba.d != &shared_null.ba) {
if (d->ref.isShared() || d->size + ba.d->size > int(d->alloc))
realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
realloc(d->size + ba.d->size, true);
memcpy(d->data() + d->size, ba.d->data(), ba.d->size);
d->size += ba.d->size;
d->data()[d->size] = '\0';
@ -1653,7 +1656,7 @@ QByteArray& QByteArray::append(const char *str)
if (str) {
int len = strlen(str);
if (d->ref.isShared() || d->size + len > int(d->alloc))
realloc(qAllocMore(d->size + len, sizeof(Data)));
realloc(d->size + len, true);
memcpy(d->data() + d->size, str, len + 1); // include null terminator
d->size += len;
}
@ -1678,7 +1681,7 @@ QByteArray &QByteArray::append(const char *str, int len)
len = qstrlen(str);
if (str && len) {
if (d->ref.isShared() || d->size + len > int(d->alloc))
realloc(qAllocMore(d->size + len, sizeof(Data)));
realloc(d->size + len, true);
memcpy(d->data() + d->size, str, len); // include null terminator
d->size += len;
d->data()[d->size] = '\0';
@ -1695,7 +1698,7 @@ QByteArray &QByteArray::append(const char *str, int len)
QByteArray& QByteArray::append(char ch)
{
if (d->ref.isShared() || d->size + 1 > int(d->alloc))
realloc(qAllocMore(d->size + 1, sizeof(Data)));
realloc(d->size + 1, true);
d->data()[d->size++] = ch;
d->data()[d->size] = '\0';
return *this;

View File

@ -406,7 +406,7 @@ private:
static const QStaticByteArrayData<1> shared_null;
static const QStaticByteArrayData<1> shared_empty;
Data *d;
void realloc(int alloc);
void realloc(int alloc, bool grow = false);
void expand(int i);
QByteArray nulTerminated() const;

View File

@ -799,11 +799,6 @@ const QString::Null QString::null = { };
const QStaticStringData<1> QString::shared_null = { Q_STATIC_STRING_DATA_HEADER_INITIALIZER(0), { 0 } };
const QStaticStringData<1> QString::shared_empty = { Q_STATIC_STRING_DATA_HEADER_INITIALIZER(0), { 0 } };
int QString::grow(int size)
{
return qAllocMore(size * sizeof(QChar), sizeof(Data)) / sizeof(QChar);
}
/*! \typedef QString::ConstIterator
Qt-style synonym for QString::const_iterator.
@ -1247,7 +1242,7 @@ void QString::resize(int size)
} else {
if (d->ref.isShared() || size > int(d->alloc) ||
(!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1))
realloc(grow(size));
realloc(size, true);
if (int(d->alloc) >= size) {
d->size = size;
d->data()[size] = '\0';
@ -1306,8 +1301,11 @@ void QString::resize(int size)
*/
// ### Qt 5: rename reallocData() to avoid confusion. 197625
void QString::realloc(int alloc)
void QString::realloc(int alloc, bool grow)
{
if (grow)
alloc = qAllocMore((alloc+1) * sizeof(QChar), sizeof(Data)) / sizeof(QChar) - 1;
if (d->ref.isShared() || IS_RAW_DATA(d)) {
Data *x = static_cast<Data *>(::malloc(sizeof(Data) + (alloc+1) * sizeof(QChar)));
Q_CHECK_PTR(x);
@ -1534,7 +1532,7 @@ QString &QString::append(const QString &str)
operator=(str);
} else {
if (d->ref.isShared() || d->size + str.d->size > int(d->alloc))
realloc(grow(d->size + str.d->size));
realloc(d->size + str.d->size, true);
memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar));
d->size += str.d->size;
d->data()[d->size] = '\0';
@ -1554,7 +1552,7 @@ QString &QString::append(const QLatin1String &str)
if (s) {
int len = str.size();
if (d->ref.isShared() || d->size + len > int(d->alloc))
realloc(grow(d->size + len));
realloc(d->size + len, true);
ushort *i = d->data() + d->size;
while ((*i++ = *s++))
;
@ -1597,7 +1595,7 @@ QString &QString::append(const QLatin1String &str)
QString &QString::append(QChar ch)
{
if (d->ref.isShared() || d->size + 1 > int(d->alloc))
realloc(grow(d->size + 1));
realloc(d->size + 1, true);
d->data()[d->size++] = ch.unicode();
d->data()[d->size] = '\0';
return *this;

View File

@ -372,7 +372,7 @@ public:
inline QString &operator+=(QChar c) {
if (d->ref.isShared() || d->size + 1 > int(d->alloc))
realloc(grow(d->size + 1));
realloc(d->size + 1, true);
d->data()[d->size++] = c.unicode();
d->data()[d->size] = '\0';
return *this;
@ -649,9 +649,8 @@ private:
static const QStaticStringData<1> shared_empty;
Data *d;
static int grow(int);
static void free(Data *);
void realloc(int alloc);
void realloc(int alloc, bool grow = false);
void expand(int i);
void updateProperties() const;
QString multiArg(int numArgs, const QString **args) const;