diff options
Diffstat (limited to 'src/corelib/tools/qbytearray.cpp')
-rw-r--r-- | src/corelib/tools/qbytearray.cpp | 142 |
1 files changed, 57 insertions, 85 deletions
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 43f666e075..31cf65b78d 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -579,13 +579,13 @@ 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; { - QByteArrayDataPtr dataPtr = { d.take() }; + QByteArrayDataPtr dataPtr = { reinterpret_cast<QByteArrayData *>(d.take()) }; return QByteArray(dataPtr); } @@ -618,9 +618,6 @@ static inline char qToLower(char c) return c; } -const QStaticByteArrayData<1> QByteArray::shared_null = { Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(0), { 0 } }; -const QStaticByteArrayData<1> QByteArray::shared_empty = { Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(0), { 0 } }; - /*! \class QByteArray \brief The QByteArray class provides an array of bytes. @@ -897,7 +894,7 @@ QByteArray &QByteArray::operator=(const QByteArray & other) { other.d->ref.ref(); if (!d->ref.deref()) - free(d); + Data::deallocate(d); d = other.d; return *this; } @@ -913,20 +910,21 @@ QByteArray &QByteArray::operator=(const char *str) { Data *x; if (!str) { - x = shared_null.data_ptr(); + x = Data::sharedNull(); } else if (!*str) { - x = shared_empty.data_ptr(); + x = Data::allocate(0); } else { int len = strlen(str); - if (d->ref.isShared() || len > int(d->alloc) || (len < d->size && len < int(d->alloc) >> 1)) - reallocData(uint(len) + 1u); + if (d->ref.isShared() || uint(len) + 1u > d->alloc + || (len < d->size && uint(len) + 1u < uint(d->alloc >> 1))) + reallocData(uint(len) + 1u, d->detachFlags()); 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(); if (!d->ref.deref()) - free(d); + Data::deallocate(d); d = x; return *this; } @@ -1321,20 +1319,16 @@ void QByteArray::chop(int n) QByteArray::QByteArray(const char *data, int size) { if (!data) { - d = shared_null.data_ptr(); + d = Data::sharedNull(); } else { if (size < 0) size = strlen(data); if (!size) { - d = shared_empty.data_ptr(); + d = Data::allocate(0); } else { - d = static_cast<Data *>(malloc(sizeof(Data) + size + 1)); + d = Data::allocate(uint(size) + 1u); Q_CHECK_PTR(d); - d->ref.initializeOwned(); d->size = size; - d->alloc = size; - d->capacityReserved = false; - d->offset = sizeof(QByteArrayData); memcpy(d->data(), data, size); d->data()[size] = '\0'; } @@ -1351,15 +1345,11 @@ QByteArray::QByteArray(const char *data, int size) QByteArray::QByteArray(int size, char ch) { if (size <= 0) { - d = shared_empty.data_ptr(); + d = Data::allocate(0); } else { - d = static_cast<Data *>(malloc(sizeof(Data) + size + 1)); + d = Data::allocate(uint(size) + 1u); Q_CHECK_PTR(d); - d->ref.initializeOwned(); d->size = size; - d->alloc = size; - d->capacityReserved = false; - d->offset = sizeof(QByteArrayData); memset(d->data(), ch, size); d->data()[size] = '\0'; } @@ -1373,13 +1363,9 @@ QByteArray::QByteArray(int size, char ch) QByteArray::QByteArray(int size, Qt::Initialization) { - d = static_cast<Data *>(malloc(sizeof(Data) + size + 1)); + d = Data::allocate(uint(size) + 1u); Q_CHECK_PTR(d); - d->ref.initializeOwned(); d->size = size; - d->alloc = size; - d->capacityReserved = false; - d->offset = sizeof(QByteArrayData); d->data()[size] = '\0'; } @@ -1395,7 +1381,6 @@ QByteArray::QByteArray(int size, Qt::Initialization) \sa size(), truncate() */ - void QByteArray::resize(int size) { if (size < 0) @@ -1407,11 +1392,11 @@ void QByteArray::resize(int size) } if (size == 0 && !d->capacityReserved) { - Data *x = shared_empty.data_ptr(); + Data *x = Data::allocate(0); if (!d->ref.deref()) - free(d); + Data::deallocate(d); d = x; - } else if (d == &shared_null.ba || d == &shared_empty.ba) { + } else if (d->size == 0 && d->ref.isStatic()) { // // Optimize the idiom: // QByteArray a; @@ -1420,19 +1405,16 @@ void QByteArray::resize(int size) // which is used in place of the Qt 3 idiom: // QByteArray a(sz); // - Data *x = static_cast<Data *>(malloc(sizeof(Data) + size + 1)); + Data *x = Data::allocate(uint(size) + 1u); Q_CHECK_PTR(x); - x->ref.initializeOwned(); x->size = size; - x->alloc = size; - 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)) - reallocData(uint(size) + 1u, true); + 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, d->detachFlags() | Data::Grow); if (d->alloc) { d->size = size; d->data()[size] = '\0'; @@ -1459,29 +1441,24 @@ 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 = static_cast<Data *>(malloc(sizeof(Data) + alloc)); + Data *x = Data::allocate(alloc, options); Q_CHECK_PTR(x); - x->ref.initializeOwned(); x->size = qMin(int(alloc) - 1, d->size); - x->alloc = alloc - 1u; - x->capacityReserved = d->capacityReserved; - x->offset = sizeof(QByteArrayData); ::memcpy(x->data(), d->data(), x->size); x->data()[x->size] = '\0'; if (!d->ref.deref()) - free(d); + Data::deallocate(d); d = x; } else { + if (options & Data::Grow) + alloc = qAllocMore(alloc, sizeof(Data)); Data *x = static_cast<Data *>(::realloc(d, sizeof(Data) + alloc)); Q_CHECK_PTR(x); - x->alloc = alloc - 1u; - x->offset = sizeof(QByteArrayData); + x->alloc = alloc; + x->capacityReserved = (options & Data::CapacityReserved) ? 1 : 0; d = x; } } @@ -1534,9 +1511,9 @@ QByteArray QByteArray::nulTerminated() const QByteArray &QByteArray::prepend(const QByteArray &ba) { - if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) { + if (d->size == 0 && d->ref.isStatic() && !IS_RAW_DATA(ba.d)) { *this = ba; - } else if (ba.d != &shared_null.ba) { + } else if (ba.d->size != 0) { QByteArray tmp = *this; *this = ba; append(tmp); @@ -1565,8 +1542,8 @@ 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)) - reallocData(uint(d->size + len) + 1u, true); + if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc) + 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; @@ -1583,8 +1560,8 @@ QByteArray &QByteArray::prepend(const char *str, int len) QByteArray &QByteArray::prepend(char ch) { - if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - reallocData(uint(d->size) + 2u, true); + if (d->ref.isShared() || uint(d->size) + 2u > d->alloc) + reallocData(uint(d->size) + 2u, d->detachFlags() | Data::Grow); memmove(d->data()+1, d->data(), d->size); d->data()[0] = ch; ++d->size; @@ -1618,11 +1595,11 @@ QByteArray &QByteArray::prepend(char ch) QByteArray &QByteArray::append(const QByteArray &ba) { - if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) { + if (d->size == 0 && d->ref.isStatic() && !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)) - reallocData(uint(d->size + ba.d->size) + 1u, true); + } 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, 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'; @@ -1655,8 +1632,8 @@ QByteArray& QByteArray::append(const char *str) { if (str) { int len = strlen(str); - if (d->ref.isShared() || d->size + len > int(d->alloc)) - reallocData(uint(d->size + len) + 1u, true); + if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc) + reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::Grow); memcpy(d->data() + d->size, str, len + 1); // include null terminator d->size += len; } @@ -1680,8 +1657,8 @@ 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)) - reallocData(uint(d->size + len) + 1u, true); + if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc) + 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'; @@ -1697,8 +1674,8 @@ QByteArray &QByteArray::append(const char *str, int len) QByteArray& QByteArray::append(char ch) { - if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - reallocData(uint(d->size) + 2u, true); + if (d->ref.isShared() || uint(d->size) + 2u > d->alloc) + reallocData(uint(d->size) + 2u, d->detachFlags() | Data::Grow); d->data()[d->size++] = ch; d->data()[d->size] = '\0'; return *this; @@ -2206,7 +2183,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); @@ -2661,7 +2638,7 @@ QByteArray QByteArray::right(int len) const QByteArray QByteArray::mid(int pos, int len) const { - if (d == &shared_null.ba || d == &shared_empty.ba || pos > d->size) + if ((d->size == 0 && d->ref.isStatic()) || pos > d->size) return QByteArray(); if (len < 0) len = d->size - pos; @@ -2731,8 +2708,8 @@ QByteArray QByteArray::toUpper() const void QByteArray::clear() { if (!d->ref.deref()) - free(d); - d = shared_null.data_ptr(); + Data::deallocate(d); + d = Data::sharedNull(); } #if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE)) @@ -3174,7 +3151,7 @@ QByteArray QByteArray::trimmed() const } int l = end - start + 1; if (l <= 0) { - QByteArrayDataPtr empty = { shared_empty.data_ptr() }; + QByteArrayDataPtr empty = { reinterpret_cast<QByteArrayData *>(Data::allocate(0)) }; return QByteArray(empty); } return QByteArray(s+start, l); @@ -3254,7 +3231,7 @@ QByteArray QByteArray::rightJustified(int width, char fill, bool truncate) const return result; } -bool QByteArray::isNull() const { return d == &shared_null.ba; } +bool QByteArray::isNull() const { return d == QArrayData::sharedNull(); } /*! @@ -3882,19 +3859,14 @@ QByteArray QByteArray::fromRawData(const char *data, int size) { Data *x; if (!data) { - x = shared_null.data_ptr(); + x = Data::sharedNull(); } else if (!size) { - x = shared_empty.data_ptr(); + x = Data::allocate(0); } else { - x = static_cast<Data *>(malloc(sizeof(Data))); + x = Data::fromRawData(data, size); Q_CHECK_PTR(x); - x->ref.initializeOwned(); - x->size = size; - x->alloc = 0; - x->capacityReserved = false; - x->offset = data - reinterpret_cast<char *>(x); } - QByteArrayDataPtr dataPtr = { x }; + QByteArrayDataPtr dataPtr = { reinterpret_cast<QByteArrayData *>(x) }; return QByteArray(dataPtr); } |