diff options
Diffstat (limited to 'src/corelib/tools/qbytearray.h')
-rw-r--r-- | src/corelib/tools/qbytearray.h | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 194555334f..45be63aa9b 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -44,6 +44,7 @@ #include <QtCore/qrefcount.h> #include <QtCore/qnamespace.h> +#include <QtCore/qarraydata.h> #include <stdlib.h> #include <string.h> @@ -121,6 +122,8 @@ template <typename T> class QList; struct QByteArrayData { + // Keep in sync with QArrayData + QtPrivate::RefCount ref; int size; uint alloc : 31; @@ -132,6 +135,12 @@ struct QByteArrayData inline const char *data() const { return reinterpret_cast<const char *>(this) + offset; } }; +Q_STATIC_ASSERT(sizeof(QArrayData) == sizeof(QByteArrayData)); +Q_STATIC_ASSERT(offsetof(QArrayData, ref) == offsetof(QByteArrayData, ref)); +Q_STATIC_ASSERT(offsetof(QArrayData, size) == offsetof(QByteArrayData, size)); +// Can't use offsetof on bitfield members alloc, capacityReserved +Q_STATIC_ASSERT(offsetof(QArrayData, offset) == offsetof(QByteArrayData, offset)); + template<int N> struct QStaticByteArrayData { QByteArrayData ba; @@ -194,11 +203,10 @@ struct QByteArrayDataPtr # define QByteArrayLiteral(str) (str) #endif - class Q_CORE_EXPORT QByteArray { private: - typedef QByteArrayData Data; + typedef QTypedArrayData<char> Data; public: inline QByteArray(); @@ -399,14 +407,15 @@ public: int length() const { return d->size; } bool isNull() const; - Q_DECL_CONSTEXPR inline QByteArray(QByteArrayDataPtr dd) : d(dd.ptr) {} + Q_DECL_CONSTEXPR inline QByteArray(QByteArrayDataPtr dd) + : d(reinterpret_cast<Data *>(dd.ptr)) + { + } private: operator QNoImplicitBoolCast() const; - static const QStaticByteArrayData<1> shared_null; - static const QStaticByteArrayData<1> shared_empty; Data *d; - void reallocData(uint alloc, bool grow = false); + void reallocData(uint alloc, Data::AllocationOptions options); void expand(int i); QByteArray nulTerminated() const; @@ -418,8 +427,8 @@ public: inline DataPtr &data_ptr() { return d; } }; -inline QByteArray::QByteArray(): d(shared_null.data_ptr()) { } -inline QByteArray::~QByteArray() { if (!d->ref.deref()) free(d); } +inline QByteArray::QByteArray(): d(Data::sharedNull()) { } +inline QByteArray::~QByteArray() { if (!d->ref.deref()) Data::deallocate(d); } inline int QByteArray::size() const { return d->size; } @@ -445,32 +454,31 @@ 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) { d->ref.ref(); } inline int QByteArray::capacity() const -{ return d->alloc; } +{ return d->alloc ? d->alloc - 1 : 0; } inline void QByteArray::reserve(int asize) { - if (d->ref.isShared() || asize > int(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() || d->size < int(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; |