diff options
Diffstat (limited to 'src/corelib/text/qbytearray.cpp')
-rw-r--r-- | src/corelib/text/qbytearray.cpp | 661 |
1 files changed, 335 insertions, 326 deletions
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp index 1b21c98a2f..d9f0ee405a 100644 --- a/src/corelib/text/qbytearray.cpp +++ b/src/corelib/text/qbytearray.cpp @@ -14,7 +14,6 @@ #include "private/qsimd_p.h" #include "qstringalgorithms_p.h" #include "qscopedpointer.h" -#include "qbytearray_p.h" #include "qstringconverter_p.h" #include <qdatastream.h> #include <qmath.h> @@ -34,7 +33,13 @@ #include <algorithm> -#define IS_RAW_DATA(d) ((d)->flags() & QArrayData::RawDataType) +#ifdef Q_OS_WIN +# if !defined(QT_BOOTSTRAPPED) && (defined(QT_NO_CAST_FROM_ASCII) || defined(QT_NO_CAST_FROM_BYTEARRAY)) +// MSVC requires this, but let's apply it to MinGW compilers too, just in case +# error "This file cannot be compiled with QT_NO_CAST_{TO,FROM}_ASCII, " \ + "otherwise some QByteArray functions will not get exported." +# endif +#endif QT_BEGIN_NAMESPACE @@ -51,15 +56,35 @@ static constexpr inline uchar asciiLower(uchar c) return c >= 'A' && c <= 'Z' ? c | 0x20 : c; } -qsizetype qFindByteArray( - const char *haystack0, qsizetype haystackLen, qsizetype from, - const char *needle0, qsizetype needleLen); - /***************************************************************************** Safe and portable C string functions; extensions to standard string.h *****************************************************************************/ /*! \relates QByteArray + \internal + + Wrapper around memrchr() for systems that don't have it. It's provided in + every system because, as a GNU extension, memrchr() may not be declared in + string.h depending on how strict the compiler was asked to be. + + Used in QByteArrayView::lastIndexOf() overload for a single char. +*/ +const void *qmemrchr(const void *s, int needle, size_t size) noexcept +{ +#if QT_CONFIG(memrchr) + return memrchr(s, needle, size); +#endif + auto b = static_cast<const char *>(s); + const char *n = b + size; + while (n-- != b) { + if (*n == needle) + return n; + } + return nullptr; +} + + +/*! \relates QByteArray Returns a duplicate string. @@ -278,7 +303,7 @@ int qstricmp(const char *str1, const char *str2) // yes, find out where uint start = qCountTrailingZeroBits(mask); uint end = sizeof(mask) * 8 - qCountLeadingZeroBits(mask); - Q_ASSUME(end >= start); + Q_ASSERT(end >= start); offset += start; n = end - start; break; @@ -687,7 +712,7 @@ QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel) if (nbytes < SingleAllocLimit) { // use maximum size capacity += compressBound(uLong(nbytes)); // cannot overflow (both times)! - return QArrayDataPointer{QTypedArrayData<char>::allocate(capacity)}; + return QArrayDataPointer<char>(capacity); } // for larger buffers, assume it compresses optimally, and @@ -697,7 +722,7 @@ QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel) // but use a nearby power-of-two (faster) capacity += std::max(qsizetype(compressBound(uLong(SingleAllocLimit))), nbytes / MaxCompressionFactor); - return QArrayDataPointer{QTypedArrayData<char>::allocate(capacity, QArrayData::Grow)}; + return QArrayDataPointer<char>(capacity, 0, QArrayData::Grow); }(); if (out.data() == nullptr) // allocation failed @@ -774,7 +799,7 @@ QByteArray qUncompress(const uchar* data, qsizetype nbytes) return QByteArray(); } - constexpr auto MaxDecompressedSize = size_t(MaxByteArraySize); + constexpr auto MaxDecompressedSize = size_t(QByteArray::max_size()); if constexpr (MaxDecompressedSize < std::numeric_limits<CompressSizeHint_t>::max()) { if (expectedSize > MaxDecompressedSize) return tooMuchData(ZLibOp::Decompression); @@ -785,7 +810,7 @@ QByteArray qUncompress(const uchar* data, qsizetype nbytes) qsizetype capacity = std::max(qsizetype(expectedSize), // cannot overflow! nbytes); - QArrayDataPointer d(QTypedArrayData<char>::allocate(capacity, QArrayData::KeepSize)); + QArrayDataPointer<char> d(capacity); return xxflate(ZLibOp::Decompression, std::move(d), {data + HeaderSize, nbytes - HeaderSize}, [] (z_stream *zs) { return inflateInit(zs); }, [] (z_stream *zs, size_t) { return inflate(zs, Z_NO_FLUSH); }, @@ -804,6 +829,14 @@ QByteArray qUncompress(const uchar* data, qsizetype nbytes) \reentrant + \compares strong + \compareswith strong {const char *} QByteArrayView + \endcompareswith + \compareswith strong QChar char16_t QString QStringView QLatin1StringView \ + QUtf8StringView + When comparing with string types, the content is interpreted as utf-8. + \endcompareswith + QByteArray can be used to store both raw bytes (including '\\0's) and traditional 8-bit '\\0'-terminated strings. Using QByteArray is much more convenient than using \c{const char *}. Behind the @@ -1276,6 +1309,7 @@ QByteArray::iterator QByteArray::erase(QByteArray::const_iterator first, QByteAr /*! \fn QByteArray::iterator QByteArray::erase(QByteArray::const_iterator it) + \overload \since 6.5 Removes the character denoted by \c it from the byte array. @@ -1335,6 +1369,9 @@ QByteArray &QByteArray::operator=(const QByteArray & other) noexcept \overload Assigns \a str to this byte array. + + \a str is assumed to point to a null-terminated string, and its length is + determined dynamically. */ QByteArray &QByteArray::operator=(const char *str) @@ -1344,14 +1381,7 @@ QByteArray &QByteArray::operator=(const char *str) } else if (!*str) { d = DataPointer::fromRawData(&_empty, 0); } else { - const qsizetype len = qsizetype(strlen(str)); - const auto capacityAtEnd = d->allocatedCapacity() - d.freeSpaceAtBegin(); - if (d->needsDetach() || len > capacityAtEnd - || (len < size() && len < (capacityAtEnd >> 1))) - // ### inefficient! reallocData() does copy the old data and we then overwrite it in the next line - reallocData(len, QArrayData::KeepSize); - memcpy(d.data(), str, len + 1); // include null terminator - d.size = len; + assign(str); } return *this; } @@ -1389,6 +1419,15 @@ QByteArray &QByteArray::operator=(const char *str) \sa isEmpty(), resize() */ +/*! \fn qsizetype QByteArray::max_size() + \since 6.8 + + This function is provided for STL compatibility. + It returns the maximum number of elements that the byte array can + theoretically hold. In practice, the number can be much smaller, + limited by the amount of memory available to the system. +*/ + /*! \fn bool QByteArray::isEmpty() const Returns \c true if the byte array has size 0; otherwise returns \c false. @@ -1802,7 +1841,7 @@ QByteArray::QByteArray(const char *data, qsizetype size) if (!size) { d = DataPointer::fromRawData(&_empty, 0); } else { - d = DataPointer(Data::allocate(size), size); + d = DataPointer(size, size); Q_CHECK_PTR(d.data()); memcpy(d.data(), data, size); d.data()[size] = '\0'; @@ -1821,7 +1860,7 @@ QByteArray::QByteArray(qsizetype size, char ch) if (size <= 0) { d = DataPointer::fromRawData(&_empty, 0); } else { - d = DataPointer(Data::allocate(size), size); + d = DataPointer(size, size); Q_CHECK_PTR(d.data()); memset(d.data(), ch, size); d.data()[size] = '\0'; @@ -1829,8 +1868,6 @@ QByteArray::QByteArray(qsizetype size, char ch) } /*! - \internal - Constructs a byte array of size \a size with uninitialized contents. */ @@ -1839,7 +1876,7 @@ QByteArray::QByteArray(qsizetype size, Qt::Initialization) if (size <= 0) { d = DataPointer::fromRawData(&_empty, 0); } else { - d = DataPointer(Data::allocate(size), size); + d = DataPointer(size, size); Q_CHECK_PTR(d.data()); d.data()[size] = '\0'; } @@ -1899,6 +1936,21 @@ void QByteArray::resize(qsizetype newSize, char c) } /*! + \since 6.8 + + Resizes the byte array to \a size bytes. If the size of the + byte array grows, the new bytes are uninitialized. + + The behavior is identical to \c{resize(size)}. + + \sa resize() +*/ +void QByteArray::resizeForOverwrite(qsizetype size) +{ + resize(size); +} + +/*! Sets every byte in the byte array to \a ch. If \a size is different from -1 (the default), the byte array is resized to size \a size beforehand. @@ -1928,7 +1980,7 @@ void QByteArray::reallocData(qsizetype alloc, QArrayData::AllocationOption optio const bool cannotUseReallocate = d.freeSpaceAtBegin() > 0; if (d->needsDetach() || cannotUseReallocate) { - DataPointer dd(Data::allocate(alloc, option), qMin(alloc, d.size)); + DataPointer dd(alloc, qMin(alloc, d.size), option); Q_CHECK_PTR(dd.data()); if (dd.size > 0) ::memcpy(dd.data(), d.data(), dd.size); @@ -2048,9 +2100,17 @@ QByteArray &QByteArray::prepend(const QByteArray &ba) QByteArray &QByteArray::append(const QByteArray &ba) { - if (size() == 0 && ba.size() > d->freeSpaceAtEnd() && ba.d.isMutable()) - return (*this = ba); - return append(QByteArrayView(ba)); + if (!ba.isNull()) { + if (isNull()) { + if (Q_UNLIKELY(!ba.d.isMutable())) + assign(ba); // fromRawData, so we do a deep copy + else + operator=(ba); + } else if (ba.size()) { + append(QByteArrayView(ba)); + } + } + return *this; } /*! @@ -2109,6 +2169,73 @@ QByteArray& QByteArray::append(char ch) } /*! + \fn QByteArray &QByteArray::assign(QByteArrayView v) + \since 6.6 + + Replaces the contents of this byte array with a copy of \a v and returns a + reference to this byte array. + + The size of this byte array will be equal to the size of \a v. + + This function only allocates memory if the size of \a v exceeds the capacity + of this byte array or this byte array is shared. +*/ + +/*! + \fn QByteArray &QByteArray::assign(qsizetype n, char c) + \since 6.6 + + Replaces the contents of this byte array with \a n copies of \a c and + returns a reference to this byte array. + + The size of this byte array will be equal to \a n, which has to be non-negative. + + This function will only allocate memory if \a n exceeds the capacity of this + byte array or this byte array is shared. + + \sa fill() +*/ + +/*! + \fn template <typename InputIterator, QByteArray::if_input_iterator<InputIterator>> QByteArray &QByteArray::assign(InputIterator first, InputIterator last) + \since 6.6 + + Replaces the contents of this byte array with a copy of the elements in the + iterator range [\a first, \a last) and returns a reference to this + byte array. + + The size of this byte array will be equal to the number of elements in the + range [\a first, \a last). + + This function will only allocate memory if the number of elements in the + range exceeds the capacity of this byte array or this byte array is shared. + + \note This function overload only participates in overload resolution if + \c InputIterator meets the requirements of a + \l {https://en.cppreference.com/w/cpp/named_req/InputIterator} {LegacyInputIterator}. + + \note The behavior is undefined if either argument is an iterator into *this or + [\a first, \a last) is not a valid range. +*/ + +QByteArray &QByteArray::assign(QByteArrayView v) +{ + const auto len = v.size(); + + if (len <= capacity() && isDetached()) { + const auto offset = d.freeSpaceAtBegin(); + if (offset) + d.setBegin(d.begin() - offset); + std::memcpy(d.begin(), v.data(), len); + d.size = len; + d.data()[d.size] = '\0'; + } else { + *this = v.toByteArray(); + } + return *this; +} + +/*! Inserts \a data at index position \a i and returns a reference to this byte array. @@ -2498,12 +2625,11 @@ QByteArray &QByteArray::replace(QByteArrayView before, QByteArrayView after) QByteArray &QByteArray::replace(char before, char after) { - if (!isEmpty()) { - char *i = data(); - char *e = i + size(); - for (; i != e; ++i) - if (*i == before) - * i = after; + if (before != after) { + if (const auto pos = indexOf(before); pos >= 0) { + const auto detachedData = data(); + std::replace(detachedData + pos, detachedData + size(), before, after); + } } return *this; } @@ -2574,45 +2700,6 @@ QByteArray QByteArray::repeated(qsizetype times) const return result; } -#define REHASH(a) \ - if (ol_minus_1 < sizeof(std::size_t) * CHAR_BIT) \ - hashHaystack -= std::size_t(a) << ol_minus_1; \ - hashHaystack <<= 1 - -static inline qsizetype findCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept -{ - if (from < 0) - from = qMax(from + haystack.size(), qsizetype(0)); - if (from < haystack.size()) { - const char *const b = haystack.data(); - if (const auto n = static_cast<const char *>( - memchr(b + from, needle, static_cast<size_t>(haystack.size() - from)))) { - return n - b; - } - } - return -1; -} - -qsizetype QtPrivate::findByteArray(QByteArrayView haystack, qsizetype from, QByteArrayView needle) noexcept -{ - const auto ol = needle.size(); - const auto l = haystack.size(); - if (ol == 0) { - if (from < 0) - return qMax(from + l, 0); - else - return from > l ? -1 : from; - } - - if (ol == 1) - return findCharHelper(haystack, from, needle.front()); - - if (from > l || ol + from > l) - return -1; - - return qFindByteArray(haystack.data(), haystack.size(), from, needle.data(), ol); -} - /*! \fn qsizetype QByteArray::indexOf(QByteArrayView bv, qsizetype from) const \since 6.0 @@ -2627,6 +2714,7 @@ qsizetype QtPrivate::findByteArray(QByteArrayView haystack, qsizetype from, QByt */ /*! + \fn qsizetype QByteArray::indexOf(char ch, qsizetype from) const \overload Returns the index position of the start of the first occurrence of the @@ -2639,11 +2727,6 @@ qsizetype QtPrivate::findByteArray(QByteArrayView haystack, qsizetype from, QByt \sa lastIndexOf(), contains() */ -qsizetype QByteArray::indexOf(char ch, qsizetype from) const -{ - return qToByteArrayViewIgnoringNull(*this).indexOf(ch, from); -} - static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char *needle, qsizetype ol, qsizetype from) { @@ -2657,10 +2740,10 @@ static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char const char *end = haystack; haystack += from; - const auto ol_minus_1 = std::size_t(ol - 1); + const qregisteruint ol_minus_1 = ol - 1; const char *n = needle + ol_minus_1; const char *h = haystack + ol_minus_1; - std::size_t hashNeedle = 0, hashHaystack = 0; + qregisteruint hashNeedle = 0, hashHaystack = 0; qsizetype idx; for (idx = 0; idx < ol; ++idx) { hashNeedle = ((hashNeedle<<1) + *(n-idx)); @@ -2672,27 +2755,9 @@ static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char if (hashHaystack == hashNeedle && memcmp(needle, haystack, ol) == 0) return haystack - end; --haystack; - REHASH(*(haystack + ol)); - } - return -1; - -} - -static inline qsizetype lastIndexOfCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept -{ - if (haystack.size() == 0) - return -1; - if (from < 0) - from += haystack.size(); - else if (from > haystack.size()) - from = haystack.size() - 1; - if (from >= 0) { - const char *b = haystack.data(); - const char *n = b + from + 1; - while (n-- != b) { - if (*n == needle) - return n - b; - } + if (ol_minus_1 < sizeof(ol_minus_1) * CHAR_BIT) + hashHaystack -= qregisteruint(*(haystack + ol)) << ol_minus_1; + hashHaystack <<= 1; } return -1; } @@ -2706,7 +2771,7 @@ qsizetype QtPrivate::lastIndexOf(QByteArrayView haystack, qsizetype from, QByteA } const auto ol = needle.size(); if (ol == 1) - return lastIndexOfCharHelper(haystack, from, needle.front()); + return QtPrivate::lastIndexOf(haystack, from, needle.front()); return lastIndexOfHelper(haystack.data(), haystack.size(), needle.data(), ol, from); } @@ -2750,6 +2815,7 @@ qsizetype QtPrivate::lastIndexOf(QByteArrayView haystack, qsizetype from, QByteA */ /*! + \fn qsizetype QByteArray::lastIndexOf(char ch, qsizetype from) const \overload Returns the index position of the start of the last occurrence of byte \a ch @@ -2763,11 +2829,6 @@ qsizetype QtPrivate::lastIndexOf(QByteArrayView haystack, qsizetype from, QByteA \sa indexOf(), contains() */ -qsizetype QByteArray::lastIndexOf(char ch, qsizetype from) const -{ - return qToByteArrayViewIgnoringNull(*this).lastIndexOf(ch, from); -} - static inline qsizetype countCharHelper(QByteArrayView haystack, char needle) noexcept { qsizetype num = 0; @@ -2959,6 +3020,9 @@ bool QByteArray::isLower() const */ /*! + \fn QByteArray QByteArray::left(qsizetype len) const & + \fn QByteArray QByteArray::left(qsizetype len) && + Returns a byte array that contains the first \a len bytes of this byte array. @@ -2973,16 +3037,10 @@ bool QByteArray::isLower() const \sa first(), last(), startsWith(), chopped(), chop(), truncate() */ -QByteArray QByteArray::left(qsizetype len) const -{ - if (len >= size()) - return *this; - if (len < 0) - len = 0; - return QByteArray(data(), len); -} - /*! + \fn QByteArray QByteArray::right(qsizetype len) const & + \fn QByteArray QByteArray::right(qsizetype len) && + Returns a byte array that contains the last \a len bytes of this byte array. If you know that \a len cannot be out of bounds, use last() instead in new @@ -2993,18 +3051,13 @@ QByteArray QByteArray::left(qsizetype len) const Returns an empty QByteArray if \a len is smaller than 0. - \sa endsWith(), last(), first(), sliced(), chopped(), chop(), truncate() + \sa endsWith(), last(), first(), sliced(), chopped(), chop(), truncate(), slice() */ -QByteArray QByteArray::right(qsizetype len) const -{ - if (len >= size()) - return *this; - if (len < 0) - len = 0; - return QByteArray(end() - len, len); -} /*! + \fn QByteArray QByteArray::mid(qsizetype pos, qsizetype len) const & + \fn QByteArray QByteArray::mid(qsizetype pos, qsizetype len) && + Returns a byte array containing \a len bytes from this byte array, starting at position \a pos. @@ -3015,10 +3068,10 @@ QByteArray QByteArray::right(qsizetype len) const returns a byte array containing all bytes starting at position \a pos until the end of the byte array. - \sa first(), last(), sliced(), chopped(), chop(), truncate() + \sa first(), last(), sliced(), chopped(), chop(), truncate(), slice() */ -QByteArray QByteArray::mid(qsizetype pos, qsizetype len) const +QByteArray QByteArray::mid(qsizetype pos, qsizetype len) const & { qsizetype p = pos; qsizetype l = len; @@ -3033,13 +3086,33 @@ QByteArray QByteArray::mid(qsizetype pos, qsizetype len) const case QContainerImplHelper::Full: return *this; case QContainerImplHelper::Subset: - return QByteArray(d.data() + p, l); + return sliced(p, l); + } + Q_UNREACHABLE_RETURN(QByteArray()); +} + +QByteArray QByteArray::mid(qsizetype pos, qsizetype len) && +{ + qsizetype p = pos; + qsizetype l = len; + using namespace QtPrivate; + switch (QContainerImplHelper::mid(size(), &p, &l)) { + case QContainerImplHelper::Null: + return QByteArray(); + case QContainerImplHelper::Empty: + resize(0); // keep capacity if we've reserve()d + [[fallthrough]]; + case QContainerImplHelper::Full: + return std::move(*this); + case QContainerImplHelper::Subset: + return std::move(*this).sliced(p, l); } Q_UNREACHABLE_RETURN(QByteArray()); } /*! - \fn QByteArray QByteArray::first(qsizetype n) const + \fn QByteArray QByteArray::first(qsizetype n) const & + \fn QByteArray QByteArray::first(qsizetype n) && \since 6.0 Returns the first \a n bytes of the byte array. @@ -3049,11 +3122,12 @@ QByteArray QByteArray::mid(qsizetype pos, qsizetype len) const Example: \snippet code/src_corelib_text_qbytearray.cpp 27 - \sa last(), sliced(), startsWith(), chopped(), chop(), truncate() + \sa last(), sliced(), startsWith(), chopped(), chop(), truncate(), slice() */ /*! - \fn QByteArray QByteArray::last(qsizetype n) const + \fn QByteArray QByteArray::last(qsizetype n) const & + \fn QByteArray QByteArray::last(qsizetype n) && \since 6.0 Returns the last \a n bytes of the byte array. @@ -3063,11 +3137,12 @@ QByteArray QByteArray::mid(qsizetype pos, qsizetype len) const Example: \snippet code/src_corelib_text_qbytearray.cpp 28 - \sa first(), sliced(), endsWith(), chopped(), chop(), truncate() + \sa first(), sliced(), endsWith(), chopped(), chop(), truncate(), slice() */ /*! - \fn QByteArray QByteArray::sliced(qsizetype pos, qsizetype n) const + \fn QByteArray QByteArray::sliced(qsizetype pos, qsizetype n) const & + \fn QByteArray QByteArray::sliced(qsizetype pos, qsizetype n) && \since 6.0 Returns a byte array containing the \a n bytes of this object starting @@ -3079,11 +3154,20 @@ QByteArray QByteArray::mid(qsizetype pos, qsizetype len) const Example: \snippet code/src_corelib_text_qbytearray.cpp 29 - \sa first(), last(), chopped(), chop(), truncate() + \sa first(), last(), chopped(), chop(), truncate(), slice() */ +QByteArray QByteArray::sliced_helper(QByteArray &a, qsizetype pos, qsizetype n) +{ + if (n == 0) + return fromRawData(&_empty, 0); + DataPointer d = std::move(a.d).sliced(pos, n); + d.data()[n] = 0; + return QByteArray(std::move(d)); +} /*! - \fn QByteArray QByteArray::sliced(qsizetype pos) const + \fn QByteArray QByteArray::sliced(qsizetype pos) const & + \fn QByteArray QByteArray::sliced(qsizetype pos) && \since 6.0 \overload @@ -3092,11 +3176,41 @@ QByteArray QByteArray::mid(qsizetype pos, qsizetype len) const \note The behavior is undefined when \a pos < 0 or \a pos > size(). - \sa first(), last(), sliced(), chopped(), chop(), truncate() + \sa first(), last(), chopped(), chop(), truncate(), slice() +*/ + +/*! + \fn QByteArray &QByteArray::slice(qsizetype pos, qsizetype n) + \since 6.8 + + Modifies this byte array to start at position \a pos, extending for \a n + bytes, and returns a reference to this byte array. + + \note The behavior is undefined if \a pos < 0, \a n < 0, + or \a pos + \a n > size(). + + Example: + \snippet code/src_corelib_text_qbytearray.cpp 57 + + \sa sliced(), first(), last(), chopped(), chop(), truncate() */ /*! - \fn QByteArray QByteArray::chopped(qsizetype len) const + \fn QByteArray &QByteArray::slice(qsizetype pos) + \since 6.8 + \overload + + Modifies this byte array to start at position \a pos, extending to its + end, and returns a reference to this byte array. + + \note The behavior is undefined if \a pos < 0 or \a pos > size(). + + \sa sliced(), first(), last(), chopped(), chop(), truncate() +*/ + +/*! + \fn QByteArray QByteArray::chopped(qsizetype len) const & + \fn QByteArray QByteArray::chopped(qsizetype len) && \since 5.10 Returns a byte array that contains the leftmost size() - \a len bytes of @@ -3104,7 +3218,7 @@ QByteArray QByteArray::mid(qsizetype pos, qsizetype len) const \note The behavior is undefined if \a len is negative or greater than size(). - \sa endsWith(), first(), last(), sliced(), chop(), truncate() + \sa endsWith(), first(), last(), sliced(), chop(), truncate(), slice() */ /*! @@ -3190,7 +3304,7 @@ void QByteArray::clear() d.clear(); } -#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED) +#if !defined(QT_NO_DATASTREAM) /*! \relates QByteArray @@ -3203,7 +3317,7 @@ void QByteArray::clear() QDataStream &operator<<(QDataStream &out, const QByteArray &ba) { if (ba.isNull() && out.version() >= 6) { - out << (quint32)0xffffffff; + QDataStream::writeQSizeType(out, -1); return out; } return out.writeBytes(ba.constData(), ba.size()); @@ -3220,13 +3334,21 @@ QDataStream &operator<<(QDataStream &out, const QByteArray &ba) QDataStream &operator>>(QDataStream &in, QByteArray &ba) { ba.clear(); - quint32 len; - in >> len; - if (len == 0xffffffff) + + qint64 size = QDataStream::readQSizeType(in); + qsizetype len = size; + if (size != len || size < -1) { + ba.clear(); + in.setStatus(QDataStream::SizeLimitExceeded); + return in; + } + if (len == -1) { // null byte-array + ba = QByteArray(); return in; + } - const quint32 Step = 1024 * 1024; - quint32 allocated = 0; + constexpr qsizetype Step = 1024 * 1024; + qsizetype allocated = 0; do { qsizetype blockSize = qMin(Step, len - allocated); @@ -3243,248 +3365,164 @@ QDataStream &operator>>(QDataStream &in, QByteArray &ba) } #endif // QT_NO_DATASTREAM -/*! \fn bool QByteArray::operator==(const QString &str) const - - Returns \c true if this byte array is equal to the UTF-8 encoding of \a str; - otherwise returns \c false. - - The comparison is case sensitive. - - You can disable this operator by defining \c - QT_NO_CAST_FROM_ASCII when you compile your applications. You - then need to call QString::fromUtf8(), QString::fromLatin1(), - or QString::fromLocal8Bit() explicitly if you want to convert the byte - array to a QString before doing the comparison. -*/ - -/*! \fn bool QByteArray::operator!=(const QString &str) const - - Returns \c true if this byte array is not equal to the UTF-8 encoding of \a - str; otherwise returns \c false. - - The comparison is case sensitive. - - You can disable this operator by defining \c - QT_NO_CAST_FROM_ASCII when you compile your applications. You - then need to call QString::fromUtf8(), QString::fromLatin1(), - or QString::fromLocal8Bit() explicitly if you want to convert the byte - array to a QString before doing the comparison. -*/ - -/*! \fn bool QByteArray::operator<(const QString &str) const - - Returns \c true if this byte array is lexically less than the UTF-8 encoding - of \a str; otherwise returns \c false. - - The comparison is case sensitive. - - You can disable this operator by defining \c - QT_NO_CAST_FROM_ASCII when you compile your applications. You - then need to call QString::fromUtf8(), QString::fromLatin1(), - or QString::fromLocal8Bit() explicitly if you want to convert the byte - array to a QString before doing the comparison. -*/ - -/*! \fn bool QByteArray::operator>(const QString &str) const - - Returns \c true if this byte array is lexically greater than the UTF-8 - encoding of \a str; otherwise returns \c false. - - The comparison is case sensitive. - - You can disable this operator by defining \c - QT_NO_CAST_FROM_ASCII when you compile your applications. You - then need to call QString::fromUtf8(), QString::fromLatin1(), - or QString::fromLocal8Bit() explicitly if you want to convert the byte - array to a QString before doing the comparison. -*/ - -/*! \fn bool QByteArray::operator<=(const QString &str) const - - Returns \c true if this byte array is lexically less than or equal to the - UTF-8 encoding of \a str; otherwise returns \c false. - - The comparison is case sensitive. - - You can disable this operator by defining \c - QT_NO_CAST_FROM_ASCII when you compile your applications. You - then need to call QString::fromUtf8(), QString::fromLatin1(), - or QString::fromLocal8Bit() explicitly if you want to convert the byte - array to a QString before doing the comparison. -*/ - -/*! \fn bool QByteArray::operator>=(const QString &str) const - - Returns \c true if this byte array is greater than or equal to the UTF-8 - encoding of \a str; otherwise returns \c false. - - The comparison is case sensitive. - - You can disable this operator by defining \c - QT_NO_CAST_FROM_ASCII when you compile your applications. You - then need to call QString::fromUtf8(), QString::fromLatin1(), - or QString::fromLocal8Bit() explicitly if you want to convert the byte - array to a QString before doing the comparison. -*/ - -/*! \fn bool QByteArray::operator==(const QByteArray &a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator==(const QByteArray &lhs, const QByteArray &rhs) \overload - Returns \c true if byte array \a a1 is equal to byte array \a a2; + Returns \c true if byte array \a lhs is equal to byte array \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator==(const QByteArray &a1, const char *a2) +/*! \fn bool QByteArray::operator==(const QByteArray &lhs, const char * const &rhs) \overload - Returns \c true if byte array \a a1 is equal to the '\\0'-terminated string - \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is equal to the '\\0'-terminated string + \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator==(const char *a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator==(const char * const &lhs, const QByteArray &rhs) \overload - Returns \c true if '\\0'-terminated string \a a1 is equal to byte array \a - a2; otherwise returns \c false. + Returns \c true if '\\0'-terminated string \a lhs is equal to byte array \a + rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator!=(const QByteArray &a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator!=(const QByteArray &lhs, const QByteArray &rhs) \overload - Returns \c true if byte array \a a1 is not equal to byte array \a a2; + Returns \c true if byte array \a lhs is not equal to byte array \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator!=(const QByteArray &a1, const char *a2) +/*! \fn bool QByteArray::operator!=(const QByteArray &lhs, const char * const &rhs) \overload - Returns \c true if byte array \a a1 is not equal to the '\\0'-terminated - string \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is not equal to the '\\0'-terminated + string \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator!=(const char *a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator!=(const char * const &lhs, const QByteArray &rhs) \overload - Returns \c true if '\\0'-terminated string \a a1 is not equal to byte array - \a a2; otherwise returns \c false. + Returns \c true if '\\0'-terminated string \a lhs is not equal to byte array + \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator<(const QByteArray &a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator<(const QByteArray &lhs, const QByteArray &rhs) \overload - Returns \c true if byte array \a a1 is lexically less than byte array - \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is lexically less than byte array + \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator<(const QByteArray &a1, const char *a2) +/*! \fn bool QByteArray::operator<(const QByteArray &lhs, const char * const &rhs) \overload - Returns \c true if byte array \a a1 is lexically less than the - '\\0'-terminated string \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is lexically less than the + '\\0'-terminated string \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator<(const char *a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator<(const char * const &lhs, const QByteArray &rhs) \overload - Returns \c true if '\\0'-terminated string \a a1 is lexically less than byte - array \a a2; otherwise returns \c false. + Returns \c true if '\\0'-terminated string \a lhs is lexically less than byte + array \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator<=(const QByteArray &a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator<=(const QByteArray &lhs, const QByteArray &rhs) \overload - Returns \c true if byte array \a a1 is lexically less than or equal - to byte array \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is lexically less than or equal + to byte array \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator<=(const QByteArray &a1, const char *a2) +/*! \fn bool QByteArray::operator<=(const QByteArray &lhs, const char * const &rhs) \overload - Returns \c true if byte array \a a1 is lexically less than or equal to the - '\\0'-terminated string \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is lexically less than or equal to the + '\\0'-terminated string \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator<=(const char *a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator<=(const char * const &lhs, const QByteArray &rhs) \overload - Returns \c true if '\\0'-terminated string \a a1 is lexically less than or - equal to byte array \a a2; otherwise returns \c false. + Returns \c true if '\\0'-terminated string \a lhs is lexically less than or + equal to byte array \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator>(const QByteArray &a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator>(const QByteArray &lhs, const QByteArray &rhs) \overload - Returns \c true if byte array \a a1 is lexically greater than byte - array \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is lexically greater than byte + array \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator>(const QByteArray &a1, const char *a2) +/*! \fn bool QByteArray::operator>(const QByteArray &lhs, const char * const &rhs) \overload - Returns \c true if byte array \a a1 is lexically greater than the - '\\0'-terminated string \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is lexically greater than the + '\\0'-terminated string \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator>(const char *a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator>(const char * const &lhs, const QByteArray &rhs) \overload - Returns \c true if '\\0'-terminated string \a a1 is lexically greater than - byte array \a a2; otherwise returns \c false. + Returns \c true if '\\0'-terminated string \a lhs is lexically greater than + byte array \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator>=(const QByteArray &a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator>=(const QByteArray &lhs, const QByteArray &rhs) \overload - Returns \c true if byte array \a a1 is lexically greater than or - equal to byte array \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is lexically greater than or + equal to byte array \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator>=(const QByteArray &a1, const char *a2) +/*! \fn bool QByteArray::operator>=(const QByteArray &lhs, const char * const &rhs) \overload - Returns \c true if byte array \a a1 is lexically greater than or equal to - the '\\0'-terminated string \a a2; otherwise returns \c false. + Returns \c true if byte array \a lhs is lexically greater than or equal to + the '\\0'-terminated string \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ -/*! \fn bool QByteArray::operator>=(const char *a1, const QByteArray &a2) +/*! \fn bool QByteArray::operator>=(const char * const &lhs, const QByteArray &rhs) \overload - Returns \c true if '\\0'-terminated string \a a1 is lexically greater than - or equal to byte array \a a2; otherwise returns \c false. + Returns \c true if '\\0'-terminated string \a lhs is lexically greater than + or equal to byte array \a rhs; otherwise returns \c false. \sa QByteArray::compare() */ @@ -3592,9 +3630,7 @@ QByteArray QByteArray::trimmed_helper(QByteArray &a) QByteArrayView QtPrivate::trimmed(QByteArrayView view) noexcept { - auto start = view.begin(); - auto stop = view.end(); - QStringAlgorithms<QByteArrayView>::trimmed_helper_positions(start, stop); + const auto [start, stop] = QStringAlgorithms<QByteArrayView>::trimmed_helper_positions(view); return QByteArrayView(start, stop); } @@ -3683,10 +3719,9 @@ auto QtPrivate::toSignedInteger(QByteArrayView data, int base) -> ParsedNumber<q if (data.isEmpty()) return {}; - bool ok = false; - const auto i = QLocaleData::bytearrayToLongLong(data, base, &ok); - if (ok) - return ParsedNumber(i); + const QSimpleParsedNumber r = QLocaleData::bytearrayToLongLong(data, base); + if (r.ok()) + return ParsedNumber(r.result); return {}; } @@ -3701,10 +3736,9 @@ auto QtPrivate::toUnsignedInteger(QByteArrayView data, int base) -> ParsedNumber if (data.isEmpty()) return {}; - bool ok = false; - const auto u = QLocaleData::bytearrayToUnsLongLong(data, base, &ok); - if (ok) - return ParsedNumber(u); + const QSimpleParsedNumber r = QLocaleData::bytearrayToUnsLongLong(data, base); + if (r.ok()) + return ParsedNumber(r.result); return {}; } @@ -4047,12 +4081,12 @@ auto QtPrivate::toFloat(QByteArrayView a) noexcept -> ParsedNumber<float> */ QByteArray QByteArray::toBase64(Base64Options options) const { - const char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef" - "ghijklmn" "opqrstuv" "wxyz0123" "456789+/"; - const char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef" - "ghijklmn" "opqrstuv" "wxyz0123" "456789-_"; + constexpr char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef" + "ghijklmn" "opqrstuv" "wxyz0123" "456789+/"; + constexpr char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef" + "ghijklmn" "opqrstuv" "wxyz0123" "456789-_"; const char *const alphabet = options & Base64UrlEncoding ? alphabet_base64url : alphabet_base64; - const char padchar = '='; + constexpr char padchar = '='; qsizetype padlen = 0; const qsizetype sz = size(); @@ -4156,24 +4190,6 @@ QByteArray QByteArray::toBase64(Base64Options options) const \sa toUShort() */ -static char *qulltoa2(char *p, qulonglong n, int base) -{ -#if defined(QT_CHECK_RANGE) - if (base < 2 || base > 36) { - qWarning("QByteArray::setNum: Invalid base %d", base); - base = 10; - } -#endif - const char b = 'a' - 10; - do { - const int c = n % base; - n /= base; - *--p = c + (c < 10 ? '0' : b); - } while (n); - - return p; -} - /*! \overload @@ -4181,7 +4197,7 @@ static char *qulltoa2(char *p, qulonglong n, int base) */ QByteArray &QByteArray::setNum(qlonglong n, int base) { - const int buffsize = 66; // big enough for MAX_ULLONG in base 2 + constexpr int buffsize = 66; // big enough for MAX_ULLONG in base 2 char buff[buffsize]; char *p; @@ -4193,9 +4209,7 @@ QByteArray &QByteArray::setNum(qlonglong n, int base) p = qulltoa2(buff + buffsize, qulonglong(n), base); } - clear(); - append(p, buffsize - (p - buff)); - return *this; + return assign(QByteArrayView{p, buff + buffsize}); } /*! @@ -4206,13 +4220,11 @@ QByteArray &QByteArray::setNum(qlonglong n, int base) QByteArray &QByteArray::setNum(qulonglong n, int base) { - const int buffsize = 66; // big enough for MAX_ULLONG in base 2 + constexpr int buffsize = 66; // big enough for MAX_ULLONG in base 2 char buff[buffsize]; char *p = qulltoa2(buff + buffsize, n, base); - clear(); - append(p, buffsize - (p - buff)); - return *this; + return assign(QByteArrayView{p, buff + buffsize}); } /*! @@ -5144,6 +5156,3 @@ size_t qHash(const QByteArray::FromBase64Result &key, size_t seed) noexcept */ QT_END_NAMESPACE - -#undef IS_RAW_DATA -#undef REHASH |