From 76d61af1e272628aa38f088ea10ec7076fae8b06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 6 Apr 2012 10:12:36 +0200 Subject: Make reallocData use QArrayData::AllocationOptions Growth computations are deferred to QArrayData::allocate, except in the case of realloc as that functionality is currently lacking in QArrayData. Since that sits in library code, anyway, it can be changed later to use a future QArrayData::reallocate. As it is, reallocData is becoming a model for QArrayData::reallocate and what it can offer to containers of POD/movable types. Change-Id: I045483f729114be43e4818149d1be1b333bcbe13 Reviewed-by: Thiago Macieira --- src/corelib/tools/qbytearray.cpp | 26 +++++++++++++------------- src/corelib/tools/qbytearray.h | 21 ++++++++++----------- 2 files changed, 23 insertions(+), 24 deletions(-) (limited to 'src/corelib/tools') diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index c8f0447739..31cf65b78d 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -917,7 +917,7 @@ QByteArray &QByteArray::operator=(const char *str) int len = strlen(str); if (d->ref.isShared() || uint(len) + 1u > d->alloc || (len < d->size && uint(len) + 1u < uint(d->alloc >> 1))) - reallocData(uint(len) + 1u); + reallocData(uint(len) + 1u, d->detachFlags()); x = d; memcpy(x->data(), str, uint(len) + 1u); // include null terminator x->size = len; @@ -1414,7 +1414,7 @@ void QByteArray::resize(int size) if (d->ref.isShared() || uint(size) + 1u > d->alloc || (!d->capacityReserved && size < d->size && uint(size) + 1u < uint(d->alloc >> 1))) - reallocData(uint(size) + 1u, true); + reallocData(uint(size) + 1u, d->detachFlags() | Data::Grow); if (d->alloc) { d->size = size; d->data()[size] = '\0'; @@ -1441,13 +1441,10 @@ QByteArray &QByteArray::fill(char ch, int size) return *this; } -void QByteArray::reallocData(uint alloc, bool grow) +void QByteArray::reallocData(uint alloc, Data::AllocationOptions options) { - if (grow) - alloc = qAllocMore(alloc, sizeof(Data)); - if (d->ref.isShared() || IS_RAW_DATA(d)) { - Data *x = Data::allocate(alloc); + Data *x = Data::allocate(alloc, options); Q_CHECK_PTR(x); x->size = qMin(int(alloc) - 1, d->size); ::memcpy(x->data(), d->data(), x->size); @@ -1456,9 +1453,12 @@ void QByteArray::reallocData(uint alloc, bool grow) Data::deallocate(d); d = x; } else { + if (options & Data::Grow) + alloc = qAllocMore(alloc, sizeof(Data)); Data *x = static_cast(::realloc(d, sizeof(Data) + alloc)); Q_CHECK_PTR(x); x->alloc = alloc; + x->capacityReserved = (options & Data::CapacityReserved) ? 1 : 0; d = x; } } @@ -1543,7 +1543,7 @@ QByteArray &QByteArray::prepend(const char *str, int len) { if (str) { if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc) - reallocData(uint(d->size + len) + 1u, true); + reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::Grow); memmove(d->data()+len, d->data(), d->size); memcpy(d->data(), str, len); d->size += len; @@ -1561,7 +1561,7 @@ QByteArray &QByteArray::prepend(const char *str, int len) QByteArray &QByteArray::prepend(char ch) { if (d->ref.isShared() || uint(d->size) + 2u > d->alloc) - reallocData(uint(d->size) + 2u, true); + reallocData(uint(d->size) + 2u, d->detachFlags() | Data::Grow); memmove(d->data()+1, d->data(), d->size); d->data()[0] = ch; ++d->size; @@ -1599,7 +1599,7 @@ QByteArray &QByteArray::append(const QByteArray &ba) *this = ba; } else if (ba.d->size != 0) { if (d->ref.isShared() || uint(d->size + ba.d->size) + 1u > d->alloc) - reallocData(uint(d->size + ba.d->size) + 1u, true); + reallocData(uint(d->size + ba.d->size) + 1u, d->detachFlags() | Data::Grow); memcpy(d->data() + d->size, ba.d->data(), ba.d->size); d->size += ba.d->size; d->data()[d->size] = '\0'; @@ -1633,7 +1633,7 @@ QByteArray& QByteArray::append(const char *str) if (str) { int len = strlen(str); if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc) - reallocData(uint(d->size + len) + 1u, true); + reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::Grow); memcpy(d->data() + d->size, str, len + 1); // include null terminator d->size += len; } @@ -1658,7 +1658,7 @@ QByteArray &QByteArray::append(const char *str, int len) len = qstrlen(str); if (str && len) { if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc) - reallocData(uint(d->size + len) + 1u, true); + reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::Grow); memcpy(d->data() + d->size, str, len); // include null terminator d->size += len; d->data()[d->size] = '\0'; @@ -1675,7 +1675,7 @@ QByteArray &QByteArray::append(const char *str, int len) QByteArray& QByteArray::append(char ch) { if (d->ref.isShared() || uint(d->size) + 2u > d->alloc) - reallocData(uint(d->size) + 2u, true); + reallocData(uint(d->size) + 2u, d->detachFlags() | Data::Grow); d->data()[d->size++] = ch; d->data()[d->size] = '\0'; return *this; diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 648fe6a162..f8427f66a5 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -415,7 +415,7 @@ public: private: operator QNoImplicitBoolCast() const; Data *d; - void reallocData(uint alloc, bool grow = false); + void reallocData(uint alloc, Data::AllocationOptions options); void expand(int i); QByteArray nulTerminated() const; @@ -454,7 +454,7 @@ inline const char *QByteArray::data() const inline const char *QByteArray::constData() const { return d->data(); } inline void QByteArray::detach() -{ if (d->ref.isShared() || (d->offset != sizeof(QByteArrayData))) reallocData(uint(d->size) + 1u); } +{ if (d->ref.isShared() || (d->offset != sizeof(QByteArrayData))) reallocData(uint(d->size) + 1u, d->detachFlags()); } inline bool QByteArray::isDetached() const { return !d->ref.isShared(); } inline QByteArray::QByteArray(const QByteArray &a) : d(a.d) @@ -465,21 +465,20 @@ inline int QByteArray::capacity() const inline void QByteArray::reserve(int asize) { - if (d->ref.isShared() || uint(asize) + 1u > d->alloc) - reallocData(uint(asize) + 1u); - - if (!d->capacityReserved) { - // cannot set unconditionally, since d could be the shared_null/shared_empty (which is const) + if (d->ref.isShared() || uint(asize) + 1u > d->alloc) { + reallocData(uint(asize) + 1u, d->detachFlags() | Data::CapacityReserved); + } else { + // cannot set unconditionally, since d could be the shared_null or + // otherwise static d->capacityReserved = true; } } inline void QByteArray::squeeze() { - if (d->ref.isShared() || uint(d->size) + 1u < d->alloc) - reallocData(uint(d->size) + 1u); - - if (d->capacityReserved) { + if (d->ref.isShared() || uint(d->size) + 1u < d->alloc) { + reallocData(uint(d->size) + 1u, d->detachFlags() & ~Data::CapacityReserved); + } else { // cannot set unconditionally, since d could be shared_null or // otherwise static. d->capacityReserved = false; -- cgit v1.2.3