From 2ac4c463afdb8a62b0abb8ba444f34ca50e8979c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 4 Apr 2012 15:36:09 +0200 Subject: Make QByteArray and QString keep track of terminating null MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In conceptual terms, this change increments the Data::alloc member by one for all strings allocated and maintained by these classes. Instances initialized with fromRawData retain 0 as the member value, so they are treated as immutable. This brings QByteArray and QString closer to QVector, making it possible for them to reference and share the same data in memory, in the future. It also brings them closer to QArrayData. In practical terms all comparisons to the alloc member were changed to take into account that it also tracks the terminating null character. Aside from the increment in the alloc member, there should be no user visible changes. Change-Id: I618f49022a9b1845754500c8f8706c72a68b9c7d Reviewed-by: João Abecasis Reviewed-by: Thiago Macieira --- src/corelib/tools/qbytearray.cpp | 46 +++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'src/corelib/tools/qbytearray.cpp') diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 43f666e075..1e1fb7903c 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -579,7 +579,7 @@ QByteArray qUncompress(const uchar* data, int nbytes) } d->ref.initializeOwned(); d->size = len; - d->alloc = len; + d->alloc = uint(len) + 1u; d->capacityReserved = false; d->offset = sizeof(QByteArrayData); d->data()[len] = 0; @@ -918,10 +918,11 @@ QByteArray &QByteArray::operator=(const char *str) x = shared_empty.data_ptr(); } else { int len = strlen(str); - if (d->ref.isShared() || len > int(d->alloc) || (len < d->size && len < int(d->alloc) >> 1)) + if (d->ref.isShared() || uint(len) + 1u > d->alloc + || (len < d->size && uint(len) + 1u < uint(d->alloc >> 1))) reallocData(uint(len) + 1u); x = d; - memcpy(x->data(), str, len + 1); // include null terminator + memcpy(x->data(), str, uint(len) + 1u); // include null terminator x->size = len; } x->ref.ref(); @@ -1328,11 +1329,11 @@ QByteArray::QByteArray(const char *data, int size) if (!size) { d = shared_empty.data_ptr(); } else { - d = static_cast(malloc(sizeof(Data) + size + 1)); + d = static_cast(::malloc(sizeof(Data) + uint(size) + 1u)); Q_CHECK_PTR(d); d->ref.initializeOwned(); d->size = size; - d->alloc = size; + d->alloc = uint(size) + 1u; d->capacityReserved = false; d->offset = sizeof(QByteArrayData); memcpy(d->data(), data, size); @@ -1353,11 +1354,11 @@ QByteArray::QByteArray(int size, char ch) if (size <= 0) { d = shared_empty.data_ptr(); } else { - d = static_cast(malloc(sizeof(Data) + size + 1)); + d = static_cast(::malloc(sizeof(Data) + uint(size) + 1u)); Q_CHECK_PTR(d); d->ref.initializeOwned(); d->size = size; - d->alloc = size; + d->alloc = uint(size) + 1u; d->capacityReserved = false; d->offset = sizeof(QByteArrayData); memset(d->data(), ch, size); @@ -1373,11 +1374,11 @@ QByteArray::QByteArray(int size, char ch) QByteArray::QByteArray(int size, Qt::Initialization) { - d = static_cast(malloc(sizeof(Data) + size + 1)); + d = static_cast(::malloc(sizeof(Data) + uint(size) + 1u)); Q_CHECK_PTR(d); d->ref.initializeOwned(); d->size = size; - d->alloc = size; + d->alloc = uint(size) + 1u; d->capacityReserved = false; d->offset = sizeof(QByteArrayData); d->data()[size] = '\0'; @@ -1420,18 +1421,19 @@ void QByteArray::resize(int size) // which is used in place of the Qt 3 idiom: // QByteArray a(sz); // - Data *x = static_cast(malloc(sizeof(Data) + size + 1)); + Data *x = static_cast(::malloc(sizeof(Data) + uint(size) + 1u)); Q_CHECK_PTR(x); x->ref.initializeOwned(); x->size = size; - x->alloc = size; + x->alloc = uint(size) + 1u; x->capacityReserved = false; x->offset = sizeof(QByteArrayData); x->data()[size] = '\0'; d = x; } else { - if (d->ref.isShared() || size > int(d->alloc) - || (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1)) + 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); if (d->alloc) { d->size = size; @@ -1469,7 +1471,7 @@ void QByteArray::reallocData(uint alloc, bool grow) Q_CHECK_PTR(x); x->ref.initializeOwned(); x->size = qMin(int(alloc) - 1, d->size); - x->alloc = alloc - 1u; + x->alloc = alloc; x->capacityReserved = d->capacityReserved; x->offset = sizeof(QByteArrayData); ::memcpy(x->data(), d->data(), x->size); @@ -1480,7 +1482,7 @@ void QByteArray::reallocData(uint alloc, bool grow) } else { Data *x = static_cast(::realloc(d, sizeof(Data) + alloc)); Q_CHECK_PTR(x); - x->alloc = alloc - 1u; + x->alloc = alloc; x->offset = sizeof(QByteArrayData); d = x; } @@ -1565,7 +1567,7 @@ QByteArray &QByteArray::prepend(const char *str) QByteArray &QByteArray::prepend(const char *str, int len) { if (str) { - if (d->ref.isShared() || d->size + len > int(d->alloc)) + if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc) reallocData(uint(d->size + len) + 1u, true); memmove(d->data()+len, d->data(), d->size); memcpy(d->data(), str, len); @@ -1583,7 +1585,7 @@ QByteArray &QByteArray::prepend(const char *str, int len) QByteArray &QByteArray::prepend(char ch) { - if (d->ref.isShared() || d->size + 1 > int(d->alloc)) + if (d->ref.isShared() || uint(d->size) + 2u > d->alloc) reallocData(uint(d->size) + 2u, true); memmove(d->data()+1, d->data(), d->size); d->data()[0] = ch; @@ -1621,7 +1623,7 @@ QByteArray &QByteArray::append(const QByteArray &ba) if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) { *this = ba; } else if (ba.d != &shared_null.ba) { - if (d->ref.isShared() || d->size + ba.d->size > int(d->alloc)) + if (d->ref.isShared() || uint(d->size + ba.d->size) + 1u > d->alloc) reallocData(uint(d->size + ba.d->size) + 1u, true); memcpy(d->data() + d->size, ba.d->data(), ba.d->size); d->size += ba.d->size; @@ -1655,7 +1657,7 @@ QByteArray& QByteArray::append(const char *str) { if (str) { int len = strlen(str); - if (d->ref.isShared() || d->size + len > int(d->alloc)) + if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc) reallocData(uint(d->size + len) + 1u, true); memcpy(d->data() + d->size, str, len + 1); // include null terminator d->size += len; @@ -1680,7 +1682,7 @@ QByteArray &QByteArray::append(const char *str, int len) if (len < 0) len = qstrlen(str); if (str && len) { - if (d->ref.isShared() || d->size + len > int(d->alloc)) + if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc) reallocData(uint(d->size + len) + 1u, true); memcpy(d->data() + d->size, str, len); // include null terminator d->size += len; @@ -1697,7 +1699,7 @@ QByteArray &QByteArray::append(const char *str, int len) QByteArray& QByteArray::append(char ch) { - if (d->ref.isShared() || d->size + 1 > int(d->alloc)) + if (d->ref.isShared() || uint(d->size) + 2u > d->alloc) reallocData(uint(d->size) + 2u, true); d->data()[d->size++] = ch; d->data()[d->size] = '\0'; @@ -2206,7 +2208,7 @@ QByteArray QByteArray::repeated(int times) const QByteArray result; result.reserve(resultSize); - if (int(result.d->alloc) != resultSize) + if (result.d->alloc != uint(resultSize) + 1u) return QByteArray(); // not enough memory memcpy(result.d->data(), d->data(), d->size); -- cgit v1.2.3