Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-11 09:33:31

0001 // Copyright (C) 2022 The Qt Company Ltd.
0002 // Copyright (C) 2016 Intel Corporation.
0003 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0004 // Qt-Security score:critical reason:data-parser
0005 
0006 #ifndef QBYTEARRAY_H
0007 #define QBYTEARRAY_H
0008 
0009 #include <QtCore/qrefcount.h>
0010 #include <QtCore/qnamespace.h>
0011 #include <QtCore/qarraydata.h>
0012 #include <QtCore/qarraydatapointer.h>
0013 #include <QtCore/qcompare.h>
0014 #include <QtCore/qcontainerfwd.h>
0015 #include <QtCore/qbytearrayalgorithms.h>
0016 #include <QtCore/qbytearrayview.h>
0017 
0018 #include <stdlib.h>
0019 #include <string.h>
0020 
0021 #include <string>
0022 #include <iterator>
0023 
0024 #ifndef QT5_NULL_STRINGS
0025 // Would ideally be off, but in practice breaks too much (Qt 6.0).
0026 #define QT5_NULL_STRINGS 1
0027 #endif
0028 
0029 #ifdef truncate
0030 #error qbytearray.h must be included before any header file that defines truncate
0031 #endif
0032 
0033 #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
0034 Q_FORWARD_DECLARE_CF_TYPE(CFData);
0035 Q_FORWARD_DECLARE_OBJC_CLASS(NSData);
0036 #endif
0037 
0038 #if defined(Q_OS_WASM) || defined(Q_QDOC)
0039 namespace emscripten {
0040     class val;
0041 }
0042 #endif
0043 
0044 class tst_QByteArray;
0045 
0046 QT_BEGIN_NAMESPACE
0047 
0048 class QString;
0049 class QDataStream;
0050 
0051 using QByteArrayData = QArrayDataPointer<char>;
0052 
0053 #  define QByteArrayLiteral(str) \
0054     (QByteArray(QByteArrayData(nullptr, const_cast<char *>(str), sizeof(str) - 1))) \
0055     /**/
0056 
0057 class Q_CORE_EXPORT QByteArray
0058 {
0059 public:
0060     using DataPointer = QByteArrayData;
0061 private:
0062     typedef QTypedArrayData<char> Data;
0063 
0064     DataPointer d;
0065     static const char _empty;
0066 
0067     friend class ::tst_QByteArray;
0068 
0069     template <typename InputIterator>
0070     using if_input_iterator = QtPrivate::IfIsInputIterator<InputIterator>;
0071 public:
0072     enum Base64Option {
0073         Base64Encoding = 0,
0074         Base64UrlEncoding = 1,
0075 
0076         KeepTrailingEquals = 0,
0077         OmitTrailingEquals = 2,
0078 
0079         IgnoreBase64DecodingErrors = 0,
0080         AbortOnBase64DecodingErrors = 4,
0081     };
0082     Q_DECLARE_FLAGS(Base64Options, Base64Option)
0083 
0084     enum class Base64DecodingStatus {
0085         Ok,
0086         IllegalInputLength,
0087         IllegalCharacter,
0088         IllegalPadding,
0089     };
0090 
0091     inline constexpr QByteArray() noexcept;
0092     QByteArray(const char *, qsizetype size = -1);
0093     QByteArray(qsizetype size, char c);
0094     QByteArray(qsizetype size, Qt::Initialization);
0095     explicit QByteArray(QByteArrayView v) : QByteArray(v.data(), v.size()) {}
0096     inline QByteArray(const QByteArray &) noexcept;
0097     inline ~QByteArray();
0098 
0099     QByteArray &operator=(const QByteArray &) noexcept;
0100     QByteArray &operator=(const char *str);
0101     inline QByteArray(QByteArray && other) noexcept
0102         = default;
0103     QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QByteArray)
0104     inline void swap(QByteArray &other) noexcept
0105     { d.swap(other.d); }
0106 
0107     constexpr bool isEmpty() const noexcept { return size() == 0; }
0108     void resize(qsizetype size);
0109     void resize(qsizetype size, char c);
0110     void resizeForOverwrite(qsizetype size);
0111 
0112     QByteArray &fill(char c, qsizetype size = -1);
0113 
0114     inline qsizetype capacity() const;
0115     inline void reserve(qsizetype size);
0116     inline void squeeze();
0117 
0118 #ifndef QT_NO_CAST_FROM_BYTEARRAY
0119     inline operator const char *() const;
0120     inline operator const void *() const;
0121 #endif
0122 
0123     // Some compilers consider this conversion ambiguous, so
0124     // we're not offering it there:
0125     // * QCC 8.3 on QNX
0126     // * GHS 2022.1.4 on INTEGRITY
0127 #if (!defined(Q_OS_QNX) || !defined(Q_CC_GNU_ONLY) || Q_CC_GNU_ONLY > 803) && \
0128     (!defined(Q_CC_GHS) || !defined(__GHS_VERSION_NUMBER) || __GHS_VERSION_NUMBER > 202214)
0129 # define QT_BYTEARRAY_CONVERTS_TO_STD_STRING_VIEW
0130     Q_IMPLICIT operator std::string_view() const noexcept
0131     { return std::string_view(data(), std::size_t(size())); }
0132 #endif
0133 
0134     inline char *data();
0135     inline const char *data() const noexcept;
0136     const char *constData() const noexcept { return data(); }
0137     inline void detach();
0138     inline bool isDetached() const;
0139     inline bool isSharedWith(const QByteArray &other) const noexcept
0140     { return data() == other.data() && size() == other.size(); }
0141     void clear();
0142 
0143     inline char at(qsizetype i) const;
0144     inline char operator[](qsizetype i) const;
0145     [[nodiscard]] inline char &operator[](qsizetype i);
0146     [[nodiscard]] char front() const { return at(0); }
0147     [[nodiscard]] inline char &front();
0148     [[nodiscard]] char back() const { return at(size() - 1); }
0149     [[nodiscard]] inline char &back();
0150 
0151     QT_CORE_INLINE_SINCE(6, 8)
0152     qsizetype indexOf(char c, qsizetype from = 0) const;
0153     qsizetype indexOf(QByteArrayView bv, qsizetype from = 0) const
0154     { return QtPrivate::findByteArray(qToByteArrayViewIgnoringNull(*this), from, bv); }
0155 
0156     QT_CORE_INLINE_SINCE(6, 8)
0157     qsizetype lastIndexOf(char c, qsizetype from = -1) const;
0158     qsizetype lastIndexOf(QByteArrayView bv) const
0159     { return lastIndexOf(bv, size()); }
0160     qsizetype lastIndexOf(QByteArrayView bv, qsizetype from) const
0161     { return QtPrivate::lastIndexOf(qToByteArrayViewIgnoringNull(*this), from, bv); }
0162 
0163     inline bool contains(char c) const;
0164     inline bool contains(QByteArrayView bv) const;
0165     qsizetype count(char c) const;
0166     qsizetype count(QByteArrayView bv) const
0167     { return QtPrivate::count(qToByteArrayViewIgnoringNull(*this), bv); }
0168 
0169     inline int compare(QByteArrayView a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
0170 
0171 #if QT_CORE_REMOVED_SINCE(6, 7)
0172     QByteArray left(qsizetype len) const;
0173     QByteArray right(qsizetype len) const;
0174     QByteArray mid(qsizetype index, qsizetype len = -1) const;
0175     QByteArray first(qsizetype n) const;
0176     QByteArray last(qsizetype n) const;
0177     QByteArray sliced(qsizetype pos) const;
0178     QByteArray sliced(qsizetype pos, qsizetype n) const;
0179     QByteArray chopped(qsizetype len) const;
0180 #else
0181     [[nodiscard]] QByteArray left(qsizetype n) const &
0182     {
0183         if (n >= size())
0184             return *this;
0185         return first(qMax(n, 0));
0186     }
0187     [[nodiscard]] QByteArray left(qsizetype n) &&
0188     {
0189         if (n >= size())
0190             return std::move(*this);
0191         return std::move(*this).first(qMax(n, 0));
0192     }
0193     [[nodiscard]] QByteArray right(qsizetype n) const &
0194     {
0195         if (n >= size())
0196             return *this;
0197         return last(qMax(n, 0));
0198     }
0199     [[nodiscard]] QByteArray right(qsizetype n) &&
0200     {
0201         if (n >= size())
0202             return std::move(*this);
0203         return std::move(*this).last(qMax(n, 0));
0204     }
0205     [[nodiscard]] QByteArray mid(qsizetype index, qsizetype len = -1) const &;
0206     [[nodiscard]] QByteArray mid(qsizetype index, qsizetype len = -1) &&;
0207 
0208     [[nodiscard]] QByteArray first(qsizetype n) const &
0209     { verify(0, n); return sliced(0, n); }
0210     [[nodiscard]] QByteArray last(qsizetype n) const &
0211     { verify(0, n); return sliced(size() - n, n); }
0212     [[nodiscard]] QByteArray sliced(qsizetype pos) const &
0213     { verify(pos, 0); return sliced(pos, size() - pos); }
0214     [[nodiscard]] QByteArray sliced(qsizetype pos, qsizetype n) const &
0215     { verify(pos, n); return QByteArray(d.data() + pos, n); }
0216     [[nodiscard]] QByteArray chopped(qsizetype len) const &
0217     { verify(0, len); return sliced(0, size() - len); }
0218 
0219     [[nodiscard]] QByteArray first(qsizetype n) &&
0220     {
0221         verify(0, n);
0222         resize(n);      // may detach and allocate memory
0223         return std::move(*this);
0224     }
0225     [[nodiscard]] QByteArray last(qsizetype n) &&
0226     { verify(0, n); return sliced_helper(*this, size() - n, n); }
0227     [[nodiscard]] QByteArray sliced(qsizetype pos) &&
0228     { verify(pos, 0); return sliced_helper(*this, pos, size() - pos); }
0229     [[nodiscard]] QByteArray sliced(qsizetype pos, qsizetype n) &&
0230     { verify(pos, n); return sliced_helper(*this, pos, n); }
0231     [[nodiscard]] QByteArray chopped(qsizetype len) &&
0232     { verify(0, len); chop(len); return std::move(*this); }
0233 #endif
0234 
0235     bool startsWith(QByteArrayView bv) const
0236     { return QtPrivate::startsWith(qToByteArrayViewIgnoringNull(*this), bv); }
0237     bool startsWith(char c) const { return size() > 0 && front() == c; }
0238 
0239     bool endsWith(char c) const { return size() > 0 && back() == c; }
0240     bool endsWith(QByteArrayView bv) const
0241     { return QtPrivate::endsWith(qToByteArrayViewIgnoringNull(*this), bv); }
0242 
0243     bool isUpper() const;
0244     bool isLower() const;
0245 
0246     [[nodiscard]] bool isValidUtf8() const noexcept
0247     {
0248         return QtPrivate::isValidUtf8(qToByteArrayViewIgnoringNull(*this));
0249     }
0250 
0251     void truncate(qsizetype pos);
0252     void chop(qsizetype n);
0253 
0254     QByteArray &slice(qsizetype pos)
0255     { verify(pos, 0); return remove(0, pos); }
0256     QByteArray &slice(qsizetype pos, qsizetype n)
0257     {
0258         verify(pos, n);
0259         if (isNull())
0260             return *this;
0261         resize(pos + n);
0262         return remove(0, pos);
0263     }
0264 
0265 #if !defined(Q_QDOC)
0266     [[nodiscard]] QByteArray toLower() const &
0267     { return toLower_helper(*this); }
0268     [[nodiscard]] QByteArray toLower() &&
0269     { return toLower_helper(*this); }
0270     [[nodiscard]] QByteArray toUpper() const &
0271     { return toUpper_helper(*this); }
0272     [[nodiscard]] QByteArray toUpper() &&
0273     { return toUpper_helper(*this); }
0274     [[nodiscard]] QByteArray trimmed() const &
0275     { return trimmed_helper(*this); }
0276     [[nodiscard]] QByteArray trimmed() &&
0277     { return trimmed_helper(*this); }
0278     [[nodiscard]] QByteArray simplified() const &
0279     { return simplified_helper(*this); }
0280     [[nodiscard]] QByteArray simplified() &&
0281     { return simplified_helper(*this); }
0282 #else
0283     [[nodiscard]] QByteArray toLower() const;
0284     [[nodiscard]] QByteArray toUpper() const;
0285     [[nodiscard]] QByteArray trimmed() const;
0286     [[nodiscard]] QByteArray simplified() const;
0287 #endif
0288 
0289     [[nodiscard]] QByteArray leftJustified(qsizetype width, char fill = ' ', bool truncate = false) const;
0290     [[nodiscard]] QByteArray rightJustified(qsizetype width, char fill = ' ', bool truncate = false) const;
0291 
0292     QByteArray &prepend(char c)
0293     { return insert(0, QByteArrayView(&c, 1)); }
0294     inline QByteArray &prepend(qsizetype count, char c);
0295     QByteArray &prepend(const char *s)
0296     { return insert(0, QByteArrayView(s, qsizetype(qstrlen(s)))); }
0297     QByteArray &prepend(const char *s, qsizetype len)
0298     { return insert(0, QByteArrayView(s, len)); }
0299     QByteArray &prepend(const QByteArray &a);
0300     QByteArray &prepend(QByteArrayView a)
0301     { return insert(0, a); }
0302 
0303     QByteArray &append(char c);
0304     inline QByteArray &append(qsizetype count, char c);
0305     QByteArray &append(const char *s)
0306     { return append(s, -1); }
0307     QByteArray &append(const char *s, qsizetype len)
0308     { return append(QByteArrayView(s, len < 0 ? qsizetype(qstrlen(s)) : len)); }
0309     QByteArray &append(const QByteArray &a);
0310     QByteArray &append(QByteArrayView a)
0311     { return insert(size(), a); }
0312 
0313     QByteArray &assign(QByteArrayView v);
0314     QByteArray &assign(qsizetype n, char c)
0315     {
0316         Q_ASSERT(n >= 0);
0317         return fill(c, n);
0318     }
0319     template <typename InputIterator, if_input_iterator<InputIterator> = true>
0320     QByteArray &assign(InputIterator first, InputIterator last)
0321     {
0322         if constexpr (std::is_same_v<InputIterator, iterator> || std::is_same_v<InputIterator, const_iterator>)
0323             return assign(QByteArrayView(first, last));
0324         d->assign(first, last);
0325         if (d.data())
0326             d.data()[d.size] = '\0';
0327         return *this;
0328     }
0329 
0330     QByteArray &insert(qsizetype i, QByteArrayView data);
0331     inline QByteArray &insert(qsizetype i, const char *s)
0332     { return insert(i, QByteArrayView(s)); }
0333     inline QByteArray &insert(qsizetype i, const QByteArray &data)
0334     { return insert(i, QByteArrayView(data)); }
0335     QByteArray &insert(qsizetype i, qsizetype count, char c);
0336     QByteArray &insert(qsizetype i, char c)
0337     { return insert(i, QByteArrayView(&c, 1)); }
0338     QByteArray &insert(qsizetype i, const char *s, qsizetype len)
0339     { return insert(i, QByteArrayView(s, len)); }
0340 
0341     QByteArray &remove(qsizetype index, qsizetype len);
0342     QByteArray &removeAt(qsizetype pos)
0343     { return size_t(pos) < size_t(size()) ? remove(pos, 1) : *this; }
0344     QByteArray &removeFirst() { return !isEmpty() ? remove(0, 1) : *this; }
0345     QByteArray &removeLast() { return !isEmpty() ? remove(size() - 1, 1) : *this; }
0346 
0347     template <typename Predicate>
0348     QByteArray &removeIf(Predicate pred)
0349     {
0350         removeIf_helper(pred);
0351         return *this;
0352     }
0353 
0354     QByteArray &replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
0355     { return replace(index, len, QByteArrayView(s, alen)); }
0356     QByteArray &replace(qsizetype index, qsizetype len, QByteArrayView s);
0357     QByteArray &replace(char before, QByteArrayView after)
0358     { return replace(QByteArrayView(&before, 1), after); }
0359     QByteArray &replace(const char *before, qsizetype bsize, const char *after, qsizetype asize)
0360     { return replace(QByteArrayView(before, bsize), QByteArrayView(after, asize)); }
0361     QByteArray &replace(QByteArrayView before, QByteArrayView after);
0362     QByteArray &replace(char before, char after);
0363 
0364     QByteArray &operator+=(char c)
0365     { return append(c); }
0366     QByteArray &operator+=(const char *s)
0367     { return append(s); }
0368     QByteArray &operator+=(const QByteArray &a)
0369     { return append(a); }
0370     QByteArray &operator+=(QByteArrayView a)
0371     { return append(a); }
0372 
0373     QList<QByteArray> split(char sep) const;
0374 
0375     [[nodiscard]] QByteArray repeated(qsizetype times) const;
0376 
0377 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
0378 #if QT_CORE_REMOVED_SINCE(6, 8)
0379     QT_ASCII_CAST_WARN inline bool operator==(const QString &s2) const;
0380     QT_ASCII_CAST_WARN inline bool operator!=(const QString &s2) const;
0381     QT_ASCII_CAST_WARN inline bool operator<(const QString &s2) const;
0382     QT_ASCII_CAST_WARN inline bool operator>(const QString &s2) const;
0383     QT_ASCII_CAST_WARN inline bool operator<=(const QString &s2) const;
0384     QT_ASCII_CAST_WARN inline bool operator>=(const QString &s2) const;
0385 #endif // QT_CORE_REMOVED_SINCE(6, 8)
0386 #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
0387 
0388     short toShort(bool *ok = nullptr, int base = 10) const;
0389     ushort toUShort(bool *ok = nullptr, int base = 10) const;
0390     int toInt(bool *ok = nullptr, int base = 10) const;
0391     uint toUInt(bool *ok = nullptr, int base = 10) const;
0392     long toLong(bool *ok = nullptr, int base = 10) const;
0393     ulong toULong(bool *ok = nullptr, int base = 10) const;
0394     qlonglong toLongLong(bool *ok = nullptr, int base = 10) const;
0395     qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;
0396     float toFloat(bool *ok = nullptr) const;
0397     double toDouble(bool *ok = nullptr) const;
0398     QByteArray toBase64(Base64Options options = Base64Encoding) const;
0399     QByteArray toHex(char separator = '\0') const;
0400     QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
0401                                  const QByteArray &include = QByteArray(),
0402                                  char percent = '%') const;
0403 #if QT_CORE_REMOVED_SINCE(6, 11)
0404     [[nodiscard]] QByteArray percentDecoded(char percent = '%') const;
0405 #else
0406     [[nodiscard]] QByteArray percentDecoded(char percent = '%') const &
0407     { return fromPercentEncoding(*this, percent); }
0408     [[nodiscard]] QByteArray percentDecoded(char percent = '%') &&
0409     { return fromPercentEncoding(std::move(*this), percent); }
0410 #endif
0411 
0412     inline QByteArray &setNum(short, int base = 10);
0413     inline QByteArray &setNum(ushort, int base = 10);
0414     inline QByteArray &setNum(int, int base = 10);
0415     inline QByteArray &setNum(uint, int base = 10);
0416     inline QByteArray &setNum(long, int base = 10);
0417     inline QByteArray &setNum(ulong, int base = 10);
0418     QByteArray &setNum(qlonglong, int base = 10);
0419     QByteArray &setNum(qulonglong, int base = 10);
0420     inline QByteArray &setNum(float, char format = 'g', int precision = 6);
0421     QByteArray &setNum(double, char format = 'g', int precision = 6);
0422     QByteArray &setRawData(const char *a, qsizetype n);
0423 
0424     [[nodiscard]] static QByteArray number(int, int base = 10);
0425     [[nodiscard]] static QByteArray number(uint, int base = 10);
0426     [[nodiscard]] static QByteArray number(long, int base = 10);
0427     [[nodiscard]] static QByteArray number(ulong, int base = 10);
0428     [[nodiscard]] static QByteArray number(qlonglong, int base = 10);
0429     [[nodiscard]] static QByteArray number(qulonglong, int base = 10);
0430     [[nodiscard]] static QByteArray number(double, char format = 'g', int precision = 6);
0431     [[nodiscard]] static QByteArray fromRawData(const char *data, qsizetype size)
0432     {
0433         return QByteArray(DataPointer::fromRawData(data, size));
0434     }
0435 
0436     class FromBase64Result;
0437     [[nodiscard]] static FromBase64Result fromBase64Encoding(QByteArray &&base64, Base64Options options = Base64Encoding);
0438     [[nodiscard]] static FromBase64Result fromBase64Encoding(const QByteArray &base64, Base64Options options = Base64Encoding);
0439     [[nodiscard]] static QByteArray fromBase64(const QByteArray &base64, Base64Options options = Base64Encoding);
0440     [[nodiscard]] static QByteArray fromHex(const QByteArray &hexEncoded);
0441     [[nodiscard]] static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
0442     [[nodiscard]] static QByteArray fromPercentEncoding(QByteArray &&pctEncoded, char percent = '%');
0443 
0444 #if defined(Q_OS_DARWIN) || defined(Q_QDOC)
0445     static QByteArray fromCFData(CFDataRef data);
0446     static QByteArray fromRawCFData(CFDataRef data);
0447     CFDataRef toCFData() const Q_DECL_CF_RETURNS_RETAINED;
0448     CFDataRef toRawCFData() const Q_DECL_CF_RETURNS_RETAINED;
0449     static QByteArray fromNSData(const NSData *data);
0450     static QByteArray fromRawNSData(const NSData *data);
0451     NSData *toNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
0452     NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
0453 #endif
0454 
0455 #if defined(Q_OS_WASM) || defined(Q_QDOC)
0456     static QByteArray fromEcmaUint8Array(emscripten::val uint8array);
0457     emscripten::val toEcmaUint8Array();
0458 #endif
0459 
0460     typedef char *iterator;
0461     typedef const char *const_iterator;
0462     typedef iterator Iterator;
0463     typedef const_iterator ConstIterator;
0464     typedef std::reverse_iterator<iterator> reverse_iterator;
0465     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
0466     iterator begin() { return data(); }
0467     const_iterator begin() const noexcept { return d.data(); }
0468     const_iterator cbegin() const noexcept { return begin(); }
0469     const_iterator constBegin() const noexcept { return begin(); }
0470     iterator end() { return begin() + size(); }
0471     const_iterator end() const noexcept { return begin() + size(); }
0472     const_iterator cend() const noexcept { return end(); }
0473     const_iterator constEnd() const noexcept { return end(); }
0474     reverse_iterator rbegin() { return reverse_iterator(end()); }
0475     reverse_iterator rend() { return reverse_iterator(begin()); }
0476     const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
0477     const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
0478     const_reverse_iterator crbegin() const noexcept { return rbegin(); }
0479     const_reverse_iterator crend() const noexcept { return rend(); }
0480 
0481     // stl compatibility
0482     typedef qsizetype size_type;
0483     typedef qptrdiff difference_type;
0484     typedef const char & const_reference;
0485     typedef char & reference;
0486     typedef char *pointer;
0487     typedef const char *const_pointer;
0488     typedef char value_type;
0489     void push_back(char c)
0490     { append(c); }
0491     void push_back(const char *s)
0492     { append(s); }
0493     void push_back(const QByteArray &a)
0494     { append(a); }
0495     void push_back(QByteArrayView a)
0496     { append(a); }
0497     void push_front(char c)
0498     { prepend(c); }
0499     void push_front(const char *c)
0500     { prepend(c); }
0501     void push_front(const QByteArray &a)
0502     { prepend(a); }
0503     void push_front(QByteArrayView a)
0504     { prepend(a); }
0505     void shrink_to_fit() { squeeze(); }
0506     iterator erase(const_iterator first, const_iterator last);
0507     inline iterator erase(const_iterator it) { return erase(it, it + 1); }
0508     constexpr qsizetype max_size() const noexcept
0509     {
0510         return maxSize();
0511     }
0512 
0513     static QByteArray fromStdString(const std::string &s);
0514     std::string toStdString() const;
0515 
0516     static constexpr qsizetype maxSize() noexcept
0517     {
0518         // -1 to deal with the NUL terminator
0519         return Data::maxSize() - 1;
0520     }
0521     constexpr qsizetype size() const noexcept
0522     {
0523         constexpr size_t MaxSize = maxSize();
0524         Q_PRESUME(size_t(d.size) <= MaxSize);
0525         return d.size;
0526     }
0527 #if QT_DEPRECATED_SINCE(6, 4)
0528     QT_DEPRECATED_VERSION_X_6_4("Use size() or length() instead.")
0529     constexpr qsizetype count() const noexcept { return size(); }
0530 #endif
0531     constexpr qsizetype length() const noexcept { return size(); }
0532     QT_CORE_CONSTEXPR_INLINE_SINCE(6, 4)
0533     bool isNull() const noexcept;
0534 
0535     inline const DataPointer &data_ptr() const { return d; }
0536     inline DataPointer &data_ptr() { return d; }
0537 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
0538     explicit inline QByteArray(const DataPointer &dd) : d(dd) {}
0539 #endif
0540     explicit inline QByteArray(DataPointer &&dd) : d(std::move(dd)) {}
0541 
0542     [[nodiscard]] QByteArray nullTerminated() const &;
0543     [[nodiscard]] QByteArray nullTerminated() &&;
0544     QByteArray &nullTerminate();
0545 
0546 private:
0547     friend bool comparesEqual(const QByteArray &lhs, const QByteArrayView &rhs) noexcept
0548     { return QByteArrayView(lhs) == rhs; }
0549     friend Qt::strong_ordering
0550     compareThreeWay(const QByteArray &lhs, const QByteArrayView &rhs) noexcept
0551     {
0552         const int res = QtPrivate::compareMemory(QByteArrayView(lhs), rhs);
0553         return Qt::compareThreeWay(res, 0);
0554     }
0555     Q_DECLARE_STRONGLY_ORDERED(QByteArray)
0556     Q_DECLARE_STRONGLY_ORDERED(QByteArray, const char *)
0557 #if defined(__GLIBCXX__) && defined(__cpp_lib_three_way_comparison)
0558     // libstdc++ has a bug [0] when `operator const void *()` is preferred over
0559     // `operator<=>()` when calling std::less<> and other similar methods.
0560     // Fix it by explicitly providing relational operators in such case.
0561     // [0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114153
0562     friend bool operator<(const QByteArray &lhs, const QByteArray &rhs) noexcept
0563     { return is_lt(compareThreeWay(lhs, rhs)); }
0564     friend bool operator<=(const QByteArray &lhs, const QByteArray &rhs) noexcept
0565     { return is_lteq(compareThreeWay(lhs, rhs)); }
0566     friend bool operator>(const QByteArray &lhs, const QByteArray &rhs) noexcept
0567     { return is_gt(compareThreeWay(lhs, rhs)); }
0568     friend bool operator>=(const QByteArray &lhs, const QByteArray &rhs) noexcept
0569     { return is_gteq(compareThreeWay(lhs, rhs)); }
0570 #endif // defined(__GLIBCXX__) && defined(__cpp_lib_three_way_comparison)
0571 
0572     // Check isEmpty() instead of isNull() for backwards compatibility.
0573     friend bool comparesEqual(const QByteArray &lhs, std::nullptr_t) noexcept
0574     { return lhs.isEmpty(); }
0575     friend Qt::strong_ordering compareThreeWay(const QByteArray &lhs, std::nullptr_t) noexcept
0576     { return lhs.isEmpty() ? Qt::strong_ordering::equivalent : Qt::strong_ordering::greater; }
0577     Q_DECLARE_STRONGLY_ORDERED(QByteArray, std::nullptr_t)
0578 
0579     // defined in qstring.cpp
0580     friend Q_CORE_EXPORT bool comparesEqual(const QByteArray &lhs, const QChar &rhs) noexcept;
0581     friend Q_CORE_EXPORT Qt::strong_ordering
0582     compareThreeWay(const QByteArray &lhs, const QChar &rhs) noexcept;
0583     friend Q_CORE_EXPORT bool comparesEqual(const QByteArray &lhs, char16_t rhs) noexcept;
0584     friend Q_CORE_EXPORT Qt::strong_ordering
0585     compareThreeWay(const QByteArray &lhs, char16_t rhs) noexcept;
0586 #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
0587     Q_DECLARE_STRONGLY_ORDERED(QByteArray, QChar, QT_ASCII_CAST_WARN)
0588     Q_DECLARE_STRONGLY_ORDERED(QByteArray, char16_t, QT_ASCII_CAST_WARN)
0589 #endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
0590 
0591 
0592     void reallocData(qsizetype alloc, QArrayData::AllocationOption option);
0593     void reallocGrowData(qsizetype n);
0594     void expand(qsizetype i);
0595 
0596     Q_ALWAYS_INLINE constexpr void verify([[maybe_unused]] qsizetype pos = 0,
0597                                           [[maybe_unused]] qsizetype n = 1) const
0598     {
0599         Q_ASSERT(pos >= 0);
0600         Q_ASSERT(pos <= d.size);
0601         Q_ASSERT(n >= 0);
0602         Q_ASSERT(n <= d.size - pos);
0603     }
0604 
0605     static QByteArray sliced_helper(QByteArray &a, qsizetype pos, qsizetype n);
0606     static QByteArray toLower_helper(const QByteArray &a);
0607     static QByteArray toLower_helper(QByteArray &a);
0608     static QByteArray toUpper_helper(const QByteArray &a);
0609     static QByteArray toUpper_helper(QByteArray &a);
0610     static QByteArray trimmed_helper(const QByteArray &a);
0611     static QByteArray trimmed_helper(QByteArray &a);
0612     static QByteArray simplified_helper(const QByteArray &a);
0613     static QByteArray simplified_helper(QByteArray &a);
0614     template <typename Predicate>
0615     qsizetype removeIf_helper(Predicate pred)
0616     {
0617         const qsizetype result = d->eraseIf(pred);
0618         if (result > 0)
0619             d.data()[d.size] = '\0';
0620         return result;
0621     }
0622 
0623     friend class QString;
0624     friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, qsizetype nbytes);
0625 
0626     template <typename T> friend qsizetype erase(QByteArray &ba, const T &t);
0627     template <typename Predicate> friend qsizetype erase_if(QByteArray &ba, Predicate pred);
0628 };
0629 
0630 Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)
0631 
0632 inline constexpr QByteArray::QByteArray() noexcept {}
0633 inline QByteArray::~QByteArray() {}
0634 
0635 inline char QByteArray::at(qsizetype i) const
0636 { verify(i, 1); return d.data()[i]; }
0637 inline char QByteArray::operator[](qsizetype i) const
0638 { verify(i, 1); return d.data()[i]; }
0639 
0640 #ifndef QT_NO_CAST_FROM_BYTEARRAY
0641 inline QByteArray::operator const char *() const
0642 { return data(); }
0643 inline QByteArray::operator const void *() const
0644 { return data(); }
0645 #endif
0646 inline char *QByteArray::data()
0647 {
0648     detach();
0649     Q_ASSERT(d.data());
0650     return d.data();
0651 }
0652 inline const char *QByteArray::data() const noexcept
0653 {
0654 #if QT5_NULL_STRINGS == 1
0655     return d.data() ? d.data() : &_empty;
0656 #else
0657     return d.data();
0658 #endif
0659 }
0660 inline void QByteArray::detach()
0661 { if (d.needsDetach()) reallocData(size(), QArrayData::KeepSize); }
0662 inline bool QByteArray::isDetached() const
0663 { return !d.isShared(); }
0664 inline QByteArray::QByteArray(const QByteArray &a) noexcept : d(a.d)
0665 {}
0666 
0667 inline qsizetype QByteArray::capacity() const { return qsizetype(d.constAllocatedCapacity()); }
0668 
0669 inline void QByteArray::reserve(qsizetype asize)
0670 {
0671     if (d.needsDetach() || asize > capacity() - d.freeSpaceAtBegin())
0672         reallocData(qMax(size(), asize), QArrayData::KeepSize);
0673     if (d.constAllocatedCapacity())
0674         d.setFlag(Data::CapacityReserved);
0675 }
0676 
0677 inline void QByteArray::squeeze()
0678 {
0679     if (!d.isMutable())
0680         return;
0681     if (d.needsDetach() || size() < capacity())
0682         reallocData(size(), QArrayData::KeepSize);
0683     if (d.constAllocatedCapacity())
0684         d.clearFlag(Data::CapacityReserved);
0685 }
0686 
0687 inline char &QByteArray::operator[](qsizetype i)
0688 { verify(i, 1); return data()[i]; }
0689 inline char &QByteArray::front() { return operator[](0); }
0690 inline char &QByteArray::back() { return operator[](size() - 1); }
0691 inline QByteArray &QByteArray::append(qsizetype n, char ch)
0692 { return insert(size(), n, ch); }
0693 inline QByteArray &QByteArray::prepend(qsizetype n, char ch)
0694 { return insert(0, n, ch); }
0695 inline bool QByteArray::contains(char c) const
0696 { return indexOf(c) != -1; }
0697 inline bool QByteArray::contains(QByteArrayView bv) const
0698 { return indexOf(bv) != -1; }
0699 inline int QByteArray::compare(QByteArrayView a, Qt::CaseSensitivity cs) const noexcept
0700 {
0701     return cs == Qt::CaseSensitive ? QtPrivate::compareMemory(*this, a) :
0702                                      qstrnicmp(data(), size(), a.data(), a.size());
0703 }
0704 #if !defined(QT_USE_QSTRINGBUILDER)
0705 inline QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
0706 { return QByteArray(a1) += a2; }
0707 inline QByteArray operator+(QByteArray &&lhs, const QByteArray &rhs)
0708 { return std::move(lhs += rhs); }
0709 inline QByteArray operator+(const QByteArray &a1, const char *a2)
0710 { return QByteArray(a1) += a2; }
0711 inline QByteArray operator+(QByteArray &&lhs, const char *rhs)
0712 { return std::move(lhs += rhs); }
0713 inline QByteArray operator+(const QByteArray &a1, char a2)
0714 { return QByteArray(a1) += a2; }
0715 inline QByteArray operator+(QByteArray &&lhs, char rhs)
0716 { return std::move(lhs += rhs); }
0717 inline QByteArray operator+(const char *a1, const QByteArray &a2)
0718 { return QByteArray(a1) += a2; }
0719 inline QByteArray operator+(char a1, const QByteArray &a2)
0720 { return QByteArray(&a1, 1) += a2; }
0721 Q_WEAK_OVERLOAD
0722 inline QByteArray operator+(const QByteArray &lhs, QByteArrayView rhs)
0723 {
0724     QByteArray tmp{lhs.size() + rhs.size(), Qt::Uninitialized};
0725     return tmp.assign(lhs).append(rhs);
0726 }
0727 Q_WEAK_OVERLOAD
0728 inline QByteArray operator+(QByteArrayView lhs, const QByteArray &rhs)
0729 {
0730     QByteArray tmp{lhs.size() + rhs.size(), Qt::Uninitialized};
0731     return tmp.assign(lhs).append(rhs);
0732 }
0733 #endif // QT_USE_QSTRINGBUILDER
0734 
0735 inline QByteArray &QByteArray::setNum(short n, int base)
0736 { return setNum(qlonglong(n), base); }
0737 inline QByteArray &QByteArray::setNum(ushort n, int base)
0738 { return setNum(qulonglong(n), base); }
0739 inline QByteArray &QByteArray::setNum(int n, int base)
0740 { return setNum(qlonglong(n), base); }
0741 inline QByteArray &QByteArray::setNum(uint n, int base)
0742 { return setNum(qulonglong(n), base); }
0743 inline QByteArray &QByteArray::setNum(long n, int base)
0744 { return setNum(qlonglong(n), base); }
0745 inline QByteArray &QByteArray::setNum(ulong n, int base)
0746 { return setNum(qulonglong(n), base); }
0747 inline QByteArray &QByteArray::setNum(float n, char format, int precision)
0748 { return setNum(double(n), format, precision); }
0749 
0750 #if QT_CORE_INLINE_IMPL_SINCE(6, 4)
0751 QT_CORE_CONSTEXPR_INLINE_SINCE(6, 4)
0752 bool QByteArray::isNull() const noexcept
0753 {
0754     return d.isNull();
0755 }
0756 #endif
0757 #if QT_CORE_INLINE_IMPL_SINCE(6, 8)
0758 qsizetype QByteArray::indexOf(char ch, qsizetype from) const
0759 {
0760     return qToByteArrayViewIgnoringNull(*this).indexOf(ch, from);
0761 }
0762 qsizetype QByteArray::lastIndexOf(char ch, qsizetype from) const
0763 {
0764     return qToByteArrayViewIgnoringNull(*this).lastIndexOf(ch, from);
0765 }
0766 #endif
0767 
0768 #if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
0769 Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QByteArray &);
0770 Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QByteArray &);
0771 #endif
0772 
0773 #ifndef QT_NO_COMPRESS
0774 Q_CORE_EXPORT QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel = -1);
0775 Q_CORE_EXPORT QByteArray qUncompress(const uchar* data, qsizetype nbytes);
0776 inline QByteArray qCompress(const QByteArray& data, int compressionLevel = -1)
0777 { return qCompress(reinterpret_cast<const uchar *>(data.constData()), data.size(), compressionLevel); }
0778 inline QByteArray qUncompress(const QByteArray& data)
0779 { return qUncompress(reinterpret_cast<const uchar*>(data.constData()), data.size()); }
0780 #endif
0781 
0782 Q_DECLARE_SHARED(QByteArray)
0783 
0784 class QByteArray::FromBase64Result
0785 {
0786 public:
0787     QByteArray decoded;
0788     QByteArray::Base64DecodingStatus decodingStatus;
0789 
0790     void swap(QByteArray::FromBase64Result &other) noexcept
0791     {
0792         decoded.swap(other.decoded);
0793         std::swap(decodingStatus, other.decodingStatus);
0794     }
0795 
0796     explicit operator bool() const noexcept { return decodingStatus == QByteArray::Base64DecodingStatus::Ok; }
0797 
0798     QByteArray &operator*() & noexcept { return decoded; }
0799     const QByteArray &operator*() const & noexcept { return decoded; }
0800     QByteArray &&operator*() && noexcept { return std::move(decoded); }
0801 
0802     friend inline bool operator==(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
0803     {
0804         if (lhs.decodingStatus != rhs.decodingStatus)
0805             return false;
0806 
0807         if (lhs.decodingStatus == QByteArray::Base64DecodingStatus::Ok && lhs.decoded != rhs.decoded)
0808             return false;
0809 
0810         return true;
0811     }
0812 
0813     friend inline bool operator!=(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
0814     {
0815         return !(lhs == rhs);
0816     }
0817 };
0818 
0819 Q_DECLARE_SHARED(QByteArray::FromBase64Result)
0820 
0821 
0822 Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QByteArray::FromBase64Result &key, size_t seed = 0) noexcept;
0823 
0824 template <typename T>
0825 qsizetype erase(QByteArray &ba, const T &t)
0826 {
0827     return ba.removeIf_helper([&t](const auto &e) { return t == e; });
0828 }
0829 
0830 template <typename Predicate>
0831 qsizetype erase_if(QByteArray &ba, Predicate pred)
0832 {
0833     return ba.removeIf_helper(pred);
0834 }
0835 
0836 //
0837 // QByteArrayView members that require QByteArray:
0838 //
0839 QByteArray QByteArrayView::toByteArray() const
0840 {
0841     return QByteArray(*this);
0842 }
0843 
0844 namespace Qt {
0845 inline namespace Literals {
0846 inline namespace StringLiterals {
0847 
0848 inline QByteArray operator""_ba(const char *str, size_t size) noexcept
0849 {
0850     return QByteArray(QByteArrayData(nullptr, const_cast<char *>(str), qsizetype(size)));
0851 }
0852 
0853 } // StringLiterals
0854 } // Literals
0855 } // Qt
0856 
0857 inline namespace QtLiterals {
0858 #if QT_DEPRECATED_SINCE(6, 8)
0859 
0860 QT_DEPRECATED_VERSION_X_6_8("Use _ba from Qt::StringLiterals namespace instead.")
0861 inline QByteArray operator""_qba(const char *str, size_t size) noexcept
0862 {
0863     return Qt::StringLiterals::operator""_ba(str, size);
0864 }
0865 
0866 #endif // QT_DEPRECATED_SINCE(6, 8)
0867 } // QtLiterals
0868 
0869 QT_END_NAMESPACE
0870 
0871 #endif // QBYTEARRAY_H