Refactor QByteArray to allow for const data
Similar refactoring as done for QString. Make shared_null read-only, and add support for compile time generated QByteArrayData. Add support for properly reserving capacity. Change-Id: Ie4c41d4caac7b3b4bb1aef40c1c860a30b82edb8 Reviewed-on: http://codereview.qt.nokia.com/1484 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Olivier Goffart <olivier.goffart@nokia.com>
This commit is contained in:
parent
9fea02400c
commit
ad35a41739
@ -57,7 +57,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define IS_RAW_DATA(d) ((d)->data != (d)->array)
|
||||
#define IS_RAW_DATA(d) ((d)->offset != 0)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -546,7 +546,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
||||
qWarning("qUncompress: Input data is corrupted");
|
||||
return QByteArray();
|
||||
}
|
||||
QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + alloc));
|
||||
QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + alloc + 1));
|
||||
if (!p) {
|
||||
// we are not allowed to crash here when compiling with QT_NO_EXCEPTIONS
|
||||
qWarning("qUncompress: could not allocate enough memory to uncompress data");
|
||||
@ -554,8 +554,9 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
||||
}
|
||||
d.take(); // realloc was successful
|
||||
d.reset(p);
|
||||
d->offset = 0;
|
||||
|
||||
int res = ::uncompress((uchar*)d->array, &len,
|
||||
int res = ::uncompress((uchar*)d->data(), &len,
|
||||
(uchar*)data+4, nbytes-4);
|
||||
|
||||
switch (res) {
|
||||
@ -566,7 +567,7 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
||||
qWarning("qUncompress: Input data is corrupted");
|
||||
return QByteArray();
|
||||
}
|
||||
QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + len));
|
||||
QByteArray::Data *p = static_cast<QByteArray::Data *>(qRealloc(d.data(), sizeof(QByteArray::Data) + len + 1));
|
||||
if (!p) {
|
||||
// we are not allowed to crash here when compiling with QT_NO_EXCEPTIONS
|
||||
qWarning("qUncompress: could not allocate enough memory to uncompress data");
|
||||
@ -576,9 +577,11 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
||||
d.reset(p);
|
||||
}
|
||||
d->ref = 1;
|
||||
d->alloc = d->size = len;
|
||||
d->data = d->array;
|
||||
d->array[len] = 0;
|
||||
d->size = len;
|
||||
d->alloc = len;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
d->data()[len] = 0;
|
||||
|
||||
return QByteArray(d.take(), 0, 0);
|
||||
|
||||
@ -611,10 +614,10 @@ static inline char qToLower(char c)
|
||||
return c;
|
||||
}
|
||||
|
||||
QByteArray::Data QByteArray::shared_null = {Q_BASIC_ATOMIC_INITIALIZER(1),
|
||||
0, 0, shared_null.array, {0} };
|
||||
QByteArray::Data QByteArray::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1),
|
||||
0, 0, shared_empty.array, {0} };
|
||||
QConstByteArrayData<1> QByteArray::shared_null = { { Q_REFCOUNT_INITIALIZER(-1),
|
||||
0, 0, 0, { 0 } }, { 0 } };
|
||||
QConstByteArrayData<1> QByteArray::shared_empty = { { Q_REFCOUNT_INITIALIZER(-1),
|
||||
0, 0, 0, { 0 } }, { 0 } };
|
||||
|
||||
/*!
|
||||
\class QByteArray
|
||||
@ -896,15 +899,15 @@ QByteArray &QByteArray::operator=(const char *str)
|
||||
{
|
||||
Data *x;
|
||||
if (!str) {
|
||||
x = &shared_null;
|
||||
x = const_cast<Data *>(&shared_null.ba);
|
||||
} else if (!*str) {
|
||||
x = &shared_empty;
|
||||
x = const_cast<Data *>(&shared_empty.ba);
|
||||
} else {
|
||||
int len = qstrlen(str);
|
||||
if (d->ref != 1 || len > d->alloc || (len < d->size && len < d->alloc >> 1))
|
||||
realloc(len);
|
||||
x = d;
|
||||
memcpy(x->data, str, len + 1); // include null terminator
|
||||
memcpy(x->data(), str, len + 1); // include null terminator
|
||||
x->size = len;
|
||||
}
|
||||
x->ref.ref();
|
||||
@ -1294,19 +1297,20 @@ void QByteArray::chop(int n)
|
||||
QByteArray::QByteArray(const char *str)
|
||||
{
|
||||
if (!str) {
|
||||
d = &shared_null;
|
||||
d = const_cast<Data *>(&shared_null.ba);
|
||||
} else if (!*str) {
|
||||
d = &shared_empty;
|
||||
d = const_cast<Data *>(&shared_empty.ba);
|
||||
} else {
|
||||
int len = qstrlen(str);
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data)+len));
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + len + 1));
|
||||
Q_CHECK_PTR(d);
|
||||
d->ref = 0;;
|
||||
d->alloc = d->size = len;
|
||||
d->data = d->array;
|
||||
memcpy(d->array, str, len+1); // include null terminator
|
||||
d->ref = 1;
|
||||
d->size = len;
|
||||
d->alloc = len;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
memcpy(d->data(), str, len+1); // include null terminator
|
||||
}
|
||||
d->ref.ref();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1323,19 +1327,20 @@ QByteArray::QByteArray(const char *str)
|
||||
QByteArray::QByteArray(const char *data, int size)
|
||||
{
|
||||
if (!data) {
|
||||
d = &shared_null;
|
||||
d = const_cast<Data *>(&shared_null.ba);
|
||||
} else if (size <= 0) {
|
||||
d = &shared_empty;
|
||||
d = const_cast<Data *>(&shared_empty.ba);
|
||||
} else {
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + size));
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + size + 1));
|
||||
Q_CHECK_PTR(d);
|
||||
d->ref = 0;
|
||||
d->alloc = d->size = size;
|
||||
d->data = d->array;
|
||||
memcpy(d->array, data, size);
|
||||
d->array[size] = '\0';
|
||||
d->ref = 1;
|
||||
d->size = size;
|
||||
d->alloc = size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
memcpy(d->data(), data, size);
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
d->ref.ref();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1348,17 +1353,18 @@ QByteArray::QByteArray(const char *data, int size)
|
||||
QByteArray::QByteArray(int size, char ch)
|
||||
{
|
||||
if (size <= 0) {
|
||||
d = &shared_null;
|
||||
d = const_cast<Data *>(&shared_null.ba);
|
||||
} else {
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data)+size));
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + size + 1));
|
||||
Q_CHECK_PTR(d);
|
||||
d->ref = 0;
|
||||
d->alloc = d->size = size;
|
||||
d->data = d->array;
|
||||
d->array[size] = '\0';
|
||||
memset(d->array, ch, size);
|
||||
d->ref = 1;
|
||||
d->size = size;
|
||||
d->alloc = size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
memset(d->data(), ch, size);
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
d->ref.ref();
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1369,12 +1375,14 @@ QByteArray::QByteArray(int size, char ch)
|
||||
|
||||
QByteArray::QByteArray(int size, Qt::Initialization)
|
||||
{
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data)+size));
|
||||
d = static_cast<Data *>(qMalloc(sizeof(Data) + size + 1));
|
||||
Q_CHECK_PTR(d);
|
||||
d->ref = 1;
|
||||
d->alloc = d->size = size;
|
||||
d->data = d->array;
|
||||
d->array[size] = '\0';
|
||||
d->size = size;
|
||||
d->alloc = size;
|
||||
d->capacityReserved = false;
|
||||
d->offset = 0;
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1392,13 +1400,20 @@ QByteArray::QByteArray(int size, Qt::Initialization)
|
||||
|
||||
void QByteArray::resize(int size)
|
||||
{
|
||||
if (size <= 0) {
|
||||
Data *x = &shared_empty;
|
||||
x->ref.ref();
|
||||
if (size < 0)
|
||||
size = 0;
|
||||
|
||||
if (d->offset && d->ref == 1 && size < d->size) {
|
||||
d->size = size;
|
||||
return;
|
||||
}
|
||||
|
||||
if (size == 0 && !d->capacityReserved) {
|
||||
Data *x = const_cast<Data *>(&shared_empty.ba);
|
||||
if (!d->ref.deref())
|
||||
qFree(d);
|
||||
d = x;
|
||||
} else if (d == &shared_null) {
|
||||
} else if (d == &shared_null.ba || d == &shared_empty.ba) {
|
||||
//
|
||||
// Optimize the idiom:
|
||||
// QByteArray a;
|
||||
@ -1407,22 +1422,21 @@ void QByteArray::resize(int size)
|
||||
// which is used in place of the Qt 3 idiom:
|
||||
// QByteArray a(sz);
|
||||
//
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data)+size));
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + size + 1));
|
||||
Q_CHECK_PTR(x);
|
||||
x->ref = 1;
|
||||
x->alloc = x->size = size;
|
||||
x->data = x->array;
|
||||
x->array[size] = '\0';
|
||||
(void) d->ref.deref(); // cannot be 0, x points to shared_null
|
||||
x->size = size;
|
||||
x->alloc = size;
|
||||
x->capacityReserved = false;
|
||||
x->offset = 0;
|
||||
x->data()[size] = '\0';
|
||||
d = x;
|
||||
} else {
|
||||
if (d->ref != 1 || size > d->alloc || (size < d->size && size < d->alloc >> 1))
|
||||
if (d->ref != 1 || size > d->alloc || (!d->capacityReserved && size < d->size && size < d->alloc >> 1))
|
||||
realloc(qAllocMore(size, sizeof(Data)));
|
||||
if (d->alloc >= size) {
|
||||
d->size = size;
|
||||
if (d->data == d->array) {
|
||||
d->array[size] = '\0';
|
||||
}
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1442,29 +1456,30 @@ QByteArray &QByteArray::fill(char ch, int size)
|
||||
{
|
||||
resize(size < 0 ? d->size : size);
|
||||
if (d->size)
|
||||
memset(d->data, ch, d->size);
|
||||
memset(d->data(), ch, d->size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void QByteArray::realloc(int alloc)
|
||||
{
|
||||
if (d->ref != 1 || d->data != d->array) {
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc));
|
||||
if (d->ref != 1 || d->offset) {
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc + 1));
|
||||
Q_CHECK_PTR(x);
|
||||
x->size = qMin(alloc, d->size);
|
||||
::memcpy(x->array, d->data, x->size);
|
||||
x->array[x->size] = '\0';
|
||||
x->ref = 1;
|
||||
x->size = qMin(alloc, d->size);
|
||||
x->alloc = alloc;
|
||||
x->data = x->array;
|
||||
x->capacityReserved = d->capacityReserved;
|
||||
x->offset = 0;
|
||||
::memcpy(x->data(), d->data(), x->size);
|
||||
x->data()[x->size] = '\0';
|
||||
if (!d->ref.deref())
|
||||
qFree(d);
|
||||
d = x;
|
||||
} else {
|
||||
Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc));
|
||||
Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc + 1));
|
||||
Q_CHECK_PTR(x);
|
||||
x->alloc = alloc;
|
||||
x->data = x->array;
|
||||
x->offset = 0;
|
||||
d = x;
|
||||
}
|
||||
}
|
||||
@ -1486,7 +1501,7 @@ void QByteArray::expand(int i)
|
||||
QByteArray QByteArray::nulTerminated() const
|
||||
{
|
||||
// is this fromRawData?
|
||||
if (d->data == d->array)
|
||||
if (!d->offset)
|
||||
return *this; // no, then we're sure we're zero terminated
|
||||
|
||||
QByteArray copy(*this);
|
||||
@ -1517,9 +1532,9 @@ QByteArray QByteArray::nulTerminated() const
|
||||
|
||||
QByteArray &QByteArray::prepend(const QByteArray &ba)
|
||||
{
|
||||
if ((d == &shared_null || d == &shared_empty) && !IS_RAW_DATA(ba.d)) {
|
||||
if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) {
|
||||
*this = ba;
|
||||
} else if (ba.d != &shared_null) {
|
||||
} else if (ba.d != &shared_null.ba) {
|
||||
QByteArray tmp = *this;
|
||||
*this = ba;
|
||||
append(tmp);
|
||||
@ -1550,10 +1565,10 @@ QByteArray &QByteArray::prepend(const char *str, int len)
|
||||
if (str) {
|
||||
if (d->ref != 1 || d->size + len > d->alloc)
|
||||
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
||||
memmove(d->data+len, d->data, d->size);
|
||||
memcpy(d->data, str, len);
|
||||
memmove(d->data()+len, d->data(), d->size);
|
||||
memcpy(d->data(), str, len);
|
||||
d->size += len;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -1568,10 +1583,10 @@ QByteArray &QByteArray::prepend(char ch)
|
||||
{
|
||||
if (d->ref != 1 || d->size + 1 > d->alloc)
|
||||
realloc(qAllocMore(d->size + 1, sizeof(Data)));
|
||||
memmove(d->data+1, d->data, d->size);
|
||||
d->data[0] = ch;
|
||||
memmove(d->data()+1, d->data(), d->size);
|
||||
d->data()[0] = ch;
|
||||
++d->size;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size] = '\0';
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -1601,14 +1616,14 @@ QByteArray &QByteArray::prepend(char ch)
|
||||
|
||||
QByteArray &QByteArray::append(const QByteArray &ba)
|
||||
{
|
||||
if ((d == &shared_null || d == &shared_empty) && !IS_RAW_DATA(ba.d)) {
|
||||
if ((d == &shared_null.ba || d == &shared_empty.ba) && !IS_RAW_DATA(ba.d)) {
|
||||
*this = ba;
|
||||
} else if (ba.d != &shared_null) {
|
||||
} else if (ba.d != &shared_null.ba) {
|
||||
if (d->ref != 1 || d->size + ba.d->size > d->alloc)
|
||||
realloc(qAllocMore(d->size + ba.d->size, sizeof(Data)));
|
||||
memcpy(d->data + d->size, ba.d->data, ba.d->size);
|
||||
memcpy(d->data() + d->size, ba.d->data(), ba.d->size);
|
||||
d->size += ba.d->size;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -1640,7 +1655,7 @@ QByteArray& QByteArray::append(const char *str)
|
||||
int len = qstrlen(str);
|
||||
if (d->ref != 1 || d->size + len > d->alloc)
|
||||
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
||||
memcpy(d->data + d->size, str, len + 1); // include null terminator
|
||||
memcpy(d->data() + d->size, str, len + 1); // include null terminator
|
||||
d->size += len;
|
||||
}
|
||||
return *this;
|
||||
@ -1665,9 +1680,9 @@ QByteArray &QByteArray::append(const char *str, int len)
|
||||
if (str && len) {
|
||||
if (d->ref != 1 || d->size + len > d->alloc)
|
||||
realloc(qAllocMore(d->size + len, sizeof(Data)));
|
||||
memcpy(d->data + d->size, str, len); // include null terminator
|
||||
memcpy(d->data() + d->size, str, len); // include null terminator
|
||||
d->size += len;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -1682,8 +1697,8 @@ QByteArray& QByteArray::append(char ch)
|
||||
{
|
||||
if (d->ref != 1 || d->size + 1 > d->alloc)
|
||||
realloc(qAllocMore(d->size + 1, sizeof(Data)));
|
||||
d->data[d->size++] = ch;
|
||||
d->data[d->size] = '\0';
|
||||
d->data()[d->size++] = ch;
|
||||
d->data()[d->size] = '\0';
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -1724,7 +1739,7 @@ static inline QByteArray &qbytearray_insert(QByteArray *ba,
|
||||
QByteArray &QByteArray::insert(int i, const QByteArray &ba)
|
||||
{
|
||||
QByteArray copy(ba);
|
||||
return qbytearray_insert(this, i, copy.d->data, copy.d->size);
|
||||
return qbytearray_insert(this, i, copy.d->data(), copy.d->size);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -1812,7 +1827,7 @@ QByteArray &QByteArray::remove(int pos, int len)
|
||||
if (pos + len >= d->size) {
|
||||
resize(pos);
|
||||
} else {
|
||||
memmove(d->data + pos, d->data + pos + len, d->size - pos - len);
|
||||
memmove(d->data() + pos, d->data() + pos + len, d->size - pos - len);
|
||||
resize(d->size - len);
|
||||
}
|
||||
return *this;
|
||||
@ -1832,7 +1847,7 @@ QByteArray &QByteArray::replace(int pos, int len, const QByteArray &after)
|
||||
{
|
||||
if (len == after.d->size && (pos + len <= d->size)) {
|
||||
detach();
|
||||
memmove(d->data + pos, after.d->data, len*sizeof(char));
|
||||
memmove(d->data() + pos, after.d->data(), len*sizeof(char));
|
||||
return *this;
|
||||
} else {
|
||||
QByteArray copy(after);
|
||||
@ -1869,7 +1884,7 @@ QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen)
|
||||
{
|
||||
if (len == alen && (pos + len <= d->size)) {
|
||||
detach();
|
||||
memcpy(d->data + pos, after, len*sizeof(char));
|
||||
memcpy(d->data() + pos, after, len*sizeof(char));
|
||||
return *this;
|
||||
} else {
|
||||
remove(pos, len);
|
||||
@ -1936,13 +1951,13 @@ QByteArray &QByteArray::replace(const char *before, int bsize, const char *after
|
||||
// protect against before or after being part of this
|
||||
const char *a = after;
|
||||
const char *b = before;
|
||||
if (after >= d->data && after < d->data + d->size) {
|
||||
if (after >= d->data() && after < d->data() + d->size) {
|
||||
char *copy = (char *)malloc(asize);
|
||||
Q_CHECK_PTR(copy);
|
||||
memcpy(copy, after, asize);
|
||||
a = copy;
|
||||
}
|
||||
if (before >= d->data && before < d->data + d->size) {
|
||||
if (before >= d->data() && before < d->data() + d->size) {
|
||||
char *copy = (char *)malloc(bsize);
|
||||
Q_CHECK_PTR(copy);
|
||||
memcpy(copy, before, bsize);
|
||||
@ -2019,7 +2034,7 @@ QByteArray &QByteArray::replace(const char *before, int bsize, const char *after
|
||||
resize(newlen);
|
||||
len = newlen;
|
||||
}
|
||||
d = this->d->data;
|
||||
d = this->d->data();
|
||||
|
||||
while(pos) {
|
||||
pos--;
|
||||
@ -2192,19 +2207,19 @@ QByteArray QByteArray::repeated(int times) const
|
||||
if (result.d->alloc != resultSize)
|
||||
return QByteArray(); // not enough memory
|
||||
|
||||
memcpy(result.d->data, d->data, d->size);
|
||||
memcpy(result.d->data(), d->data(), d->size);
|
||||
|
||||
int sizeSoFar = d->size;
|
||||
char *end = result.d->data + sizeSoFar;
|
||||
char *end = result.d->data() + sizeSoFar;
|
||||
|
||||
const int halfResultSize = resultSize >> 1;
|
||||
while (sizeSoFar <= halfResultSize) {
|
||||
memcpy(end, result.d->data, sizeSoFar);
|
||||
memcpy(end, result.d->data(), sizeSoFar);
|
||||
end += sizeSoFar;
|
||||
sizeSoFar <<= 1;
|
||||
}
|
||||
memcpy(end, result.d->data, resultSize - sizeSoFar);
|
||||
result.d->data[resultSize] = '\0';
|
||||
memcpy(end, result.d->data(), resultSize - sizeSoFar);
|
||||
result.d->data()[resultSize] = '\0';
|
||||
result.d->size = resultSize;
|
||||
return result;
|
||||
}
|
||||
@ -2231,13 +2246,13 @@ int QByteArray::indexOf(const QByteArray &ba, int from) const
|
||||
if (ol == 0)
|
||||
return from;
|
||||
if (ol == 1)
|
||||
return indexOf(*ba.d->data, from);
|
||||
return indexOf(*ba.d->data(), from);
|
||||
|
||||
const int l = d->size;
|
||||
if (from > d->size || ol + from > l)
|
||||
return -1;
|
||||
|
||||
return qFindByteArray(d->data, d->size, from, ba.d->data, ol);
|
||||
return qFindByteArray(d->data(), d->size, from, ba.d->data(), ol);
|
||||
}
|
||||
|
||||
/*! \fn int QByteArray::indexOf(const QString &str, int from) const
|
||||
@ -2279,7 +2294,7 @@ int QByteArray::indexOf(const char *c, int from) const
|
||||
if (ol == 0)
|
||||
return from;
|
||||
|
||||
return qFindByteArray(d->data, d->size, from, c, ol);
|
||||
return qFindByteArray(d->data(), d->size, from, c, ol);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2300,11 +2315,11 @@ int QByteArray::indexOf(char ch, int from) const
|
||||
if (from < 0)
|
||||
from = qMax(from + d->size, 0);
|
||||
if (from < d->size) {
|
||||
const char *n = d->data + from - 1;
|
||||
const char *e = d->data + d->size;
|
||||
const char *n = d->data() + from - 1;
|
||||
const char *e = d->data() + d->size;
|
||||
while (++n != e)
|
||||
if (*n == ch)
|
||||
return n - d->data;
|
||||
return n - d->data();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -2361,9 +2376,9 @@ int QByteArray::lastIndexOf(const QByteArray &ba, int from) const
|
||||
{
|
||||
const int ol = ba.d->size;
|
||||
if (ol == 1)
|
||||
return lastIndexOf(*ba.d->data, from);
|
||||
return lastIndexOf(*ba.d->data(), from);
|
||||
|
||||
return lastIndexOfHelper(d->data, d->size, ba.d->data, ol, from);
|
||||
return lastIndexOfHelper(d->data(), d->size, ba.d->data(), ol, from);
|
||||
}
|
||||
|
||||
/*! \fn int QByteArray::lastIndexOf(const QString &str, int from) const
|
||||
@ -2400,7 +2415,7 @@ int QByteArray::lastIndexOf(const char *str, int from) const
|
||||
if (ol == 1)
|
||||
return lastIndexOf(*str, from);
|
||||
|
||||
return lastIndexOfHelper(d->data, d->size, str, ol, from);
|
||||
return lastIndexOfHelper(d->data(), d->size, str, ol, from);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2424,8 +2439,8 @@ int QByteArray::lastIndexOf(char ch, int from) const
|
||||
else if (from > d->size)
|
||||
from = d->size-1;
|
||||
if (from >= 0) {
|
||||
const char *b = d->data;
|
||||
const char *n = d->data + from + 1;
|
||||
const char *b = d->data();
|
||||
const char *n = d->data() + from + 1;
|
||||
while (n-- != b)
|
||||
if (*n == ch)
|
||||
return n - b;
|
||||
@ -2479,8 +2494,8 @@ int QByteArray::count(const char *str) const
|
||||
int QByteArray::count(char ch) const
|
||||
{
|
||||
int num = 0;
|
||||
const char *i = d->data + d->size;
|
||||
const char *b = d->data;
|
||||
const char *i = d->data() + d->size;
|
||||
const char *b = d->data();
|
||||
while (i != b)
|
||||
if (*--i == ch)
|
||||
++num;
|
||||
@ -2509,7 +2524,7 @@ bool QByteArray::startsWith(const QByteArray &ba) const
|
||||
return true;
|
||||
if (d->size < ba.d->size)
|
||||
return false;
|
||||
return memcmp(d->data, ba.d->data, ba.d->size) == 0;
|
||||
return memcmp(d->data(), ba.d->data(), ba.d->size) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
@ -2524,7 +2539,7 @@ bool QByteArray::startsWith(const char *str) const
|
||||
int len = qstrlen(str);
|
||||
if (d->size < len)
|
||||
return false;
|
||||
return qstrncmp(d->data, str, len) == 0;
|
||||
return qstrncmp(d->data(), str, len) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
@ -2536,7 +2551,7 @@ bool QByteArray::startsWith(char ch) const
|
||||
{
|
||||
if (d->size == 0)
|
||||
return false;
|
||||
return d->data[0] == ch;
|
||||
return d->data()[0] == ch;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2554,7 +2569,7 @@ bool QByteArray::endsWith(const QByteArray &ba) const
|
||||
return true;
|
||||
if (d->size < ba.d->size)
|
||||
return false;
|
||||
return memcmp(d->data + d->size - ba.d->size, ba.d->data, ba.d->size) == 0;
|
||||
return memcmp(d->data() + d->size - ba.d->size, ba.d->data(), ba.d->size) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
@ -2569,7 +2584,7 @@ bool QByteArray::endsWith(const char *str) const
|
||||
int len = qstrlen(str);
|
||||
if (d->size < len)
|
||||
return false;
|
||||
return qstrncmp(d->data + d->size - len, str, len) == 0;
|
||||
return qstrncmp(d->data() + d->size - len, str, len) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
@ -2581,7 +2596,7 @@ bool QByteArray::endsWith(char ch) const
|
||||
{
|
||||
if (d->size == 0)
|
||||
return false;
|
||||
return d->data[d->size - 1] == ch;
|
||||
return d->data()[d->size - 1] == ch;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2603,7 +2618,7 @@ QByteArray QByteArray::left(int len) const
|
||||
return *this;
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
return QByteArray(d->data, len);
|
||||
return QByteArray(d->data(), len);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2625,7 +2640,7 @@ QByteArray QByteArray::right(int len) const
|
||||
return *this;
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
return QByteArray(d->data + d->size - len, len);
|
||||
return QByteArray(d->data() + d->size - len, len);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2644,7 +2659,7 @@ QByteArray QByteArray::right(int len) const
|
||||
|
||||
QByteArray QByteArray::mid(int pos, int len) const
|
||||
{
|
||||
if (d == &shared_null || d == &shared_empty || pos >= d->size)
|
||||
if (d == &shared_null.ba || d == &shared_empty.ba || pos >= d->size)
|
||||
return QByteArray();
|
||||
if (len < 0)
|
||||
len = d->size - pos;
|
||||
@ -2656,7 +2671,7 @@ QByteArray QByteArray::mid(int pos, int len) const
|
||||
len = d->size - pos;
|
||||
if (pos == 0 && len == d->size)
|
||||
return *this;
|
||||
return QByteArray(d->data + pos, len);
|
||||
return QByteArray(d->data() + pos, len);
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -2715,7 +2730,7 @@ void QByteArray::clear()
|
||||
{
|
||||
if (!d->ref.deref())
|
||||
qFree(d);
|
||||
d = &shared_null;
|
||||
d = const_cast<Data *>(&shared_null.ba);
|
||||
d->ref.ref();
|
||||
}
|
||||
|
||||
@ -3106,10 +3121,10 @@ QByteArray QByteArray::simplified() const
|
||||
if (d->size == 0)
|
||||
return *this;
|
||||
QByteArray result(d->size, Qt::Uninitialized);
|
||||
const char *from = d->data;
|
||||
const char *from = d->data();
|
||||
const char *fromend = from + d->size;
|
||||
int outc=0;
|
||||
char *to = result.d->data;
|
||||
char *to = result.d->data();
|
||||
for (;;) {
|
||||
while (from!=fromend && isspace(uchar(*from)))
|
||||
from++;
|
||||
@ -3145,7 +3160,7 @@ QByteArray QByteArray::trimmed() const
|
||||
{
|
||||
if (d->size == 0)
|
||||
return *this;
|
||||
const char *s = d->data;
|
||||
const char *s = d->data();
|
||||
if (!isspace(uchar(*s)) && !isspace(uchar(s[d->size-1])))
|
||||
return *this;
|
||||
int start = 0;
|
||||
@ -3158,8 +3173,7 @@ QByteArray QByteArray::trimmed() const
|
||||
}
|
||||
int l = end - start + 1;
|
||||
if (l <= 0) {
|
||||
shared_empty.ref.ref();
|
||||
return QByteArray(&shared_empty, 0, 0);
|
||||
return QByteArray(const_cast<Data *>(&shared_empty.ba), 0, 0);
|
||||
}
|
||||
return QByteArray(s+start, l);
|
||||
}
|
||||
@ -3190,8 +3204,8 @@ QByteArray QByteArray::leftJustified(int width, char fill, bool truncate) const
|
||||
if (padlen > 0) {
|
||||
result.resize(len+padlen);
|
||||
if (len)
|
||||
memcpy(result.d->data, d->data, len);
|
||||
memset(result.d->data+len, fill, padlen);
|
||||
memcpy(result.d->data(), d->data(), len);
|
||||
memset(result.d->data()+len, fill, padlen);
|
||||
} else {
|
||||
if (truncate)
|
||||
result = left(width);
|
||||
@ -3227,8 +3241,8 @@ QByteArray QByteArray::rightJustified(int width, char fill, bool truncate) const
|
||||
if (padlen > 0) {
|
||||
result.resize(len+padlen);
|
||||
if (len)
|
||||
memcpy(result.d->data+padlen, data(), len);
|
||||
memset(result.d->data, fill, padlen);
|
||||
memcpy(result.d->data()+padlen, data(), len);
|
||||
memset(result.d->data(), fill, padlen);
|
||||
} else {
|
||||
if (truncate)
|
||||
result = left(width);
|
||||
@ -3238,7 +3252,7 @@ QByteArray QByteArray::rightJustified(int width, char fill, bool truncate) const
|
||||
return result;
|
||||
}
|
||||
|
||||
bool QByteArray::isNull() const { return d == &shared_null; }
|
||||
bool QByteArray::isNull() const { return d == &shared_null.ba; }
|
||||
|
||||
|
||||
/*!
|
||||
@ -3562,13 +3576,13 @@ QByteArray QByteArray::toBase64() const
|
||||
char *out = tmp.data();
|
||||
while (i < d->size) {
|
||||
int chunk = 0;
|
||||
chunk |= int(uchar(d->data[i++])) << 16;
|
||||
chunk |= int(uchar(d->data()[i++])) << 16;
|
||||
if (i == d->size) {
|
||||
padlen = 2;
|
||||
} else {
|
||||
chunk |= int(uchar(d->data[i++])) << 8;
|
||||
chunk |= int(uchar(d->data()[i++])) << 8;
|
||||
if (i == d->size) padlen = 1;
|
||||
else chunk |= int(uchar(d->data[i++]));
|
||||
else chunk |= int(uchar(d->data()[i++]));
|
||||
}
|
||||
|
||||
int j = (chunk & 0x00fc0000) >> 18;
|
||||
@ -3864,17 +3878,20 @@ QByteArray QByteArray::number(double n, char f, int prec)
|
||||
|
||||
QByteArray QByteArray::fromRawData(const char *data, int size)
|
||||
{
|
||||
Data *x = static_cast<Data *>(qMalloc(sizeof(Data)));
|
||||
Q_CHECK_PTR(x);
|
||||
if (data) {
|
||||
x->data = const_cast<char *>(data);
|
||||
Data *x;
|
||||
if (!data) {
|
||||
x = const_cast<Data *>(&shared_null.ba);
|
||||
} else if (!size) {
|
||||
x = const_cast<Data *>(&shared_empty.ba);
|
||||
} else {
|
||||
x->data = x->array;
|
||||
size = 0;
|
||||
x = static_cast<Data *>(qMalloc(sizeof(Data) + 1));
|
||||
Q_CHECK_PTR(x);
|
||||
x->ref = 1;
|
||||
x->size = size;
|
||||
x->alloc = 0;
|
||||
x->capacityReserved = false;
|
||||
x->offset = data - (x->d + sizeof(qptrdiff));
|
||||
}
|
||||
x->ref = 1;
|
||||
x->alloc = x->size = size;
|
||||
*x->array = '\0';
|
||||
return QByteArray(x, 0, 0);
|
||||
}
|
||||
|
||||
@ -3898,13 +3915,13 @@ QByteArray &QByteArray::setRawData(const char *data, uint size)
|
||||
*this = fromRawData(data, size);
|
||||
} else {
|
||||
if (data) {
|
||||
d->data = const_cast<char *>(data);
|
||||
d->size = size;
|
||||
d->offset = data - (d->d + sizeof(qptrdiff));
|
||||
} else {
|
||||
d->data = d->array;
|
||||
size = 0;
|
||||
d->offset = 0;
|
||||
d->size = 0;
|
||||
*d->data() = 0;
|
||||
}
|
||||
d->alloc = d->size = size;
|
||||
*d->array = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -4013,7 +4030,7 @@ QByteArray QByteArray::toHex() const
|
||||
{
|
||||
QByteArray hex(d->size * 2, Qt::Uninitialized);
|
||||
char *hexData = hex.data();
|
||||
const uchar *data = (const uchar *)d->data;
|
||||
const uchar *data = (const uchar *)d->data();
|
||||
for (int i = 0; i < d->size; ++i) {
|
||||
int j = (data[i] >> 4) & 0xf;
|
||||
if (j <= 9)
|
||||
|
@ -42,7 +42,7 @@
|
||||
#ifndef QBYTEARRAY_H
|
||||
#define QBYTEARRAY_H
|
||||
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qrefcount.h>
|
||||
#include <QtCore/qnamespace.h>
|
||||
|
||||
#include <string.h>
|
||||
@ -119,18 +119,65 @@ class QString;
|
||||
class QDataStream;
|
||||
template <typename T> class QList;
|
||||
|
||||
struct QByteArrayData
|
||||
{
|
||||
QtPrivate::RefCount ref;
|
||||
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; }
|
||||
};
|
||||
|
||||
template<int n> struct QConstByteArrayData
|
||||
{
|
||||
const QByteArrayData ba;
|
||||
const char data[n];
|
||||
};
|
||||
|
||||
template<int N> struct QConstByteArrayDataPtr
|
||||
{
|
||||
const QConstByteArrayData<N> *ptr;
|
||||
};
|
||||
|
||||
|
||||
#if defined(Q_COMPILER_LAMBDA)
|
||||
# define QByteArrayLiteral(str) ([]() { \
|
||||
enum { Size = sizeof(str) }; \
|
||||
static const QConstByteArrayData<Size> qbytearray_literal = \
|
||||
{ { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, str }; \
|
||||
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
|
||||
return holder; }())
|
||||
|
||||
#elif defined(Q_CC_GNU)
|
||||
// We need to create a QByteArrayData in the .rodata section of memory
|
||||
// and the only way to do that is to create a "static const" variable.
|
||||
// To do that, we need the __extension__ {( )} trick which only GCC supports
|
||||
|
||||
# define QByteArrayLiteral(str) \
|
||||
__extension__ ({ \
|
||||
enum { Size = sizeof(str) }; \
|
||||
static const QConstByteArrayData<Size> qbytearray_literal = \
|
||||
{ { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, str }; \
|
||||
QConstByteArrayDataPtr<Size> holder = { &qbytearray_literal }; \
|
||||
holder; })
|
||||
#endif
|
||||
|
||||
#ifndef QByteArrayLiteral
|
||||
// no lambdas, not GCC, use const char * instead
|
||||
|
||||
# define QByteArrayLiteral(str) (str)
|
||||
#endif
|
||||
|
||||
|
||||
class Q_CORE_EXPORT QByteArray
|
||||
{
|
||||
private:
|
||||
struct Data {
|
||||
QBasicAtomicInt ref;
|
||||
int alloc, size;
|
||||
// ### Qt 5.0: We need to add the missing capacity bit
|
||||
// (like other tool classes have), to maintain the
|
||||
// reserved memory on resize.
|
||||
char *data;
|
||||
char array[1];
|
||||
};
|
||||
typedef QByteArrayData Data;
|
||||
|
||||
public:
|
||||
inline QByteArray();
|
||||
@ -330,10 +377,17 @@ public:
|
||||
int length() const { return d->size; }
|
||||
bool isNull() const;
|
||||
|
||||
template <int n>
|
||||
inline QByteArray(const QConstByteArrayData<n> &dd)
|
||||
: d(const_cast<QByteArrayData *>(&dd.str)) {}
|
||||
template <int N>
|
||||
Q_DECL_CONSTEXPR inline QByteArray(QConstByteArrayDataPtr<N> dd)
|
||||
: d(const_cast<QByteArrayData *>(&dd.ptr->ba)) {}
|
||||
|
||||
private:
|
||||
operator QNoImplicitBoolCast() const;
|
||||
static Data shared_null;
|
||||
static Data shared_empty;
|
||||
static QConstByteArrayData<1> shared_null;
|
||||
static QConstByteArrayData<1> shared_empty;
|
||||
Data *d;
|
||||
QByteArray(Data *dd, int /*dummy*/, int /*dummy*/) : d(dd) {}
|
||||
void realloc(int alloc);
|
||||
@ -348,34 +402,34 @@ public:
|
||||
inline DataPtr &data_ptr() { return d; }
|
||||
};
|
||||
|
||||
inline QByteArray::QByteArray(): d(&shared_null) { d->ref.ref(); }
|
||||
inline QByteArray::QByteArray(): d(const_cast<Data *>(&shared_null.ba)) { d->ref.ref(); }
|
||||
inline QByteArray::~QByteArray() { if (!d->ref.deref()) qFree(d); }
|
||||
inline int QByteArray::size() const
|
||||
{ return d->size; }
|
||||
|
||||
inline char QByteArray::at(int i) const
|
||||
{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
|
||||
{ Q_ASSERT(i >= 0 && i < size()); return d->data()[i]; }
|
||||
inline char QByteArray::operator[](int i) const
|
||||
{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
|
||||
{ Q_ASSERT(i >= 0 && i < size()); return d->data()[i]; }
|
||||
inline char QByteArray::operator[](uint i) const
|
||||
{ Q_ASSERT(i < uint(size())); return d->data[i]; }
|
||||
{ Q_ASSERT(i < uint(size())); return d->data()[i]; }
|
||||
|
||||
inline bool QByteArray::isEmpty() const
|
||||
{ return d->size == 0; }
|
||||
#ifndef QT_NO_CAST_FROM_BYTEARRAY
|
||||
inline QByteArray::operator const char *() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline QByteArray::operator const void *() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
#endif
|
||||
inline char *QByteArray::data()
|
||||
{ detach(); return d->data; }
|
||||
{ detach(); return d->data(); }
|
||||
inline const char *QByteArray::data() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline const char *QByteArray::constData() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline void QByteArray::detach()
|
||||
{ if (d->ref != 1 || d->data != d->array) realloc(d->size); }
|
||||
{ if (d->ref != 1 || d->offset) realloc(d->size); }
|
||||
inline bool QByteArray::isDetached() const
|
||||
{ return d->ref == 1; }
|
||||
inline QByteArray::QByteArray(const QByteArray &a) : d(a.d)
|
||||
@ -385,10 +439,10 @@ inline int QByteArray::capacity() const
|
||||
{ return d->alloc; }
|
||||
|
||||
inline void QByteArray::reserve(int asize)
|
||||
{ if (d->ref != 1 || asize > d->alloc) realloc(asize); }
|
||||
{ if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacityReserved = true; }
|
||||
|
||||
inline void QByteArray::squeeze()
|
||||
{ if (d->size < d->alloc) realloc(d->size); }
|
||||
{ if (d->size < d->alloc) realloc(d->size); d->capacityReserved = false; }
|
||||
|
||||
class Q_CORE_EXPORT QByteRef {
|
||||
QByteArray &a;
|
||||
@ -398,25 +452,25 @@ class Q_CORE_EXPORT QByteRef {
|
||||
friend class QByteArray;
|
||||
public:
|
||||
inline operator char() const
|
||||
{ return i < a.d->size ? a.d->data[i] : char(0); }
|
||||
{ return i < a.d->size ? a.d->data()[i] : char(0); }
|
||||
inline QByteRef &operator=(char c)
|
||||
{ if (i >= a.d->size) a.expand(i); else a.detach();
|
||||
a.d->data[i] = c; return *this; }
|
||||
a.d->data()[i] = c; return *this; }
|
||||
inline QByteRef &operator=(const QByteRef &c)
|
||||
{ if (i >= a.d->size) a.expand(i); else a.detach();
|
||||
a.d->data[i] = c.a.d->data[c.i]; return *this; }
|
||||
a.d->data()[i] = c.a.d->data()[c.i]; return *this; }
|
||||
inline bool operator==(char c) const
|
||||
{ return a.d->data[i] == c; }
|
||||
{ return a.d->data()[i] == c; }
|
||||
inline bool operator!=(char c) const
|
||||
{ return a.d->data[i] != c; }
|
||||
{ return a.d->data()[i] != c; }
|
||||
inline bool operator>(char c) const
|
||||
{ return a.d->data[i] > c; }
|
||||
{ return a.d->data()[i] > c; }
|
||||
inline bool operator>=(char c) const
|
||||
{ return a.d->data[i] >= c; }
|
||||
{ return a.d->data()[i] >= c; }
|
||||
inline bool operator<(char c) const
|
||||
{ return a.d->data[i] < c; }
|
||||
{ return a.d->data()[i] < c; }
|
||||
inline bool operator<=(char c) const
|
||||
{ return a.d->data[i] <= c; }
|
||||
{ return a.d->data()[i] <= c; }
|
||||
};
|
||||
|
||||
inline QByteRef QByteArray::operator[](int i)
|
||||
@ -424,17 +478,17 @@ inline QByteRef QByteArray::operator[](int i)
|
||||
inline QByteRef QByteArray::operator[](uint i)
|
||||
{ return QByteRef(*this, i); }
|
||||
inline QByteArray::iterator QByteArray::begin()
|
||||
{ detach(); return d->data; }
|
||||
{ detach(); return d->data(); }
|
||||
inline QByteArray::const_iterator QByteArray::begin() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline QByteArray::const_iterator QByteArray::constBegin() const
|
||||
{ return d->data; }
|
||||
{ return d->data(); }
|
||||
inline QByteArray::iterator QByteArray::end()
|
||||
{ detach(); return d->data + d->size; }
|
||||
{ detach(); return d->data() + d->size; }
|
||||
inline QByteArray::const_iterator QByteArray::end() const
|
||||
{ return d->data + d->size; }
|
||||
{ return d->data() + d->size; }
|
||||
inline QByteArray::const_iterator QByteArray::constEnd() const
|
||||
{ return d->data + d->size; }
|
||||
{ return d->data() + d->size; }
|
||||
inline QByteArray &QByteArray::operator+=(char c)
|
||||
{ return append(c); }
|
||||
inline QByteArray &QByteArray::operator+=(const char *s)
|
||||
|
@ -145,6 +145,8 @@ private slots:
|
||||
void byteRefDetaching() const;
|
||||
|
||||
void reserve();
|
||||
|
||||
void literals();
|
||||
};
|
||||
|
||||
tst_QByteArray::tst_QByteArray()
|
||||
@ -1527,14 +1529,38 @@ void tst_QByteArray::reserve()
|
||||
QVERIFY(qba.capacity() == capacity);
|
||||
char *data = qba.data();
|
||||
|
||||
// FIXME count from 0 to make it fail
|
||||
for (int i = 1; i < capacity; i++) {
|
||||
for (int i = 0; i < capacity; i++) {
|
||||
qba.resize(i);
|
||||
QVERIFY(capacity == qba.capacity());
|
||||
QVERIFY(data == qba.data());
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QByteArray::literals()
|
||||
{
|
||||
#if defined(Q_COMPILER_LAMBDA) || defined(Q_CC_GNU)
|
||||
QByteArray str(QByteArrayLiteral("abcd"));
|
||||
|
||||
QVERIFY(str.length() == 4);
|
||||
QVERIFY(str == "abcd");
|
||||
QVERIFY(str.data_ptr()->ref == -1);
|
||||
QVERIFY(str.data_ptr()->offset == 0);
|
||||
|
||||
const char *s = str.constData();
|
||||
QByteArray str2 = str;
|
||||
QVERIFY(str2.constData() == s);
|
||||
|
||||
// detach on non const access
|
||||
QVERIFY(str.data() != s);
|
||||
|
||||
QVERIFY(str2.constData() == s);
|
||||
QVERIFY(str2.data() != s);
|
||||
|
||||
#else
|
||||
QSKIP("Only tested on c++0x compliant compiler or gcc", SkipAll);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char globalChar = '1';
|
||||
|
||||
QTEST_APPLESS_MAIN(tst_QByteArray)
|
||||
|
Loading…
Reference in New Issue
Block a user