diff options
Diffstat (limited to 'src/corelib/text/qbytearray.h')
-rw-r--r-- | src/corelib/text/qbytearray.h | 240 |
1 files changed, 66 insertions, 174 deletions
diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h index 36cf580cd9..e3fec1e62c 100644 --- a/src/corelib/text/qbytearray.h +++ b/src/corelib/text/qbytearray.h @@ -44,6 +44,8 @@ #include <QtCore/qrefcount.h> #include <QtCore/qnamespace.h> #include <QtCore/qarraydata.h> +#include <QtCore/qarraydatapointer.h> +#include <QtCore/qcontainerfwd.h> #include <stdlib.h> #include <string.h> @@ -106,48 +108,23 @@ Q_CORE_EXPORT int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap); Q_CORE_EXPORT int qsnprintf(char *str, size_t n, const char *fmt, ...); // qChecksum: Internet checksum -Q_CORE_EXPORT quint16 qChecksum(const char *s, uint len); // ### Qt 6: Remove -Q_CORE_EXPORT quint16 qChecksum(const char *s, uint len, Qt::ChecksumType standard); // ### Qt 6: Use Qt::ChecksumType standard = Qt::ChecksumIso3309 +Q_CORE_EXPORT quint16 qChecksum(const char *s, uint len, + Qt::ChecksumType standard = Qt::ChecksumIso3309); -class QByteRef; class QString; class QDataStream; -template <typename T> class QList; -typedef QArrayData QByteArrayData; - -template<int N> struct QStaticByteArrayData -{ - QByteArrayData ba; - char data[N + 1]; - - QByteArrayData *data_ptr() const - { - Q_ASSERT(ba.ref.isStatic()); - return const_cast<QByteArrayData *>(&ba); - } -}; - -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)) \ - /**/ +using QByteArrayData = QArrayDataPointer<char>; # 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, 0 }; \ + QByteArrayData holder = { \ + static_cast<QTypedArrayData<char> *>(const_cast<QArrayData *>(&qbytearray_literal)), \ + const_cast<char *>(str), \ + Size }; \ const QByteArray ba(holder); \ return ba; \ }()) \ @@ -155,10 +132,14 @@ struct QByteArrayDataPtr class Q_CORE_EXPORT QByteArray { +public: + using DataPointer = QByteArrayData; private: typedef QTypedArrayData<char> Data; + DataPointer d; public: + enum Base64Option { Base64Encoding = 0, Base64UrlEncoding = 1, @@ -187,14 +168,13 @@ 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 + { qSwap(d, other.d); } inline QByteArray &operator=(QByteArray &&other) noexcept { qSwap(d, other.d); return *this; } - inline void swap(QByteArray &other) noexcept { qSwap(d, other.d); } - inline int size() const; inline bool isEmpty() const; void resize(int size); @@ -213,18 +193,17 @@ 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; inline char operator[](int i) const; - inline char operator[](uint i) const; - Q_REQUIRED_RESULT inline QByteRef operator[](int i); - Q_REQUIRED_RESULT inline QByteRef operator[](uint i); + Q_REQUIRED_RESULT inline char &operator[](int i); Q_REQUIRED_RESULT char front() const { return at(0); } - Q_REQUIRED_RESULT inline QByteRef front(); + Q_REQUIRED_RESULT inline char &front(); Q_REQUIRED_RESULT char back() const { return at(size() - 1); } - Q_REQUIRED_RESULT inline QByteRef back(); + Q_REQUIRED_RESULT inline char &back(); int indexOf(char c, int from = 0) const; int indexOf(const char *c, int from = 0) const; @@ -365,10 +344,8 @@ public: qulonglong toULongLong(bool *ok = nullptr, int base = 10) const; float toFloat(bool *ok = nullptr) const; double toDouble(bool *ok = nullptr) const; - QByteArray toBase64(Base64Options options) const; - QByteArray toBase64() const; // ### Qt6 merge with previous - QByteArray toHex() const; - QByteArray toHex(char separator) const; // ### Qt6 merge with previous + QByteArray toBase64(Base64Options options = Base64Encoding) const; + QByteArray toHex(char separator = '\0') const; QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(), const QByteArray &include = QByteArray(), char percent = '%') const; @@ -393,8 +370,7 @@ public: class FromBase64Result; Q_REQUIRED_RESULT static FromBase64Result fromBase64Encoding(QByteArray &&base64, Base64Options options = Base64Encoding); Q_REQUIRED_RESULT static FromBase64Result fromBase64Encoding(const QByteArray &base64, Base64Options options = Base64Encoding); - Q_REQUIRED_RESULT static QByteArray fromBase64(const QByteArray &base64, Base64Options options); - Q_REQUIRED_RESULT static QByteArray fromBase64(const QByteArray &base64); // ### Qt6 merge with previous + Q_REQUIRED_RESULT static QByteArray fromBase64(const QByteArray &base64, Base64Options options = Base64Encoding); Q_REQUIRED_RESULT static QByteArray fromHex(const QByteArray &hexEncoded); Q_REQUIRED_RESULT static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%'); @@ -449,19 +425,20 @@ 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 size() const { return d->size; } + inline int count() const { return size(); } + inline int length() const { return size(); } bool isNull() const; - inline QByteArray(QByteArrayDataPtr dd) - : d(static_cast<Data *>(dd.ptr)) + inline DataPointer &data_ptr() { return d; } + explicit inline QByteArray(const DataPointer &dd) + : d(dd) { } private: operator QNoImplicitBoolCast() const; - Data *d; - void reallocData(uint alloc, Data::AllocationOptions options); + void reallocData(uint alloc, Data::ArrayOptions options); void expand(int i); QByteArray nulTerminated() const; @@ -474,171 +451,86 @@ private: static QByteArray simplified_helper(const QByteArray &a); static QByteArray simplified_helper(QByteArray &a); - friend class QByteRef; friend class QString; friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, int nbytes); -public: - typedef Data * 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->ref.deref()) Data::deallocate(d); } -inline int QByteArray::size() const -{ return d->size; } +inline QByteArray::QByteArray() noexcept {} +inline QByteArray::~QByteArray() {} 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.data()[i]; } inline char QByteArray::operator[](int i) const -{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; } -inline char QByteArray::operator[](uint i) const -{ Q_ASSERT(i < uint(size())); return d->data()[i]; } +{ Q_ASSERT(uint(i) < uint(size())); return d.data()[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.data(); } inline const char *QByteArray::data() const -{ return d->data(); } +{ return d.data(); } inline const char *QByteArray::constData() const -{ return d->data(); } +{ return d.data(); } inline void QByteArray::detach() -{ if (d->ref.isShared() || (d->offset != sizeof(QByteArrayData))) reallocData(uint(d->size) + 1u, d->detachFlags()); } +{ if (d->needsDetach()) reallocData(uint(size()) + 1u, d->detachFlags()); } inline bool QByteArray::isDetached() const -{ return !d->ref.isShared(); } +{ return !d->isShared(); } inline QByteArray::QByteArray(const QByteArray &a) noexcept : d(a.d) -{ d->ref.ref(); } +{} inline int QByteArray::capacity() const -{ return d->alloc ? d->alloc - 1 : 0; } +{ const auto realCapacity = d->constAllocatedCapacity(); return realCapacity ? int(realCapacity) - 1 : 0; } inline void QByteArray::reserve(int asize) { - if (d->ref.isShared() || uint(asize) + 1u > d->alloc) { + if (d->needsDetach() || asize > capacity()) { reallocData(qMax(uint(size()), uint(asize)) + 1u, d->detachFlags() | Data::CapacityReserved); } else { - // cannot set unconditionally, since d could be the shared_null or - // otherwise static - d->capacityReserved = true; + d->flags() |= Data::CapacityReserved; } } inline void QByteArray::squeeze() { - if (d->ref.isShared() || uint(d->size) + 1u < d->alloc) { - reallocData(uint(d->size) + 1u, d->detachFlags() & ~Data::CapacityReserved); + if ((d->flags() & Data::CapacityReserved) == 0) + return; + if (d->needsDetach() || size() < capacity()) { + reallocData(uint(size()) + 1u, d->detachFlags() & ~Data::CapacityReserved); } else { - // cannot set unconditionally, since d could be shared_null or - // otherwise static. - d->capacityReserved = false; + d->flags() &= uint(~Data::CapacityReserved); } } -namespace QtPrivate { -namespace DeprecatedRefClassBehavior { - enum class EmittingClass { - QByteRef, - QCharRef, - }; - - enum class WarningType { - OutOfRange, - DelayedDetach, - }; - - Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void warn(WarningType w, EmittingClass c); -} // namespace DeprecatedAssignmentOperatorBehavior -} // namespace QtPrivate - -class -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -Q_CORE_EXPORT -#endif -QByteRef { // ### Qt 7: remove - QByteArray &a; - int i; - inline QByteRef(QByteArray &array, int idx) - : a(array),i(idx) {} - friend class QByteArray; -public: - inline operator char() const - { - using namespace QtPrivate::DeprecatedRefClassBehavior; - if (Q_LIKELY(i < a.d->size)) - return a.d->data()[i]; -#ifdef QT_DEBUG - warn(WarningType::OutOfRange, EmittingClass::QByteRef); -#endif - return char(0); - } - inline QByteRef &operator=(char c) - { - using namespace QtPrivate::DeprecatedRefClassBehavior; - if (Q_UNLIKELY(i >= a.d->size)) { -#ifdef QT_DEBUG - warn(WarningType::OutOfRange, EmittingClass::QByteRef); -#endif - a.expand(i); - } else { -#ifdef QT_DEBUG - if (Q_UNLIKELY(!a.isDetached())) - warn(WarningType::DelayedDetach, EmittingClass::QByteRef); -#endif - a.detach(); - } - a.d->data()[i] = c; - return *this; - } - inline QByteRef &operator=(const QByteRef &c) - { - return operator=(char(c)); - } - inline bool operator==(char c) const - { return a.d->data()[i] == c; } - inline bool operator!=(char c) const - { return a.d->data()[i] != c; } - inline bool operator>(char c) const - { return a.d->data()[i] > c; } - inline bool operator>=(char c) const - { return a.d->data()[i] >= c; } - inline bool operator<(char c) const - { return a.d->data()[i] < c; } - inline bool operator<=(char c) const - { return a.d->data()[i] <= c; } -}; - -inline QByteRef QByteArray::operator[](int i) -{ Q_ASSERT(i >= 0); detach(); return QByteRef(*this, i); } -inline QByteRef QByteArray::operator[](uint i) -{ detach(); return QByteRef(*this, i); } -inline QByteRef QByteArray::front() { return operator[](0); } -inline QByteRef QByteArray::back() { return operator[](size() - 1); } +inline char &QByteArray::operator[](int i) +{ Q_ASSERT(i >= 0 && i < size()); return data()[i]; } +inline char &QByteArray::front() { return operator[](0); } +inline char &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) |