diff options
author | João Abecasis <joao.abecasis@nokia.com> | 2012-02-17 14:11:28 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-21 00:37:58 +0100 |
commit | 4c8a4058c359c8d163c643120426079fc80c8214 (patch) | |
tree | 282de013f6e6caa4ee2071335bda367fbd944a4f | |
parent | ebeebe212624b0d6fb87266629dce20ee75391bd (diff) |
Change meaning of offset in QByteArrayData
It used to be an index into the first element in 'd' that came after
'offset'. It is now the byte offset from the beginning of the
QByteArrayData structure.
By no longer using an actual array to access characters, we also steer
clear of GCC bug #43247:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43247
This aligns this data structure with QArrayData. The intention is to
have QVector, QString and QByteArray share the same memory layout and
possibly code.
Change-Id: I8546e5f51cd2161ba09bd4ada174b7f5e6f09db7
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | src/corelib/tools/qbytearray.cpp | 34 | ||||
-rw-r--r-- | src/corelib/tools/qbytearray.h | 17 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp | 2 |
3 files changed, 26 insertions, 27 deletions
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 559ba193d1..0d5c0f59ba 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -57,7 +57,7 @@ #include <string.h> #include <stdlib.h> -#define IS_RAW_DATA(d) ((d)->offset != 0) +#define IS_RAW_DATA(d) ((d)->offset != sizeof(QByteArrayData)) QT_BEGIN_NAMESPACE @@ -555,7 +555,7 @@ QByteArray qUncompress(const uchar* data, int nbytes) } d.take(); // realloc was successful d.reset(p); - d->offset = 0; + d->offset = sizeof(QByteArrayData); int res = ::uncompress((uchar*)d->data(), &len, (uchar*)data+4, nbytes-4); @@ -581,7 +581,7 @@ QByteArray qUncompress(const uchar* data, int nbytes) d->size = len; d->alloc = len; d->capacityReserved = false; - d->offset = 0; + d->offset = sizeof(QByteArrayData); d->data()[len] = 0; return QByteArray(d.take(), 0, 0); @@ -616,9 +616,9 @@ static inline char qToLower(char c) } const QStaticByteArrayData<1> QByteArray::shared_null = { { Q_REFCOUNT_INITIALIZE_STATIC, - 0, 0, 0, { 0 } }, { 0 } }; + 0, 0, 0, sizeof(QByteArrayData) }, { 0 } }; const QStaticByteArrayData<1> QByteArray::shared_empty = { { Q_REFCOUNT_INITIALIZE_STATIC, - 0, 0, 0, { 0 } }, { 0 } }; + 0, 0, 0, sizeof(QByteArrayData) }, { 0 } }; /*! \class QByteArray @@ -1319,7 +1319,7 @@ QByteArray::QByteArray(const char *data, int size) d->size = size; d->alloc = size; d->capacityReserved = false; - d->offset = 0; + d->offset = sizeof(QByteArrayData); memcpy(d->data(), data, size); d->data()[size] = '\0'; } @@ -1344,7 +1344,7 @@ QByteArray::QByteArray(int size, char ch) d->size = size; d->alloc = size; d->capacityReserved = false; - d->offset = 0; + d->offset = sizeof(QByteArrayData); memset(d->data(), ch, size); d->data()[size] = '\0'; } @@ -1364,7 +1364,7 @@ QByteArray::QByteArray(int size, Qt::Initialization) d->size = size; d->alloc = size; d->capacityReserved = false; - d->offset = 0; + d->offset = sizeof(QByteArrayData); d->data()[size] = '\0'; } @@ -1386,7 +1386,7 @@ void QByteArray::resize(int size) if (size < 0) size = 0; - if (d->offset && !d->ref.isShared() && size < d->size) { + if (IS_RAW_DATA(d) && !d->ref.isShared() && size < d->size) { d->size = size; return; } @@ -1411,7 +1411,7 @@ void QByteArray::resize(int size) x->size = size; x->alloc = size; x->capacityReserved = false; - x->offset = 0; + x->offset = sizeof(QByteArrayData); x->data()[size] = '\0'; d = x; } else { @@ -1446,14 +1446,14 @@ QByteArray &QByteArray::fill(char ch, int size) void QByteArray::realloc(int alloc) { - if (d->ref.isShared() || d->offset) { + if (d->ref.isShared() || IS_RAW_DATA(d)) { Data *x = static_cast<Data *>(malloc(sizeof(Data) + alloc + 1)); Q_CHECK_PTR(x); x->ref.initializeOwned(); x->size = qMin(alloc, d->size); x->alloc = alloc; x->capacityReserved = d->capacityReserved; - x->offset = 0; + x->offset = sizeof(QByteArrayData); ::memcpy(x->data(), d->data(), x->size); x->data()[x->size] = '\0'; if (!d->ref.deref()) @@ -1463,7 +1463,7 @@ void QByteArray::realloc(int alloc) Data *x = static_cast<Data *>(::realloc(d, sizeof(Data) + alloc + 1)); Q_CHECK_PTR(x); x->alloc = alloc; - x->offset = 0; + x->offset = sizeof(QByteArrayData); d = x; } } @@ -1485,7 +1485,7 @@ void QByteArray::expand(int i) QByteArray QByteArray::nulTerminated() const { // is this fromRawData? - if (!d->offset) + if (!IS_RAW_DATA(d)) return *this; // no, then we're sure we're zero terminated QByteArray copy(*this); @@ -3874,7 +3874,7 @@ QByteArray QByteArray::fromRawData(const char *data, int size) x->size = size; x->alloc = 0; x->capacityReserved = false; - x->offset = data - (x->d + sizeof(qptrdiff)); + x->offset = data - reinterpret_cast<char *>(x); } return QByteArray(x, 0, 0); } @@ -3900,9 +3900,9 @@ QByteArray &QByteArray::setRawData(const char *data, uint size) } else { if (data) { d->size = size; - d->offset = data - (d->d + sizeof(qptrdiff)); + d->offset = data - reinterpret_cast<char *>(d); } else { - d->offset = 0; + d->offset = sizeof(QByteArrayData); d->size = 0; *d->data() = 0; } diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index c4feb63814..c654673959 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -124,12 +124,11 @@ struct QByteArrayData int size; uint alloc : 31; uint capacityReserved : 1; - union { - qptrdiff offset; // will always work as we add/subtract from a ushort ptr - char d[sizeof(qptrdiff)]; - }; - inline char *data() { return d + sizeof(qptrdiff) + offset; } - inline const char *data() const { return d + sizeof(qptrdiff) + offset; } + + qptrdiff offset; + + inline char *data() { return reinterpret_cast<char *>(this) + offset; } + inline const char *data() const { return reinterpret_cast<const char *>(this) + offset; } }; template<int N> struct QStaticByteArrayData @@ -148,7 +147,7 @@ template<int N> struct QStaticByteArrayDataPtr # define QByteArrayLiteral(str) ([]() -> QStaticByteArrayDataPtr<sizeof(str) - 1> { \ enum { Size = sizeof(str) - 1 }; \ static const QStaticByteArrayData<Size> qbytearray_literal = \ - { { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, { 0 } }, str }; \ + { { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, sizeof(QByteArrayData) }, str }; \ QStaticByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \ return holder; }()) @@ -161,7 +160,7 @@ template<int N> struct QStaticByteArrayDataPtr __extension__ ({ \ enum { Size = sizeof(str) - 1 }; \ static const QStaticByteArrayData<Size> qbytearray_literal = \ - { { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, { 0 } }, str }; \ + { { Q_REFCOUNT_INITIALIZE_STATIC, Size, 0, 0, sizeof(QByteArrayData) }, str }; \ QStaticByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \ holder; }) #endif @@ -427,7 +426,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) realloc(d->size); } +{ if (d->ref.isShared() || (d->offset != sizeof(QByteArrayData))) realloc(d->size); } inline bool QByteArray::isDetached() const { return !d->ref.isShared(); } inline QByteArray::QByteArray(const QByteArray &a) : d(a.d) diff --git a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp index 4fb74a2af5..e442aa7e1a 100644 --- a/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/corelib/tools/qbytearray/tst_qbytearray.cpp @@ -1592,7 +1592,7 @@ void tst_QByteArray::literals() QVERIFY(str.length() == 4); QVERIFY(str == "abcd"); QVERIFY(str.data_ptr()->ref.isStatic()); - QVERIFY(str.data_ptr()->offset == 0); + QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData)); const char *s = str.constData(); QByteArray str2 = str; |