Inline the size and data pointers in QByteArray
Change-Id: I82feeb2c9bd2900f421fc0c8d78698b1e83db043 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>bb10
parent
e58b44d557
commit
00fbc087dd
|
|
@ -67,7 +67,7 @@
|
|||
#include <qcoreevent.h>
|
||||
#include <qiodevice.h>
|
||||
#include <qlist.h>
|
||||
//#include <qvariant.h> /* All moc genereated code has this include */
|
||||
#include <qvariant.h> /* All moc genereated code has this include */
|
||||
#include <qobject.h>
|
||||
#include <qregexp.h>
|
||||
#include <qscopedpointer.h>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE
|
|||
|
||||
class QByteArray;
|
||||
struct QArrayData;
|
||||
typedef QArrayData QByteArrayData;
|
||||
struct QByteArrayData;
|
||||
|
||||
class QString;
|
||||
|
||||
|
|
|
|||
|
|
@ -731,27 +731,25 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
|||
return invalidCompressedData();
|
||||
}
|
||||
|
||||
QScopedPointer<QByteArray::Data, QByteArrayDataDeleter> d(QByteArray::Data::allocate(expectedSize + 1).first);
|
||||
QPair<QByteArray::Data *, char *> pair = QByteArray::Data::allocate(expectedSize + 1);
|
||||
QScopedPointer<QByteArray::Data, QByteArrayDataDeleter> d(pair.first);
|
||||
if (Q_UNLIKELY(d.data() == nullptr))
|
||||
return invalidCompressedData();
|
||||
|
||||
d->size = expectedSize;
|
||||
forever {
|
||||
ulong alloc = len;
|
||||
|
||||
int res = ::uncompress((uchar*)d->data(), &len,
|
||||
int res = ::uncompress((uchar*)pair.second, &len,
|
||||
data+4, nbytes-4);
|
||||
|
||||
switch (res) {
|
||||
case Z_OK:
|
||||
case Z_OK: {
|
||||
Q_ASSERT(len <= alloc);
|
||||
Q_UNUSED(alloc);
|
||||
d->size = len;
|
||||
d->data()[len] = 0;
|
||||
{
|
||||
QByteArrayDataPtr dataPtr = { d.take() };
|
||||
return QByteArray(dataPtr);
|
||||
}
|
||||
QByteArrayData dataPtr = { d.take(), pair.second, uint(len) };
|
||||
pair.second[len] = '\0';
|
||||
return QByteArray(dataPtr);
|
||||
}
|
||||
|
||||
case Z_MEM_ERROR:
|
||||
qWarning("qUncompress: Z_MEM_ERROR: Not enough memory");
|
||||
|
|
@ -764,12 +762,12 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
|||
return invalidCompressedData();
|
||||
} else {
|
||||
// grow the block
|
||||
char *dataPointer = d->data();
|
||||
QByteArray::Data *p = QByteArray::Data::reallocateUnaligned(d.data(), dataPointer, len + 1).first;
|
||||
if (Q_UNLIKELY(p == nullptr))
|
||||
pair = QByteArray::Data::reallocateUnaligned(d.data(), pair.second, len + 1);
|
||||
Q_CHECK_PTR(pair.first);
|
||||
if (Q_UNLIKELY(pair.first == nullptr))
|
||||
return invalidCompressedData();
|
||||
d.take(); // don't free
|
||||
d.reset(p);
|
||||
d.reset(pair.first);
|
||||
}
|
||||
continue;
|
||||
|
||||
|
|
@ -1185,9 +1183,9 @@ QByteArray qUncompress(const uchar* data, int nbytes)
|
|||
*/
|
||||
QByteArray &QByteArray::operator=(const QByteArray & other) noexcept
|
||||
{
|
||||
other.d->ref();
|
||||
if (!d->deref())
|
||||
Data::deallocate(d);
|
||||
other.d.d->ref();
|
||||
if (!d.d->deref())
|
||||
Data::deallocate(d.d);
|
||||
d = other.d;
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1201,25 +1199,28 @@ QByteArray &QByteArray::operator=(const QByteArray & other) noexcept
|
|||
|
||||
QByteArray &QByteArray::operator=(const char *str)
|
||||
{
|
||||
Data *x;
|
||||
if (!str) {
|
||||
x = Data::sharedNull();
|
||||
} else if (!*str) {
|
||||
x = Data::allocate(0).first;
|
||||
if (!str || !*str) {
|
||||
QPair<Data *, char *> pair;
|
||||
if (!str) {
|
||||
pair = qMakePair(Data::sharedNull(), Data::sharedNullData());
|
||||
} else {
|
||||
pair = Data::allocate(0);
|
||||
pair.first->ref();
|
||||
}
|
||||
if (!d.d->deref())
|
||||
Data::deallocate(d.d);
|
||||
d.d = pair.first;
|
||||
d.b = pair.second;
|
||||
d.size = 0;
|
||||
} else {
|
||||
const int len = int(strlen(str));
|
||||
const int fullLen = len + 1;
|
||||
if (d->needsDetach() || fullLen > int(d->allocatedCapacity())
|
||||
|| (len < d->size && fullLen < int(d->allocatedCapacity() >> 1)))
|
||||
reallocData(fullLen, d->detachFlags());
|
||||
x = d;
|
||||
memcpy(x->data(), str, fullLen); // include null terminator
|
||||
x->size = len;
|
||||
const size_t fullLen = len + 1;
|
||||
if (d.d->needsDetach() || fullLen > d.d->allocatedCapacity()
|
||||
|| (len < size() && fullLen < (d.d->allocatedCapacity() >> 1)))
|
||||
reallocData(fullLen, d.d->detachFlags());
|
||||
memcpy(d.b, str, fullLen); // include null terminator
|
||||
d.size = len;
|
||||
}
|
||||
x->ref();
|
||||
if (!d->deref())
|
||||
Data::deallocate(d);
|
||||
d = x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1555,7 +1556,7 @@ QByteArray &QByteArray::operator=(const char *str)
|
|||
*/
|
||||
void QByteArray::truncate(int pos)
|
||||
{
|
||||
if (pos < d->size)
|
||||
if (pos < size())
|
||||
resize(pos);
|
||||
}
|
||||
|
||||
|
|
@ -1575,7 +1576,7 @@ void QByteArray::truncate(int pos)
|
|||
void QByteArray::chop(int n)
|
||||
{
|
||||
if (n > 0)
|
||||
resize(d->size - n);
|
||||
resize(size() - n);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1679,19 +1680,19 @@ void QByteArray::chop(int n)
|
|||
QByteArray::QByteArray(const char *data, int size)
|
||||
{
|
||||
if (!data) {
|
||||
d = Data::sharedNull();
|
||||
d.d = Data::sharedNull();
|
||||
d.b = Data::sharedNullData();
|
||||
d.size = 0;
|
||||
} else {
|
||||
if (size < 0)
|
||||
size = int(strlen(data));
|
||||
if (!size) {
|
||||
d = Data::allocate(0).first;
|
||||
} else {
|
||||
d = Data::allocate(uint(size) + 1u).first;
|
||||
Q_CHECK_PTR(d);
|
||||
d->size = size;
|
||||
memcpy(d->data(), data, size);
|
||||
d->data()[size] = '\0';
|
||||
}
|
||||
QPair<Data *, char *> pair = Data::allocate(uint(size) + 1u);
|
||||
Q_CHECK_PTR(pair.first);
|
||||
d.d = pair.first;
|
||||
d.b = pair.second;
|
||||
d.size = size;
|
||||
memcpy(d.b, data, size);
|
||||
d.b[size] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1705,13 +1706,18 @@ QByteArray::QByteArray(const char *data, int size)
|
|||
QByteArray::QByteArray(int size, char ch)
|
||||
{
|
||||
if (size <= 0) {
|
||||
d = Data::allocate(0).first;
|
||||
QPair<Data *, char *> pair = Data::allocate(0);
|
||||
d.d = pair.first;
|
||||
d.b = pair.second;
|
||||
d.size = 0;
|
||||
} else {
|
||||
d = Data::allocate(uint(size) + 1u).first;
|
||||
Q_CHECK_PTR(d);
|
||||
d->size = size;
|
||||
memset(d->data(), ch, size);
|
||||
d->data()[size] = '\0';
|
||||
QPair<Data *, char *> pair = Data::allocate(uint(size) + 1u);
|
||||
Q_CHECK_PTR(pair.first);
|
||||
d.d = pair.first;
|
||||
d.b = pair.second;
|
||||
d.size = size;
|
||||
memset(d.b, ch, size);
|
||||
d.b[size] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1723,10 +1729,12 @@ QByteArray::QByteArray(int size, char ch)
|
|||
|
||||
QByteArray::QByteArray(int size, Qt::Initialization)
|
||||
{
|
||||
d = Data::allocate(uint(size) + 1u).first;
|
||||
Q_CHECK_PTR(d);
|
||||
d->size = size;
|
||||
d->data()[size] = '\0';
|
||||
QPair<Data *, char *> pair = Data::allocate(uint(size) + 1u);
|
||||
Q_CHECK_PTR(pair.first);
|
||||
d.d = pair.first;
|
||||
d.b = pair.second;
|
||||
d.size = size;
|
||||
d.b[size] = '\0';
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1746,31 +1754,26 @@ void QByteArray::resize(int size)
|
|||
if (size < 0)
|
||||
size = 0;
|
||||
|
||||
if (!d->isShared() && !d->isMutable() && size < d->size) {
|
||||
d->size = size;
|
||||
if (!d.d->isShared() && !d.d->isMutable() && size < int(d.size)) {
|
||||
d.size = size;
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->size == 0 && d->isStatic()) {
|
||||
//
|
||||
// Optimize the idiom:
|
||||
// QByteArray a;
|
||||
// a.resize(sz);
|
||||
// ...
|
||||
// which is used in place of the Qt 3 idiom:
|
||||
// QByteArray a(sz);
|
||||
//
|
||||
Data *x = Data::allocate(uint(size) + 1u).first;
|
||||
Q_CHECK_PTR(x);
|
||||
x->size = size;
|
||||
x->data()[size] = '\0';
|
||||
d = x;
|
||||
if (size == 0 && !(d.d->flags & Data::CapacityReserved)) {
|
||||
QPair<Data *, char *> pair = Data::allocate(0);
|
||||
if (!d.d->deref())
|
||||
Data::deallocate(d.d);
|
||||
d.d = pair.first;
|
||||
d.b = pair.second;
|
||||
d.size = 0;
|
||||
} else {
|
||||
if (d->needsDetach() || size > capacity())
|
||||
reallocData(uint(size) + 1u, d->detachFlags() | Data::GrowsForward);
|
||||
if (d->isMutable()) {
|
||||
d->size = size;
|
||||
d->data()[size] = '\0';
|
||||
if (d.d->needsDetach() || size > capacity()
|
||||
|| (!(d.d->flags & Data::CapacityReserved) && size < int(d.size)
|
||||
&& size < (capacity() >> 1)))
|
||||
reallocData(uint(size) + 1u, d.d->detachFlags() | Data::GrowsForward);
|
||||
d.size = size;
|
||||
if (d.d->isMutable()) {
|
||||
d.b[size] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1788,33 +1791,36 @@ void QByteArray::resize(int size)
|
|||
|
||||
QByteArray &QByteArray::fill(char ch, int size)
|
||||
{
|
||||
resize(size < 0 ? d->size : size);
|
||||
if (d->size)
|
||||
memset(d->data(), ch, d->size);
|
||||
resize(size < 0 ? this->size() : size);
|
||||
if (this->size())
|
||||
memset(d.b, ch, this->size());
|
||||
return *this;
|
||||
}
|
||||
|
||||
void QByteArray::reallocData(uint alloc, Data::ArrayOptions options)
|
||||
{
|
||||
if (d->needsDetach()) {
|
||||
Data *x = Data::allocate(alloc, options).first;
|
||||
Q_CHECK_PTR(x);
|
||||
x->size = qMin(int(alloc) - 1, d->size);
|
||||
::memcpy(x->data(), d->data(), x->size);
|
||||
x->data()[x->size] = '\0';
|
||||
if (!d->deref())
|
||||
Data::deallocate(d);
|
||||
d = x;
|
||||
if (d.d->needsDetach()) {
|
||||
QPair<Data *, char *> pair = Data::allocate(alloc, options);
|
||||
Q_CHECK_PTR(pair.first);
|
||||
d.size = qMin(alloc - 1, d.size);
|
||||
::memcpy(pair.second, d.b, d.size);
|
||||
pair.second[d.size] = 0;
|
||||
if (!d.d->deref())
|
||||
Data::deallocate(d.d);
|
||||
d.d = pair.first;
|
||||
d.b = pair.second;
|
||||
} else {
|
||||
Data *x = Data::reallocateUnaligned(d, d->data(), alloc, options).first;
|
||||
Q_CHECK_PTR(x);
|
||||
d = x;
|
||||
QPair<Data *, char *> pair =
|
||||
Data::reallocateUnaligned(static_cast<Data *>(d.d), d.b, alloc, options);
|
||||
Q_CHECK_PTR(pair.first);
|
||||
d.d = pair.first;
|
||||
d.b = pair.second;
|
||||
}
|
||||
}
|
||||
|
||||
void QByteArray::expand(int i)
|
||||
{
|
||||
resize(qMax(i + 1, d->size));
|
||||
resize(qMax(i + 1, size()));
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -1829,7 +1835,7 @@ void QByteArray::expand(int i)
|
|||
QByteArray QByteArray::nulTerminated() const
|
||||
{
|
||||
// is this fromRawData?
|
||||
if (!IS_RAW_DATA(d))
|
||||
if (!IS_RAW_DATA(d.d))
|
||||
return *this; // no, then we're sure we're zero terminated
|
||||
|
||||
QByteArray copy(*this);
|
||||
|
|
@ -1860,9 +1866,9 @@ QByteArray QByteArray::nulTerminated() const
|
|||
|
||||
QByteArray &QByteArray::prepend(const QByteArray &ba)
|
||||
{
|
||||
if (d->size == 0 && d->isStatic() && !IS_RAW_DATA(ba.d)) {
|
||||
if (size() == 0 && d.d->isStatic() && !IS_RAW_DATA(ba.d.d)) {
|
||||
*this = ba;
|
||||
} else if (ba.d->size != 0) {
|
||||
} else if (ba.size() != 0) {
|
||||
QByteArray tmp = *this;
|
||||
*this = ba;
|
||||
append(tmp);
|
||||
|
|
@ -1891,12 +1897,12 @@ QByteArray &QByteArray::prepend(const char *str)
|
|||
QByteArray &QByteArray::prepend(const char *str, int len)
|
||||
{
|
||||
if (str) {
|
||||
if (d->needsDetach() || d->size + len > capacity())
|
||||
reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::GrowsForward);
|
||||
memmove(d->data()+len, d->data(), d->size);
|
||||
memcpy(d->data(), str, len);
|
||||
d->size += len;
|
||||
d->data()[d->size] = '\0';
|
||||
if (d.d->needsDetach() || size() + len > capacity())
|
||||
reallocData(uint(size() + len) + 1u, d.d->detachFlags() | Data::GrowsForward);
|
||||
memmove(d.b+len, d.b, d.size);
|
||||
memcpy(d.b, str, len);
|
||||
d.size += len;
|
||||
d.b[d.size] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1917,12 +1923,12 @@ QByteArray &QByteArray::prepend(const char *str, int len)
|
|||
|
||||
QByteArray &QByteArray::prepend(char ch)
|
||||
{
|
||||
if (d->needsDetach() || d->size + 1 > capacity())
|
||||
reallocData(uint(d->size) + 2u, d->detachFlags() | Data::GrowsForward);
|
||||
memmove(d->data()+1, d->data(), d->size);
|
||||
d->data()[0] = ch;
|
||||
++d->size;
|
||||
d->data()[d->size] = '\0';
|
||||
if (d.d->needsDetach() || size() + 1 > capacity())
|
||||
reallocData(uint(size()) + 2u, d.d->detachFlags() | Data::GrowsForward);
|
||||
memmove(d.b+1, d.b, d.size);
|
||||
d.b[0] = ch;
|
||||
++d.size;
|
||||
d.b[d.size] = '\0';
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -1952,14 +1958,14 @@ QByteArray &QByteArray::prepend(char ch)
|
|||
|
||||
QByteArray &QByteArray::append(const QByteArray &ba)
|
||||
{
|
||||
if (d->size == 0 && d->isStatic() && !IS_RAW_DATA(ba.d)) {
|
||||
if (size() == 0 && d.d->isStatic() && !IS_RAW_DATA(ba.d.d)) {
|
||||
*this = ba;
|
||||
} else if (ba.d->size != 0) {
|
||||
if (d->needsDetach() || d->size + ba.d->size > capacity())
|
||||
reallocData(uint(d->size + ba.d->size) + 1u, d->detachFlags() | Data::GrowsForward);
|
||||
memcpy(d->data() + d->size, ba.d->data(), ba.d->size);
|
||||
d->size += ba.d->size;
|
||||
d->data()[d->size] = '\0';
|
||||
} else if (ba.size() != 0) {
|
||||
if (d.d->needsDetach() || size() + ba.size() > capacity())
|
||||
reallocData(uint(size() + ba.size()) + 1u, d.d->detachFlags() | Data::GrowsForward);
|
||||
memcpy(d.b + d.size, ba.data(), ba.size());
|
||||
d.size += ba.size();
|
||||
d.b[d.size] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -1987,10 +1993,10 @@ QByteArray& QByteArray::append(const char *str)
|
|||
{
|
||||
if (str) {
|
||||
const int len = int(strlen(str));
|
||||
if (d->needsDetach() || d->size + len > capacity())
|
||||
reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::GrowsForward);
|
||||
memcpy(d->data() + d->size, str, len + 1); // include null terminator
|
||||
d->size += len;
|
||||
if (d.d->needsDetach() || size() + len > capacity())
|
||||
reallocData(uint(size() + len) + 1u, d.d->detachFlags() | Data::GrowsForward);
|
||||
memcpy(d.b + d.size, str, len + 1); // include null terminator
|
||||
d.size += len;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -2012,11 +2018,11 @@ QByteArray &QByteArray::append(const char *str, int len)
|
|||
if (len < 0)
|
||||
len = qstrlen(str);
|
||||
if (str && len) {
|
||||
if (d->needsDetach() || d->size + len > capacity())
|
||||
reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::GrowsForward);
|
||||
memcpy(d->data() + d->size, str, len); // include null terminator
|
||||
d->size += len;
|
||||
d->data()[d->size] = '\0';
|
||||
if (d.d->needsDetach() || size() + len > capacity())
|
||||
reallocData(uint(size() + len) + 1u, d.d->detachFlags() | Data::GrowsForward);
|
||||
memcpy(d.b + d.size, str, len);
|
||||
d.size += len;
|
||||
d.b[d.size] = '\0';
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -2040,10 +2046,10 @@ QByteArray &QByteArray::append(const char *str, int len)
|
|||
|
||||
QByteArray& QByteArray::append(char ch)
|
||||
{
|
||||
if (d->needsDetach() || d->size + 1 > capacity())
|
||||
reallocData(uint(d->size) + 2u, d->detachFlags() | Data::GrowsForward);
|
||||
d->data()[d->size++] = ch;
|
||||
d->data()[d->size] = '\0';
|
||||
if (d.d->needsDetach() || size() + 1 > capacity())
|
||||
reallocData(uint(size()) + 2u, d.d->detachFlags() | Data::GrowsForward);
|
||||
d.b[d.size++] = ch;
|
||||
d.b[d.size] = '\0';
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -2084,7 +2090,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.constData(), copy.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2166,7 +2172,7 @@ QByteArray &QByteArray::insert(int i, int count, char ch)
|
|||
|
||||
int oldsize = size();
|
||||
resize(qMax(i, oldsize) + count);
|
||||
char *dst = d->data();
|
||||
char *dst = d.b;
|
||||
if (i > oldsize)
|
||||
::memset(dst + oldsize, 0x20, i - oldsize);
|
||||
else if (i < oldsize)
|
||||
|
|
@ -2191,14 +2197,14 @@ QByteArray &QByteArray::insert(int i, int count, char ch)
|
|||
|
||||
QByteArray &QByteArray::remove(int pos, int len)
|
||||
{
|
||||
if (len <= 0 || uint(pos) >= uint(d->size))
|
||||
if (len <= 0 || uint(pos) >= uint(size()))
|
||||
return *this;
|
||||
detach();
|
||||
if (len >= d->size - pos) {
|
||||
if (len >= size() - pos) {
|
||||
resize(pos);
|
||||
} else {
|
||||
memmove(d->data() + pos, d->data() + pos + len, d->size - pos - len);
|
||||
resize(d->size - len);
|
||||
memmove(d.b + pos, d.b + pos + len, size() - pos - len);
|
||||
resize(size() - len);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -2215,9 +2221,9 @@ QByteArray &QByteArray::remove(int pos, int len)
|
|||
|
||||
QByteArray &QByteArray::replace(int pos, int len, const QByteArray &after)
|
||||
{
|
||||
if (len == after.d->size && (pos + len <= d->size)) {
|
||||
if (len == after.size() && (pos + len <= size())) {
|
||||
detach();
|
||||
memmove(d->data() + pos, after.d->data(), len*sizeof(char));
|
||||
memmove(d.b + pos, after.data(), len*sizeof(char));
|
||||
return *this;
|
||||
} else {
|
||||
QByteArray copy(after);
|
||||
|
|
@ -2252,9 +2258,9 @@ QByteArray &QByteArray::replace(int pos, int len, const char *after)
|
|||
*/
|
||||
QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen)
|
||||
{
|
||||
if (len == alen && (pos + len <= d->size)) {
|
||||
if (len == alen && (pos + len <= size())) {
|
||||
detach();
|
||||
memcpy(d->data() + pos, after, len*sizeof(char));
|
||||
memcpy(d.b + pos, after, len*sizeof(char));
|
||||
return *this;
|
||||
} else {
|
||||
remove(pos, len);
|
||||
|
|
@ -2277,14 +2283,7 @@ QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen)
|
|||
|
||||
QByteArray &QByteArray::replace(const QByteArray &before, const QByteArray &after)
|
||||
{
|
||||
if (isNull() || before.d == after.d)
|
||||
return *this;
|
||||
|
||||
QByteArray aft = after;
|
||||
if (after.d == d)
|
||||
aft.detach();
|
||||
|
||||
return replace(before.constData(), before.size(), aft.constData(), aft.size());
|
||||
return replace(before.constData(), before.size(), after.constData(), after.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2297,11 +2296,7 @@ QByteArray &QByteArray::replace(const QByteArray &before, const QByteArray &afte
|
|||
|
||||
QByteArray &QByteArray::replace(const char *c, const QByteArray &after)
|
||||
{
|
||||
QByteArray aft = after;
|
||||
if (after.d == d)
|
||||
aft.detach();
|
||||
|
||||
return replace(c, qstrlen(c), aft.constData(), aft.size());
|
||||
return replace(c, qstrlen(c), after.constData(), after.size());
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2321,13 +2316,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 >= constBegin() && after < constEnd()) {
|
||||
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 >= constBegin() && before < constEnd()) {
|
||||
char *copy = (char *)malloc(bsize);
|
||||
Q_CHECK_PTR(copy);
|
||||
memcpy(copy, before, bsize);
|
||||
|
|
@ -2336,8 +2331,8 @@ QByteArray &QByteArray::replace(const char *before, int bsize, const char *after
|
|||
|
||||
QByteArrayMatcher matcher(before, bsize);
|
||||
int index = 0;
|
||||
int len = d->size;
|
||||
char *d = data();
|
||||
int len = size();
|
||||
char *d = data(); // detaches
|
||||
|
||||
if (bsize == asize) {
|
||||
if (bsize) {
|
||||
|
|
@ -2404,7 +2399,7 @@ QByteArray &QByteArray::replace(const char *before, int bsize, const char *after
|
|||
resize(newlen);
|
||||
len = newlen;
|
||||
}
|
||||
d = this->d->data();
|
||||
d = this->d.b; // data(), without the detach() check
|
||||
|
||||
while(pos) {
|
||||
pos--;
|
||||
|
|
@ -2476,8 +2471,7 @@ QByteArray &QByteArray::replace(const char *before, int bsize, const char *after
|
|||
QByteArray &QByteArray::replace(char before, const QByteArray &after)
|
||||
{
|
||||
char b[2] = { before, '\0' };
|
||||
QByteArray cb = fromRawData(b, 1);
|
||||
return replace(cb, after);
|
||||
return replace(b, 1, after.constData(), after.size());
|
||||
}
|
||||
|
||||
/*! \fn QByteArray &QByteArray::replace(char before, const QString &after)
|
||||
|
|
@ -2511,9 +2505,9 @@ QByteArray &QByteArray::replace(char before, const QByteArray &after)
|
|||
|
||||
QByteArray &QByteArray::replace(char before, char after)
|
||||
{
|
||||
if (d->size) {
|
||||
if (!isEmpty()) {
|
||||
char *i = data();
|
||||
char *e = i + d->size;
|
||||
char *e = i + size();
|
||||
for (; i != e; ++i)
|
||||
if (*i == before)
|
||||
* i = after;
|
||||
|
|
@ -2554,7 +2548,7 @@ QList<QByteArray> QByteArray::split(char sep) const
|
|||
*/
|
||||
QByteArray QByteArray::repeated(int times) const
|
||||
{
|
||||
if (d->size == 0)
|
||||
if (isEmpty())
|
||||
return *this;
|
||||
|
||||
if (times <= 1) {
|
||||
|
|
@ -2563,27 +2557,27 @@ QByteArray QByteArray::repeated(int times) const
|
|||
return QByteArray();
|
||||
}
|
||||
|
||||
const int resultSize = times * d->size;
|
||||
const int resultSize = times * size();
|
||||
|
||||
QByteArray result;
|
||||
result.reserve(resultSize);
|
||||
if (result.capacity() != resultSize)
|
||||
return QByteArray(); // not enough memory
|
||||
|
||||
memcpy(result.d->data(), d->data(), d->size);
|
||||
memcpy(result.d.b, data(), size());
|
||||
|
||||
int sizeSoFar = d->size;
|
||||
char *end = result.d->data() + sizeSoFar;
|
||||
int sizeSoFar = size();
|
||||
char *end = result.d.b + sizeSoFar;
|
||||
|
||||
const int halfResultSize = resultSize >> 1;
|
||||
while (sizeSoFar <= halfResultSize) {
|
||||
memcpy(end, result.d->data(), sizeSoFar);
|
||||
memcpy(end, result.d.b, sizeSoFar);
|
||||
end += sizeSoFar;
|
||||
sizeSoFar <<= 1;
|
||||
}
|
||||
memcpy(end, result.d->data(), resultSize - sizeSoFar);
|
||||
result.d->data()[resultSize] = '\0';
|
||||
result.d->size = resultSize;
|
||||
memcpy(end, result.d.b, resultSize - sizeSoFar);
|
||||
result.d.b[resultSize] = '\0';
|
||||
result.d.size = resultSize;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -2605,17 +2599,17 @@ QByteArray QByteArray::repeated(int times) const
|
|||
|
||||
int QByteArray::indexOf(const QByteArray &ba, int from) const
|
||||
{
|
||||
const int ol = ba.d->size;
|
||||
const int ol = ba.size();
|
||||
if (ol == 0)
|
||||
return from;
|
||||
if (ol == 1)
|
||||
return indexOf(*ba.d->data(), from);
|
||||
return indexOf(ba[0], from);
|
||||
|
||||
const int l = d->size;
|
||||
if (from > d->size || ol + from > l)
|
||||
const int l = size();
|
||||
if (from > l || ol + from > l)
|
||||
return -1;
|
||||
|
||||
return qFindByteArray(d->data(), d->size, from, ba.d->data(), ol);
|
||||
return qFindByteArray(data(), size(), from, ba.data(), ol);
|
||||
}
|
||||
|
||||
/*! \fn int QByteArray::indexOf(const QString &str, int from) const
|
||||
|
|
@ -2649,13 +2643,13 @@ int QByteArray::indexOf(const char *c, int from) const
|
|||
if (ol == 1)
|
||||
return indexOf(*c, from);
|
||||
|
||||
const int l = d->size;
|
||||
if (from > d->size || ol + from > l)
|
||||
const int l = size();
|
||||
if (from > l || ol + from > l)
|
||||
return -1;
|
||||
if (ol == 0)
|
||||
return from;
|
||||
|
||||
return qFindByteArray(d->data(), d->size, from, c, ol);
|
||||
return qFindByteArray(data(), size(), from, c, ol);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2674,13 +2668,13 @@ int QByteArray::indexOf(const char *c, int from) const
|
|||
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;
|
||||
from = qMax(from + size(), 0);
|
||||
if (from < size()) {
|
||||
const char *n = data() + from - 1;
|
||||
const char *e = end();
|
||||
while (++n != e)
|
||||
if (*n == ch)
|
||||
return n - d->data();
|
||||
return n - data();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -2735,11 +2729,11 @@ static int lastIndexOfHelper(const char *haystack, int l, const char *needle, in
|
|||
|
||||
int QByteArray::lastIndexOf(const QByteArray &ba, int from) const
|
||||
{
|
||||
const int ol = ba.d->size;
|
||||
const int ol = ba.size();
|
||||
if (ol == 1)
|
||||
return lastIndexOf(*ba.d->data(), from);
|
||||
return lastIndexOf(ba[0], from);
|
||||
|
||||
return lastIndexOfHelper(d->data(), d->size, ba.d->data(), ol, from);
|
||||
return lastIndexOfHelper(data(), size(), ba.data(), ol, from);
|
||||
}
|
||||
|
||||
/*! \fn int QByteArray::lastIndexOf(const QString &str, int from) const
|
||||
|
|
@ -2774,7 +2768,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(data(), size(), str, ol, from);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2794,12 +2788,12 @@ int QByteArray::lastIndexOf(const char *str, int from) const
|
|||
int QByteArray::lastIndexOf(char ch, int from) const
|
||||
{
|
||||
if (from < 0)
|
||||
from += d->size;
|
||||
else if (from > d->size)
|
||||
from = d->size-1;
|
||||
from += size();
|
||||
else if (from > size())
|
||||
from = size()-1;
|
||||
if (from >= 0) {
|
||||
const char *b = d->data();
|
||||
const char *n = d->data() + from + 1;
|
||||
const char *b = data();
|
||||
const char *n = b + from + 1;
|
||||
while (n-- != b)
|
||||
if (*n == ch)
|
||||
return n - b;
|
||||
|
|
@ -2818,7 +2812,7 @@ int QByteArray::count(const QByteArray &ba) const
|
|||
{
|
||||
int num = 0;
|
||||
int i = -1;
|
||||
if (d->size > 500 && ba.d->size > 5) {
|
||||
if (size() > 500 && ba.size() > 5) {
|
||||
QByteArrayMatcher matcher(ba);
|
||||
while ((i = matcher.indexIn(*this, i + 1)) != -1)
|
||||
++num;
|
||||
|
|
@ -2853,8 +2847,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 = end();
|
||||
const char *b = begin();
|
||||
while (i != b)
|
||||
if (*--i == ch)
|
||||
++num;
|
||||
|
|
@ -2904,11 +2898,11 @@ int QByteArray::count(char ch) const
|
|||
*/
|
||||
bool QByteArray::startsWith(const QByteArray &ba) const
|
||||
{
|
||||
if (d == ba.d || ba.d->size == 0)
|
||||
return true;
|
||||
if (d->size < ba.d->size)
|
||||
if (size() < ba.size())
|
||||
return false;
|
||||
return memcmp(d->data(), ba.d->data(), ba.d->size) == 0;
|
||||
if (data() == ba.data() || ba.size() == 0)
|
||||
return true;
|
||||
return memcmp(data(), ba.data(), ba.size()) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
|
|
@ -2921,9 +2915,9 @@ bool QByteArray::startsWith(const char *str) const
|
|||
if (!str || !*str)
|
||||
return true;
|
||||
const int len = int(strlen(str));
|
||||
if (d->size < len)
|
||||
if (size() < len)
|
||||
return false;
|
||||
return qstrncmp(d->data(), str, len) == 0;
|
||||
return qstrncmp(data(), str, len) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
|
|
@ -2933,9 +2927,9 @@ bool QByteArray::startsWith(const char *str) const
|
|||
*/
|
||||
bool QByteArray::startsWith(char ch) const
|
||||
{
|
||||
if (d->size == 0)
|
||||
if (size() == 0)
|
||||
return false;
|
||||
return d->data()[0] == ch;
|
||||
return data()[0] == ch;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -2949,11 +2943,11 @@ bool QByteArray::startsWith(char ch) const
|
|||
*/
|
||||
bool QByteArray::endsWith(const QByteArray &ba) const
|
||||
{
|
||||
if (d == ba.d || ba.d->size == 0)
|
||||
return true;
|
||||
if (d->size < ba.d->size)
|
||||
if (size() < ba.size())
|
||||
return false;
|
||||
return memcmp(d->data() + d->size - ba.d->size, ba.d->data(), ba.d->size) == 0;
|
||||
if (end() == ba.end() || ba.size() == 0)
|
||||
return true;
|
||||
return memcmp(end() - ba.size(), ba.data(), ba.size()) == 0;
|
||||
}
|
||||
|
||||
/*! \overload
|
||||
|
|
@ -2966,9 +2960,9 @@ bool QByteArray::endsWith(const char *str) const
|
|||
if (!str || !*str)
|
||||
return true;
|
||||
const int len = int(strlen(str));
|
||||
if (d->size < len)
|
||||
if (size() < len)
|
||||
return false;
|
||||
return qstrncmp(d->data() + d->size - len, str, len) == 0;
|
||||
return qstrncmp(end() - len, str, len) == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3050,9 +3044,9 @@ bool QByteArray::isLower() const
|
|||
*/
|
||||
bool QByteArray::endsWith(char ch) const
|
||||
{
|
||||
if (d->size == 0)
|
||||
if (size() == 0)
|
||||
return false;
|
||||
return d->data()[d->size - 1] == ch;
|
||||
return data()[size() - 1] == ch;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -3070,11 +3064,11 @@ bool QByteArray::endsWith(char ch) const
|
|||
|
||||
QByteArray QByteArray::left(int len) const
|
||||
{
|
||||
if (len >= d->size)
|
||||
if (len >= size())
|
||||
return *this;
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
return QByteArray(d->data(), len);
|
||||
return QByteArray(data(), len);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -3092,11 +3086,11 @@ QByteArray QByteArray::left(int len) const
|
|||
|
||||
QByteArray QByteArray::right(int len) const
|
||||
{
|
||||
if (len >= d->size)
|
||||
if (len >= size())
|
||||
return *this;
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
return QByteArray(d->data() + d->size - len, len);
|
||||
return QByteArray(end() - len, len);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -3121,13 +3115,14 @@ QByteArray QByteArray::mid(int pos, int len) const
|
|||
return QByteArray();
|
||||
case QContainerImplHelper::Empty:
|
||||
{
|
||||
QByteArrayDataPtr empty = { Data::allocate(0).first };
|
||||
auto alloc = Data::allocate(0);
|
||||
QByteArrayData empty = { alloc.first, alloc.second, 0 };
|
||||
return QByteArray(empty);
|
||||
}
|
||||
case QContainerImplHelper::Full:
|
||||
return *this;
|
||||
case QContainerImplHelper::Subset:
|
||||
return QByteArray(d->data() + pos, len);
|
||||
return QByteArray(d.b + pos, len);
|
||||
}
|
||||
Q_UNREACHABLE();
|
||||
return QByteArray();
|
||||
|
|
@ -3230,9 +3225,11 @@ QByteArray QByteArray::toUpper_helper(QByteArray &a)
|
|||
|
||||
void QByteArray::clear()
|
||||
{
|
||||
if (!d->deref())
|
||||
Data::deallocate(d);
|
||||
d = Data::sharedNull();
|
||||
if (!d.d->deref())
|
||||
Data::deallocate(d.d);
|
||||
d.d = Data::sharedNull();
|
||||
d.b = Data::sharedNullData();
|
||||
d.size = 0;
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE))
|
||||
|
|
@ -3709,13 +3706,13 @@ QByteArray QByteArray::trimmed_helper(QByteArray &a)
|
|||
QByteArray QByteArray::leftJustified(int width, char fill, bool truncate) const
|
||||
{
|
||||
QByteArray result;
|
||||
int len = d->size;
|
||||
int len = size();
|
||||
int padlen = width - len;
|
||||
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.b, data(), len);
|
||||
memset(result.d.b+len, fill, padlen);
|
||||
} else {
|
||||
if (truncate)
|
||||
result = left(width);
|
||||
|
|
@ -3746,13 +3743,13 @@ QByteArray QByteArray::leftJustified(int width, char fill, bool truncate) const
|
|||
QByteArray QByteArray::rightJustified(int width, char fill, bool truncate) const
|
||||
{
|
||||
QByteArray result;
|
||||
int len = d->size;
|
||||
int len = size();
|
||||
int padlen = width - len;
|
||||
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.b+padlen, data(), len);
|
||||
memset(result.d.b, fill, padlen);
|
||||
} else {
|
||||
if (truncate)
|
||||
result = left(width);
|
||||
|
|
@ -3762,7 +3759,10 @@ QByteArray QByteArray::rightJustified(int width, char fill, bool truncate) const
|
|||
return result;
|
||||
}
|
||||
|
||||
bool QByteArray::isNull() const { return d == QArrayData::sharedNull(); }
|
||||
bool QByteArray::isNull() const
|
||||
{
|
||||
return d.d == QArrayData::sharedNull();
|
||||
}
|
||||
|
||||
static qlonglong toIntegral_helper(const char *data, bool *ok, int base, qlonglong)
|
||||
{
|
||||
|
|
@ -4089,19 +4089,19 @@ QByteArray QByteArray::toBase64(Base64Options options) const
|
|||
const char padchar = '=';
|
||||
int padlen = 0;
|
||||
|
||||
QByteArray tmp((d->size + 2) / 3 * 4, Qt::Uninitialized);
|
||||
QByteArray tmp((size() + 2) / 3 * 4, Qt::Uninitialized);
|
||||
|
||||
int i = 0;
|
||||
char *out = tmp.data();
|
||||
while (i < d->size) {
|
||||
while (i < size()) {
|
||||
// encode 3 bytes at a time
|
||||
int chunk = 0;
|
||||
chunk |= int(uchar(d->data()[i++])) << 16;
|
||||
if (i == d->size) {
|
||||
chunk |= int(uchar(data()[i++])) << 16;
|
||||
if (i == size()) {
|
||||
padlen = 2;
|
||||
} else {
|
||||
chunk |= int(uchar(d->data()[i++])) << 8;
|
||||
if (i == d->size)
|
||||
chunk |= int(uchar(data()[i++])) << 8;
|
||||
if (i == size())
|
||||
padlen = 1;
|
||||
else
|
||||
chunk |= int(uchar(data()[i++]));
|
||||
|
|
@ -4431,17 +4431,23 @@ QByteArray QByteArray::number(double n, char f, int prec)
|
|||
|
||||
QByteArray QByteArray::fromRawData(const char *data, int size)
|
||||
{
|
||||
Data *x;
|
||||
QByteArrayData x;
|
||||
if (!data) {
|
||||
x = Data::sharedNull();
|
||||
x.d = Data::sharedNull();
|
||||
x.b = Data::sharedNullData();
|
||||
x.size = 0;
|
||||
} else if (!size) {
|
||||
x = Data::allocate(0).first;
|
||||
QPair<Data *, char *> pair = Data::allocate(0);
|
||||
x.d = pair.first;
|
||||
x.b = pair.second;
|
||||
x.size = 0;
|
||||
} else {
|
||||
x = Data::fromRawData(data, size).ptr;
|
||||
Q_CHECK_PTR(x);
|
||||
x.d = Data::fromRawData(data, size).ptr;
|
||||
Q_CHECK_PTR(x.d);
|
||||
x.b = const_cast<char *>(data);
|
||||
x.size = size;
|
||||
}
|
||||
QByteArrayDataPtr dataPtr = { x };
|
||||
return QByteArray(dataPtr);
|
||||
return QByteArray(x);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
@ -4462,11 +4468,11 @@ QByteArray &QByteArray::setRawData(const char *data, uint size)
|
|||
{
|
||||
if (!data || !size) {
|
||||
clear();
|
||||
} else if (d->isShared() || (d->flags & Data::RawDataType) == 0) {
|
||||
} else if (d.d->isShared() || (d.d->flags & Data::RawDataType) == 0) {
|
||||
*this = fromRawData(data, size);
|
||||
} else {
|
||||
d->size = size;
|
||||
d->offset = data - reinterpret_cast<char *>(d);
|
||||
d.size = size;
|
||||
d.b = const_cast<char *>(data);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -4579,14 +4585,14 @@ QByteArray QByteArray::fromHex(const QByteArray &hexEncoded)
|
|||
*/
|
||||
QByteArray QByteArray::toHex(char separator) const
|
||||
{
|
||||
if (!d->size)
|
||||
if (isEmpty())
|
||||
return QByteArray();
|
||||
|
||||
const int length = separator ? (d->size * 3 - 1) : (d->size * 2);
|
||||
const int length = separator ? (size() * 3 - 1) : (size() * 2);
|
||||
QByteArray hex(length, Qt::Uninitialized);
|
||||
char *hexData = hex.data();
|
||||
const uchar *data = (const uchar *)d->data();
|
||||
for (int i = 0, o = 0; i < d->size; ++i) {
|
||||
const uchar *data = (const uchar *)this->data();
|
||||
for (int i = 0, o = 0; i < size(); ++i) {
|
||||
hexData[o++] = QtMiscUtils::toHexLower(data[i] >> 4);
|
||||
hexData[o++] = QtMiscUtils::toHexLower(data[i] & 0xf);
|
||||
|
||||
|
|
|
|||
|
|
@ -114,40 +114,22 @@ class QByteRef;
|
|||
class QString;
|
||||
class QDataStream;
|
||||
|
||||
typedef QArrayData QByteArrayData;
|
||||
|
||||
template<int N> struct QStaticByteArrayData
|
||||
struct QByteArrayData
|
||||
{
|
||||
QByteArrayData ba;
|
||||
char data[N + 1];
|
||||
|
||||
QByteArrayData *data_ptr() const
|
||||
{
|
||||
Q_ASSERT(ba.isStatic());
|
||||
return const_cast<QByteArrayData *>(&ba);
|
||||
}
|
||||
QArrayData *d;
|
||||
char *b;
|
||||
uint size;
|
||||
};
|
||||
|
||||
struct QByteArrayDataPtr
|
||||
{
|
||||
QByteArrayData *ptr;
|
||||
};
|
||||
|
||||
#define Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \
|
||||
Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset)
|
||||
/**/
|
||||
|
||||
#define Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(size) \
|
||||
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, sizeof(QByteArrayData)) \
|
||||
/**/
|
||||
|
||||
# define QByteArrayLiteral(str) \
|
||||
([]() -> QByteArray { \
|
||||
enum { Size = sizeof(str) - 1 }; \
|
||||
static const QStaticByteArrayData<Size> qbytearray_literal = { \
|
||||
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(Size), \
|
||||
str }; \
|
||||
QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; \
|
||||
static const QArrayData qbytearray_literal = { \
|
||||
Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, Size, 0, sizeof(QArrayData) }; \
|
||||
QByteArrayData holder = { \
|
||||
const_cast<QArrayData *>(&qbytearray_literal), \
|
||||
const_cast<char *>(str), \
|
||||
Size }; \
|
||||
const QByteArray ba(holder); \
|
||||
return ba; \
|
||||
}()) \
|
||||
|
|
@ -177,10 +159,10 @@ public:
|
|||
|
||||
QByteArray &operator=(const QByteArray &) noexcept;
|
||||
QByteArray &operator=(const char *str);
|
||||
inline QByteArray(QByteArray && other) noexcept : d(other.d) { other.d = Data::sharedNull(); }
|
||||
inline QByteArray(QByteArray && other) noexcept : d(std::move(other.d))
|
||||
{ other.d.d = Data::sharedNull(); other.d.b = Data::sharedNullData(); other.d.size = 0; }
|
||||
inline QByteArray &operator=(QByteArray &&other) noexcept
|
||||
{ qSwap(d, other.d); return *this; }
|
||||
|
||||
inline void swap(QByteArray &other) noexcept
|
||||
{ qSwap(d, other.d); }
|
||||
|
||||
|
|
@ -203,7 +185,8 @@ public:
|
|||
inline const char *constData() const;
|
||||
inline void detach();
|
||||
inline bool isDetached() const;
|
||||
inline bool isSharedWith(const QByteArray &other) const { return d == other.d; }
|
||||
inline bool isSharedWith(const QByteArray &other) const
|
||||
{ return data() == other.data() && size() == other.size(); }
|
||||
void clear();
|
||||
|
||||
inline char at(int i) const;
|
||||
|
|
@ -431,18 +414,18 @@ public:
|
|||
static inline QByteArray fromStdString(const std::string &s);
|
||||
inline std::string toStdString() const;
|
||||
|
||||
inline int count() const { return d->size; }
|
||||
int length() const { return d->size; }
|
||||
inline int count() const { return int(d.size); }
|
||||
int length() const { return int(d.size); }
|
||||
bool isNull() const;
|
||||
|
||||
inline QByteArray(QByteArrayDataPtr dd)
|
||||
: d(static_cast<Data *>(dd.ptr))
|
||||
explicit inline QByteArray(const QByteArrayData &dd)
|
||||
: d(dd)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
operator QNoImplicitBoolCast() const;
|
||||
Data *d;
|
||||
QByteArrayData d;
|
||||
void reallocData(uint alloc, Data::ArrayOptions options);
|
||||
void expand(int i);
|
||||
QByteArray nulTerminated() const;
|
||||
|
|
@ -460,63 +443,63 @@ private:
|
|||
friend class QString;
|
||||
friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, int nbytes);
|
||||
public:
|
||||
typedef Data * DataPtr;
|
||||
typedef QByteArrayData DataPtr;
|
||||
inline DataPtr &data_ptr() { return d; }
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)
|
||||
|
||||
inline QByteArray::QByteArray() noexcept : d(Data::sharedNull()) { }
|
||||
inline QByteArray::~QByteArray() { if (!d->deref()) Data::deallocate(d); }
|
||||
inline QByteArray::QByteArray() noexcept { d.d = Data::sharedNull(); d.b = Data::sharedNullData(); d.size = 0; }
|
||||
inline QByteArray::~QByteArray() { if (!d.d->deref()) Data::deallocate(d.d); }
|
||||
inline int QByteArray::size() const
|
||||
{ return d->size; }
|
||||
{ return int(d.size); }
|
||||
|
||||
inline char QByteArray::at(int i) const
|
||||
{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; }
|
||||
{ Q_ASSERT(uint(i) < uint(size())); return d.b[i]; }
|
||||
inline char QByteArray::operator[](int i) const
|
||||
{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; }
|
||||
{ Q_ASSERT(uint(i) < uint(size())); return d.b[i]; }
|
||||
|
||||
inline bool QByteArray::isEmpty() const
|
||||
{ return d->size == 0; }
|
||||
{ return size() == 0; }
|
||||
#ifndef QT_NO_CAST_FROM_BYTEARRAY
|
||||
inline QByteArray::operator const char *() const
|
||||
{ return d->data(); }
|
||||
{ return data(); }
|
||||
inline QByteArray::operator const void *() const
|
||||
{ return d->data(); }
|
||||
{ return data(); }
|
||||
#endif
|
||||
inline char *QByteArray::data()
|
||||
{ detach(); return d->data(); }
|
||||
{ detach(); return d.b; }
|
||||
inline const char *QByteArray::data() const
|
||||
{ return d->data(); }
|
||||
{ return d.b; }
|
||||
inline const char *QByteArray::constData() const
|
||||
{ return d->data(); }
|
||||
{ return d.b; }
|
||||
inline void QByteArray::detach()
|
||||
{ if (d->needsDetach()) reallocData(uint(d->size) + 1u, d->detachFlags()); }
|
||||
{ if (d.d->needsDetach()) reallocData(uint(size()) + 1u, d.d->detachFlags()); }
|
||||
inline bool QByteArray::isDetached() const
|
||||
{ return !d->isShared(); }
|
||||
{ return !d.d->isShared(); }
|
||||
inline QByteArray::QByteArray(const QByteArray &a) noexcept : d(a.d)
|
||||
{ d->ref(); }
|
||||
{ d.d->ref(); }
|
||||
|
||||
inline int QByteArray::capacity() const
|
||||
{ int realCapacity = d->constAllocatedCapacity(); return realCapacity ? realCapacity - 1 : 0; }
|
||||
{ int realCapacity = d.d->constAllocatedCapacity(); return realCapacity ? realCapacity - 1 : 0; }
|
||||
|
||||
inline void QByteArray::reserve(int asize)
|
||||
{
|
||||
if (d->needsDetach() || asize > capacity()) {
|
||||
reallocData(qMax(uint(size()), uint(asize)) + 1u, d->detachFlags() | Data::CapacityReserved);
|
||||
if (d.d->needsDetach() || asize > capacity()) {
|
||||
reallocData(qMax(uint(size()), uint(asize)) + 1u, d.d->detachFlags() | Data::CapacityReserved);
|
||||
} else {
|
||||
d->flags |= Data::CapacityReserved;
|
||||
d.d->flags |= Data::CapacityReserved;
|
||||
}
|
||||
}
|
||||
|
||||
inline void QByteArray::squeeze()
|
||||
{
|
||||
if ((d->flags & Data::CapacityReserved) == 0)
|
||||
if ((d.d->flags & Data::CapacityReserved) == 0)
|
||||
return;
|
||||
if (d->needsDetach() || d->size < capacity()) {
|
||||
reallocData(uint(d->size) + 1u, d->detachFlags() & ~Data::CapacityReserved);
|
||||
if (d.d->needsDetach() || size() < capacity()) {
|
||||
reallocData(uint(size()) + 1u, d.d->detachFlags() & ~Data::CapacityReserved);
|
||||
} else {
|
||||
d->flags &= ~Data::CapacityReserved;
|
||||
d.d->flags &= uint(~Data::CapacityReserved);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -550,8 +533,8 @@ public:
|
|||
inline operator char() const
|
||||
{
|
||||
using namespace QtPrivate::DeprecatedRefClassBehavior;
|
||||
if (Q_LIKELY(i < a.d->size))
|
||||
return a.d->data()[i];
|
||||
if (Q_LIKELY(i < a.size()))
|
||||
return a.constData()[i];
|
||||
#ifdef QT_DEBUG
|
||||
warn(WarningType::OutOfRange, EmittingClass::QByteRef);
|
||||
#endif
|
||||
|
|
@ -560,7 +543,7 @@ public:
|
|||
inline QByteRef &operator=(char c)
|
||||
{
|
||||
using namespace QtPrivate::DeprecatedRefClassBehavior;
|
||||
if (Q_UNLIKELY(i >= a.d->size)) {
|
||||
if (Q_UNLIKELY(i >= a.size())) {
|
||||
#ifdef QT_DEBUG
|
||||
warn(WarningType::OutOfRange, EmittingClass::QByteRef);
|
||||
#endif
|
||||
|
|
@ -572,7 +555,7 @@ public:
|
|||
#endif
|
||||
a.detach();
|
||||
}
|
||||
a.d->data()[i] = c;
|
||||
a.d.b[i] = c;
|
||||
return *this;
|
||||
}
|
||||
inline QByteRef &operator=(const QByteRef &c)
|
||||
|
|
@ -580,17 +563,17 @@ public:
|
|||
return operator=(char(c));
|
||||
}
|
||||
inline bool operator==(char c) const
|
||||
{ return a.d->data()[i] == c; }
|
||||
{ return a.data()[i] == c; }
|
||||
inline bool operator!=(char c) const
|
||||
{ return a.d->data()[i] != c; }
|
||||
{ return a.data()[i] != c; }
|
||||
inline bool operator>(char c) const
|
||||
{ return a.d->data()[i] > c; }
|
||||
{ return a.data()[i] > c; }
|
||||
inline bool operator>=(char c) const
|
||||
{ return a.d->data()[i] >= c; }
|
||||
{ return a.data()[i] >= c; }
|
||||
inline bool operator<(char c) const
|
||||
{ return a.d->data()[i] < c; }
|
||||
{ return a.data()[i] < c; }
|
||||
inline bool operator<=(char c) const
|
||||
{ return a.d->data()[i] <= c; }
|
||||
{ return a.data()[i] <= c; }
|
||||
};
|
||||
|
||||
inline QByteRef QByteArray::operator[](int i)
|
||||
|
|
@ -598,23 +581,23 @@ inline QByteRef QByteArray::operator[](int i)
|
|||
inline QByteRef QByteArray::front() { return operator[](0); }
|
||||
inline QByteRef QByteArray::back() { return operator[](size() - 1); }
|
||||
inline QByteArray::iterator QByteArray::begin()
|
||||
{ detach(); return d->data(); }
|
||||
{ return data(); }
|
||||
inline QByteArray::const_iterator QByteArray::begin() const
|
||||
{ return d->data(); }
|
||||
{ return data(); }
|
||||
inline QByteArray::const_iterator QByteArray::cbegin() const
|
||||
{ return d->data(); }
|
||||
{ return data(); }
|
||||
inline QByteArray::const_iterator QByteArray::constBegin() const
|
||||
{ return d->data(); }
|
||||
{ return data(); }
|
||||
inline QByteArray::iterator QByteArray::end()
|
||||
{ detach(); return d->data() + d->size; }
|
||||
{ return data() + size(); }
|
||||
inline QByteArray::const_iterator QByteArray::end() const
|
||||
{ return d->data() + d->size; }
|
||||
{ return data() + size(); }
|
||||
inline QByteArray::const_iterator QByteArray::cend() const
|
||||
{ return d->data() + d->size; }
|
||||
{ return data() + size(); }
|
||||
inline QByteArray::const_iterator QByteArray::constEnd() const
|
||||
{ return d->data() + d->size; }
|
||||
{ return data() + size(); }
|
||||
inline QByteArray &QByteArray::append(int n, char ch)
|
||||
{ return insert(d->size, n, ch); }
|
||||
{ return insert(size(), n, ch); }
|
||||
inline QByteArray &QByteArray::prepend(int n, char ch)
|
||||
{ return insert(0, n, ch); }
|
||||
inline QByteArray &QByteArray::operator+=(char c)
|
||||
|
|
|
|||
|
|
@ -80,11 +80,6 @@ public:
|
|||
inline QByteArray join(char sep) const
|
||||
{ return QtPrivate::QByteArrayList_join(self(), &sep, 1); }
|
||||
|
||||
#if 0
|
||||
inline int indexOf(const char *needle, int from = 0) const
|
||||
{ return QtPrivate::QByteArrayList_indexOf(self(), needle, from); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef QVector<QByteArray> Self;
|
||||
Self *self() { return static_cast<Self *>(this); }
|
||||
|
|
|
|||
|
|
@ -2288,8 +2288,8 @@ void QString::resize(int size)
|
|||
|
||||
if (d.d->needsDetach() || size > capacity())
|
||||
reallocData(uint(size) + 1u, true);
|
||||
d.size = size;
|
||||
if (d.d->isMutable()) {
|
||||
d.size = size;
|
||||
d.b[size] = '\0';
|
||||
}
|
||||
}
|
||||
|
|
@ -5170,24 +5170,24 @@ QByteArray QString::toLatin1_helper_inplace(QString &s)
|
|||
|
||||
// Swap the d pointers.
|
||||
// Kids, avert your eyes. Don't try this at home.
|
||||
QArrayData *ba_d = s.d.d;
|
||||
QByteArrayData ba_d = {
|
||||
s.d.d,
|
||||
reinterpret_cast<char *>(s.d.b),
|
||||
length
|
||||
};
|
||||
|
||||
// multiply the allocated capacity by sizeof(ushort)
|
||||
ba_d->alloc *= sizeof(ushort);
|
||||
ba_d.d->alloc *= sizeof(ushort);
|
||||
|
||||
// reset ourselves to QString()
|
||||
s.d = QString().d;
|
||||
|
||||
// do the in-place conversion
|
||||
uchar *dst = reinterpret_cast<uchar *>(ba_d->data());
|
||||
qt_to_latin1(dst, data, length);
|
||||
dst[length] = '\0';
|
||||
|
||||
QByteArrayDataPtr badptr = { ba_d };
|
||||
return QByteArray(badptr);
|
||||
qt_to_latin1(reinterpret_cast<uchar *>(ba_d.b), data, length);
|
||||
ba_d.b[length] = '\0';
|
||||
return QByteArray(ba_d);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\fn QByteArray QString::toLatin1() const
|
||||
|
||||
|
|
|
|||
|
|
@ -263,8 +263,8 @@ public:
|
|||
inline QString &operator=(QString &&other) noexcept
|
||||
{ qSwap(d, other.d); return *this; }
|
||||
inline void swap(QString &other) noexcept { qSwap(d, other.d); }
|
||||
inline int size() const { return d.size; }
|
||||
inline int count() const { return d.size; }
|
||||
inline int size() const { return int(d.size); }
|
||||
inline int count() const { return int(d.size); }
|
||||
inline int length() const;
|
||||
inline bool isEmpty() const;
|
||||
void resize(int size);
|
||||
|
|
@ -1020,7 +1020,7 @@ QString QStringView::toString() const
|
|||
inline QString::QString(QLatin1String aLatin1) : d(fromLatin1_helper(aLatin1.latin1(), aLatin1.size()))
|
||||
{ }
|
||||
inline int QString::length() const
|
||||
{ return d.size; }
|
||||
{ return int(d.size); }
|
||||
inline const QChar QString::at(int i) const
|
||||
{ Q_ASSERT(uint(i) < uint(size())); return QChar(d.b[i]); }
|
||||
inline const QChar QString::operator[](int i) const
|
||||
|
|
@ -1259,7 +1259,7 @@ inline QString::~QString() { if (!d.d->deref()) Data::deallocate(d.d); }
|
|||
inline void QString::reserve(int asize)
|
||||
{
|
||||
if (d.d->needsDetach() || asize >= capacity())
|
||||
reallocData(qMax(asize, size()) + 1u);
|
||||
reallocData(uint(qMax(asize, size())) + 1u);
|
||||
|
||||
// we're not shared anymore, for sure
|
||||
d.d->flags |= Data::CapacityReserved;
|
||||
|
|
@ -1273,7 +1273,7 @@ inline void QString::squeeze()
|
|||
reallocData(uint(d.size) + 1u);
|
||||
|
||||
// we're not shared anymore, for sure
|
||||
d.d->flags &= ~Data::CapacityReserved;
|
||||
d.d->flags &= uint(~Data::CapacityReserved);
|
||||
}
|
||||
|
||||
inline QString &QString::setUtf16(const ushort *autf16, int asize)
|
||||
|
|
|
|||
|
|
@ -199,11 +199,6 @@ struct QPodArrayOps
|
|||
|
||||
bool compare(const T *begin1, const T *begin2, size_t n) const
|
||||
{
|
||||
// only use memcmp for fundamental types or pointers.
|
||||
// Other types could have padding in the data structure or custom comparison
|
||||
// operators that would break the comparison using memcmp
|
||||
if (QArrayDataPointer<T>::pass_parameter_by_value)
|
||||
return ::memcmp(begin1, begin2, n * sizeof(T)) == 0;
|
||||
const T *end1 = begin1 + n;
|
||||
while (begin1 != end1) {
|
||||
if (*begin1 == *begin2)
|
||||
|
|
|
|||
|
|
@ -149,36 +149,17 @@ private slots:
|
|||
void stdString();
|
||||
};
|
||||
|
||||
static const struct StaticByteArrays {
|
||||
struct Standard {
|
||||
QByteArrayData data;
|
||||
const char string[8];
|
||||
} standard;
|
||||
struct NotNullTerminated {
|
||||
QByteArrayData data;
|
||||
const char string[8];
|
||||
} notNullTerminated;
|
||||
struct Shifted {
|
||||
QByteArrayData data;
|
||||
const char dummy; // added to change offset of string
|
||||
const char string[8];
|
||||
} shifted;
|
||||
struct ShiftedNotNullTerminated {
|
||||
QByteArrayData data;
|
||||
const char dummy; // added to change offset of string
|
||||
const char string[8];
|
||||
} shiftedNotNullTerminated;
|
||||
|
||||
} statics = {{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(4), "data"}
|
||||
,{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(4), "dataBAD"}
|
||||
,{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(4, sizeof(QByteArrayData) + sizeof(char)), 0, "data"}
|
||||
,{Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(4, sizeof(QByteArrayData) + sizeof(char)), 0, "dataBAD"}
|
||||
};
|
||||
|
||||
static const QByteArrayDataPtr staticStandard = { const_cast<QByteArrayData *>(&statics.standard.data) };
|
||||
static const QByteArrayDataPtr staticNotNullTerminated = { const_cast<QByteArrayData *>(&statics.notNullTerminated.data) };
|
||||
static const QByteArrayDataPtr staticShifted = { const_cast<QByteArrayData *>(&statics.shifted.data) };
|
||||
static const QByteArrayDataPtr staticShiftedNotNullTerminated = { const_cast<QByteArrayData *>(&statics.shiftedNotNullTerminated.data) };
|
||||
static const QArrayData staticDataFlags = { Q_BASIC_ATOMIC_INITIALIZER(-1), QArrayData::StaticDataFlags, 0 };
|
||||
static const QByteArrayData staticStandard = {
|
||||
static_cast<QTypedArrayData<char> *>(const_cast<QArrayData *>(&staticDataFlags)),
|
||||
const_cast<char *>("data"),
|
||||
4
|
||||
};
|
||||
static const QByteArrayData staticNotNullTerminated = {
|
||||
static_cast<QTypedArrayData<char> *>(const_cast<QArrayData *>(&staticDataFlags)),
|
||||
const_cast<char *>("dataBAD"),
|
||||
4
|
||||
};
|
||||
|
||||
template <class T> const T &verifyZeroTermination(const T &t) { return t; }
|
||||
|
||||
|
|
@ -189,8 +170,7 @@ QByteArray verifyZeroTermination(const QByteArray &ba)
|
|||
QByteArray::DataPtr baDataPtr = const_cast<QByteArray &>(ba).data_ptr();
|
||||
|
||||
// Skip if isStatic() or fromRawData(), as those offer no guarantees
|
||||
if (baDataPtr->isStatic()
|
||||
|| baDataPtr->offset != QByteArray().data_ptr()->offset)
|
||||
if (baDataPtr.d->isStatic() || baDataPtr.d->flags & QArrayData::RawDataType)
|
||||
return ba;
|
||||
|
||||
int baSize = ba.size();
|
||||
|
|
@ -201,7 +181,7 @@ QByteArray verifyZeroTermination(const QByteArray &ba)
|
|||
.arg(baTerminator, 2, 16, QChar('0')).toLatin1();
|
||||
|
||||
// Skip mutating checks on shared strings
|
||||
if (baDataPtr->isShared())
|
||||
if (baDataPtr.d->isShared())
|
||||
return ba;
|
||||
|
||||
const char *baData = ba.constData();
|
||||
|
|
@ -951,9 +931,7 @@ void tst_QByteArray::prependExtended_data()
|
|||
QTest::addColumn<QByteArray>("array");
|
||||
QTest::newRow("literal") << QByteArray(QByteArrayLiteral("data"));
|
||||
QTest::newRow("standard") << QByteArray(staticStandard);
|
||||
QTest::newRow("shifted") << QByteArray(staticShifted);
|
||||
QTest::newRow("notNullTerminated") << QByteArray(staticNotNullTerminated);
|
||||
QTest::newRow("shiftedNotNullTerminated") << QByteArray(staticShiftedNotNullTerminated);
|
||||
QTest::newRow("non static data") << QByteArray("data");
|
||||
QTest::newRow("from raw data") << QByteArray::fromRawData("data", 4);
|
||||
QTest::newRow("from raw data not terminated") << QByteArray::fromRawData("dataBAD", 4);
|
||||
|
|
@ -2019,14 +1997,6 @@ void tst_QByteArray::repeated_data() const
|
|||
<< QByteArray(staticStandard)
|
||||
<< QByteArray("datadatadatadata")
|
||||
<< 4;
|
||||
QTest::newRow("static shifted not null terminated")
|
||||
<< QByteArray(staticShiftedNotNullTerminated)
|
||||
<< QByteArray("datadatadatadata")
|
||||
<< 4;
|
||||
QTest::newRow("static shifted")
|
||||
<< QByteArray(staticShifted)
|
||||
<< QByteArray("datadatadatadata")
|
||||
<< 4;
|
||||
}
|
||||
|
||||
void tst_QByteArray::byteRefDetaching() const
|
||||
|
|
@ -2198,8 +2168,7 @@ void tst_QByteArray::literals()
|
|||
|
||||
QVERIFY(str.length() == 4);
|
||||
QVERIFY(str == "abcd");
|
||||
QVERIFY(str.data_ptr()->isStatic());
|
||||
QVERIFY(str.data_ptr()->offset == sizeof(QByteArrayData));
|
||||
QVERIFY(str.data_ptr().d->isStatic());
|
||||
|
||||
const char *s = str.constData();
|
||||
QByteArray str2 = str;
|
||||
|
|
|
|||
Loading…
Reference in New Issue