Coverage Report

Created: 2025-07-16 07:53

/usr/include/QtCore/qbytearray.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2022 The Qt Company Ltd.
2
// Copyright (C) 2016 Intel Corporation.
3
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
// Qt-Security score:critical reason:data-parser
5
6
#ifndef QBYTEARRAY_H
7
#define QBYTEARRAY_H
8
9
#include <QtCore/qrefcount.h>
10
#include <QtCore/qnamespace.h>
11
#include <QtCore/qarraydata.h>
12
#include <QtCore/qarraydatapointer.h>
13
#include <QtCore/qcompare.h>
14
#include <QtCore/qcontainerfwd.h>
15
#include <QtCore/qbytearrayalgorithms.h>
16
#include <QtCore/qbytearrayview.h>
17
18
#include <stdlib.h>
19
#include <string.h>
20
21
#include <string>
22
#include <iterator>
23
24
#ifndef QT5_NULL_STRINGS
25
// Would ideally be off, but in practice breaks too much (Qt 6.0).
26
#define QT5_NULL_STRINGS 1
27
#endif
28
29
#ifdef truncate
30
#error qbytearray.h must be included before any header file that defines truncate
31
#endif
32
33
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
34
Q_FORWARD_DECLARE_CF_TYPE(CFData);
35
Q_FORWARD_DECLARE_OBJC_CLASS(NSData);
36
#endif
37
38
#if defined(Q_OS_WASM) || defined(Q_QDOC)
39
namespace emscripten {
40
    class val;
41
}
42
#endif
43
44
class tst_QByteArray;
45
46
QT_BEGIN_NAMESPACE
47
48
class QString;
49
class QDataStream;
50
51
using QByteArrayData = QArrayDataPointer<char>;
52
53
#  define QByteArrayLiteral(str) \
54
    (QByteArray(QByteArrayData(nullptr, const_cast<char *>(str), sizeof(str) - 1))) \
55
    /**/
56
57
class Q_CORE_EXPORT QByteArray
58
{
59
public:
60
    using DataPointer = QByteArrayData;
61
private:
62
    typedef QTypedArrayData<char> Data;
63
64
    DataPointer d;
65
    static const char _empty;
66
67
    friend class ::tst_QByteArray;
68
69
    template <typename InputIterator>
70
    using if_input_iterator = QtPrivate::IfIsInputIterator<InputIterator>;
71
public:
72
    enum Base64Option {
73
        Base64Encoding = 0,
74
        Base64UrlEncoding = 1,
75
76
        KeepTrailingEquals = 0,
77
        OmitTrailingEquals = 2,
78
79
        IgnoreBase64DecodingErrors = 0,
80
        AbortOnBase64DecodingErrors = 4,
81
    };
82
    Q_DECLARE_FLAGS(Base64Options, Base64Option)
83
84
    enum class Base64DecodingStatus {
85
        Ok,
86
        IllegalInputLength,
87
        IllegalCharacter,
88
        IllegalPadding,
89
    };
90
91
    inline constexpr QByteArray() noexcept;
92
    QByteArray(const char *, qsizetype size = -1);
93
    QByteArray(qsizetype size, char c);
94
    QByteArray(qsizetype size, Qt::Initialization);
95
    explicit QByteArray(QByteArrayView v) : QByteArray(v.data(), v.size()) {}
96
    inline QByteArray(const QByteArray &) noexcept;
97
    inline ~QByteArray();
98
99
    QByteArray &operator=(const QByteArray &) noexcept;
100
    QByteArray &operator=(const char *str);
101
    inline QByteArray(QByteArray && other) noexcept
102
7.08M
        = default;
103
    QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QByteArray)
104
    inline void swap(QByteArray &other) noexcept
105
1.07M
    { d.swap(other.d); }
106
107
58.3M
    constexpr bool isEmpty() const noexcept { return size() == 0; }
108
    void resize(qsizetype size);
109
    void resize(qsizetype size, char c);
110
    void resizeForOverwrite(qsizetype size);
111
112
    QByteArray &fill(char c, qsizetype size = -1);
113
114
    inline qsizetype capacity() const;
115
    inline void reserve(qsizetype size);
116
    inline void squeeze();
117
118
#ifndef QT_NO_CAST_FROM_BYTEARRAY
119
    inline operator const char *() const;
120
    inline operator const void *() const;
121
#endif
122
123
    // Some compilers consider this conversion ambiguous, so
124
    // we're not offering it there:
125
    // * QCC 8.3 on QNX
126
    // * GHS 2022.1.4 on INTEGRITY
127
#if (!defined(Q_OS_QNX) || !defined(Q_CC_GNU_ONLY) || Q_CC_GNU_ONLY > 803) && \
128
    (!defined(Q_CC_GHS) || !defined(__GHS_VERSION_NUMBER) || __GHS_VERSION_NUMBER > 202214)
129
# define QT_BYTEARRAY_CONVERTS_TO_STD_STRING_VIEW
130
    Q_IMPLICIT operator std::string_view() const noexcept
131
0
    { return std::string_view(data(), std::size_t(size())); }
132
#endif
133
134
    inline char *data();
135
    inline const char *data() const noexcept;
136
901M
    const char *constData() const noexcept { return data(); }
137
    inline void detach();
138
    inline bool isDetached() const;
139
    inline bool isSharedWith(const QByteArray &other) const noexcept
140
0
    { return data() == other.data() && size() == other.size(); }
141
    void clear();
142
143
    inline char at(qsizetype i) const;
144
    inline char operator[](qsizetype i) const;
145
    [[nodiscard]] inline char &operator[](qsizetype i);
146
0
    [[nodiscard]] char front() const { return at(0); }
147
    [[nodiscard]] inline char &front();
148
    [[nodiscard]] char back() const { return at(size() - 1); }
149
    [[nodiscard]] inline char &back();
150
151
    QT_CORE_INLINE_SINCE(6, 8)
152
    qsizetype indexOf(char c, qsizetype from = 0) const;
153
    qsizetype indexOf(QByteArrayView bv, qsizetype from = 0) const
154
4.09k
    { return QtPrivate::findByteArray(qToByteArrayViewIgnoringNull(*this), from, bv); }
155
156
    QT_CORE_INLINE_SINCE(6, 8)
157
    qsizetype lastIndexOf(char c, qsizetype from = -1) const;
158
    qsizetype lastIndexOf(QByteArrayView bv) const
159
0
    { return lastIndexOf(bv, size()); }
160
    qsizetype lastIndexOf(QByteArrayView bv, qsizetype from) const
161
0
    { return QtPrivate::lastIndexOf(qToByteArrayViewIgnoringNull(*this), from, bv); }
162
163
    inline bool contains(char c) const;
164
    inline bool contains(QByteArrayView bv) const;
165
    qsizetype count(char c) const;
166
    qsizetype count(QByteArrayView bv) const
167
0
    { return QtPrivate::count(qToByteArrayViewIgnoringNull(*this), bv); }
168
169
    inline int compare(QByteArrayView a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
170
171
#if QT_CORE_REMOVED_SINCE(6, 7)
172
    QByteArray left(qsizetype len) const;
173
    QByteArray right(qsizetype len) const;
174
    QByteArray mid(qsizetype index, qsizetype len = -1) const;
175
    QByteArray first(qsizetype n) const;
176
    QByteArray last(qsizetype n) const;
177
    QByteArray sliced(qsizetype pos) const;
178
    QByteArray sliced(qsizetype pos, qsizetype n) const;
179
    QByteArray chopped(qsizetype len) const;
180
#else
181
    [[nodiscard]] QByteArray left(qsizetype n) const &
182
544k
    {
183
544k
        if (n >= size())
184
17.5k
            return *this;
185
527k
        return first(qMax(n, 0));
186
544k
    }
187
    [[nodiscard]] QByteArray left(qsizetype n) &&
188
0
    {
189
0
        if (n >= size())
190
0
            return std::move(*this);
191
0
        return std::move(*this).first(qMax(n, 0));
192
0
    }
193
    [[nodiscard]] QByteArray right(qsizetype n) const &
194
    {
195
        if (n >= size())
196
            return *this;
197
        return last(qMax(n, 0));
198
    }
199
    [[nodiscard]] QByteArray right(qsizetype n) &&
200
0
    {
201
0
        if (n >= size())
202
0
            return std::move(*this);
203
0
        return std::move(*this).last(qMax(n, 0));
204
0
    }
205
    [[nodiscard]] QByteArray mid(qsizetype index, qsizetype len = -1) const &;
206
    [[nodiscard]] QByteArray mid(qsizetype index, qsizetype len = -1) &&;
207
208
    [[nodiscard]] QByteArray first(qsizetype n) const &
209
527k
    { verify(0, n); return sliced(0, n); }
210
    [[nodiscard]] QByteArray last(qsizetype n) const &
211
    { verify(0, n); return sliced(size() - n, n); }
212
    [[nodiscard]] QByteArray sliced(qsizetype pos) const &
213
0
    { verify(pos, 0); return sliced(pos, size() - pos); }
214
    [[nodiscard]] QByteArray sliced(qsizetype pos, qsizetype n) const &
215
7.62M
    { verify(pos, n); return QByteArray(d.data() + pos, n); }
216
    [[nodiscard]] QByteArray chopped(qsizetype len) const &
217
0
    { verify(0, len); return sliced(0, size() - len); }
218
219
    [[nodiscard]] QByteArray first(qsizetype n) &&
220
0
    {
221
0
        verify(0, n);
222
0
        resize(n);      // may detach and allocate memory
223
0
        return std::move(*this);
224
0
    }
225
    [[nodiscard]] QByteArray last(qsizetype n) &&
226
0
    { verify(0, n); return sliced_helper(*this, size() - n, n); }
227
    [[nodiscard]] QByteArray sliced(qsizetype pos) &&
228
0
    { verify(pos, 0); return sliced_helper(*this, pos, size() - pos); }
229
    [[nodiscard]] QByteArray sliced(qsizetype pos, qsizetype n) &&
230
0
    { verify(pos, n); return sliced_helper(*this, pos, n); }
231
    [[nodiscard]] QByteArray chopped(qsizetype len) &&
232
0
    { verify(0, len); return std::move(*this).first(size() - len); }
233
#endif
234
235
    bool startsWith(QByteArrayView bv) const
236
4.32M
    { return QtPrivate::startsWith(qToByteArrayViewIgnoringNull(*this), bv); }
237
0
    bool startsWith(char c) const { return size() > 0 && front() == c; }
238
239
    bool endsWith(char c) const { return size() > 0 && back() == c; }
240
    bool endsWith(QByteArrayView bv) const
241
0
    { return QtPrivate::endsWith(qToByteArrayViewIgnoringNull(*this), bv); }
242
243
    bool isUpper() const;
244
    bool isLower() const;
245
246
    [[nodiscard]] bool isValidUtf8() const noexcept
247
0
    {
248
0
        return QtPrivate::isValidUtf8(qToByteArrayViewIgnoringNull(*this));
249
0
    }
250
251
    void truncate(qsizetype pos);
252
    void chop(qsizetype n);
253
254
    QByteArray &slice(qsizetype pos)
255
0
    { verify(pos, 0); return remove(0, pos); }
256
    QByteArray &slice(qsizetype pos, qsizetype n)
257
0
    {
258
0
        verify(pos, n);
259
0
        if (isNull())
260
0
            return *this;
261
0
        resize(pos + n);
262
0
        return remove(0, pos);
263
0
    }
264
265
#if !defined(Q_QDOC)
266
    [[nodiscard]] QByteArray toLower() const &
267
    { return toLower_helper(*this); }
268
    [[nodiscard]] QByteArray toLower() &&
269
    { return toLower_helper(*this); }
270
    [[nodiscard]] QByteArray toUpper() const &
271
0
    { return toUpper_helper(*this); }
272
    [[nodiscard]] QByteArray toUpper() &&
273
0
    { return toUpper_helper(*this); }
274
    [[nodiscard]] QByteArray trimmed() const &
275
0
    { return trimmed_helper(*this); }
276
    [[nodiscard]] QByteArray trimmed() &&
277
    { return trimmed_helper(*this); }
278
    [[nodiscard]] QByteArray simplified() const &
279
0
    { return simplified_helper(*this); }
280
    [[nodiscard]] QByteArray simplified() &&
281
    { return simplified_helper(*this); }
282
#else
283
    [[nodiscard]] QByteArray toLower() const;
284
    [[nodiscard]] QByteArray toUpper() const;
285
    [[nodiscard]] QByteArray trimmed() const;
286
    [[nodiscard]] QByteArray simplified() const;
287
#endif
288
289
    [[nodiscard]] QByteArray leftJustified(qsizetype width, char fill = ' ', bool truncate = false) const;
290
    [[nodiscard]] QByteArray rightJustified(qsizetype width, char fill = ' ', bool truncate = false) const;
291
292
    QByteArray &prepend(char c)
293
0
    { return insert(0, QByteArrayView(&c, 1)); }
294
    inline QByteArray &prepend(qsizetype count, char c);
295
    QByteArray &prepend(const char *s)
296
0
    { return insert(0, QByteArrayView(s, qsizetype(qstrlen(s)))); }
297
    QByteArray &prepend(const char *s, qsizetype len)
298
0
    { return insert(0, QByteArrayView(s, len)); }
299
    QByteArray &prepend(const QByteArray &a);
300
    QByteArray &prepend(QByteArrayView a)
301
0
    { return insert(0, a); }
302
303
    QByteArray &append(char c);
304
    inline QByteArray &append(qsizetype count, char c);
305
    QByteArray &append(const char *s)
306
24
    { return append(s, -1); }
307
    QByteArray &append(const char *s, qsizetype len)
308
17.3k
    { return append(QByteArrayView(s, len < 0 ? qsizetype(qstrlen(s)) : len)); }
309
    QByteArray &append(const QByteArray &a);
310
    QByteArray &append(QByteArrayView a)
311
11.3M
    { return insert(size(), a); }
312
313
    QByteArray &assign(QByteArrayView v);
314
    QByteArray &assign(qsizetype n, char c)
315
0
    {
316
0
        Q_ASSERT(n >= 0);
317
0
        return fill(c, n);
318
0
    }
319
    template <typename InputIterator, if_input_iterator<InputIterator> = true>
320
    QByteArray &assign(InputIterator first, InputIterator last)
321
    {
322
        if constexpr (std::is_same_v<InputIterator, iterator> || std::is_same_v<InputIterator, const_iterator>)
323
            return assign(QByteArrayView(first, last));
324
        d.assign(first, last);
325
        if (d.data())
326
            d.data()[d.size] = '\0';
327
        return *this;
328
    }
329
330
    QByteArray &insert(qsizetype i, QByteArrayView data);
331
    inline QByteArray &insert(qsizetype i, const char *s)
332
0
    { return insert(i, QByteArrayView(s)); }
333
    inline QByteArray &insert(qsizetype i, const QByteArray &data)
334
0
    { return insert(i, QByteArrayView(data)); }
335
    QByteArray &insert(qsizetype i, qsizetype count, char c);
336
    QByteArray &insert(qsizetype i, char c)
337
0
    { return insert(i, QByteArrayView(&c, 1)); }
338
    QByteArray &insert(qsizetype i, const char *s, qsizetype len)
339
0
    { return insert(i, QByteArrayView(s, len)); }
340
341
    QByteArray &remove(qsizetype index, qsizetype len);
342
    QByteArray &removeAt(qsizetype pos)
343
0
    { return size_t(pos) < size_t(size()) ? remove(pos, 1) : *this; }
344
0
    QByteArray &removeFirst() { return !isEmpty() ? remove(0, 1) : *this; }
345
19.1k
    QByteArray &removeLast() { return !isEmpty() ? remove(size() - 1, 1) : *this; }
346
347
    template <typename Predicate>
348
    QByteArray &removeIf(Predicate pred)
349
    {
350
        removeIf_helper(pred);
351
        return *this;
352
    }
353
354
    QByteArray &replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
355
0
    { return replace(index, len, QByteArrayView(s, alen)); }
356
    QByteArray &replace(qsizetype index, qsizetype len, QByteArrayView s);
357
    QByteArray &replace(char before, QByteArrayView after)
358
    { return replace(QByteArrayView(&before, 1), after); }
359
    QByteArray &replace(const char *before, qsizetype bsize, const char *after, qsizetype asize)
360
0
    { return replace(QByteArrayView(before, bsize), QByteArrayView(after, asize)); }
361
    QByteArray &replace(QByteArrayView before, QByteArrayView after);
362
    QByteArray &replace(char before, char after);
363
364
    QByteArray &operator+=(char c)
365
    { return append(c); }
366
    QByteArray &operator+=(const char *s)
367
    { return append(s); }
368
    QByteArray &operator+=(const QByteArray &a)
369
0
    { return append(a); }
370
    QByteArray &operator+=(QByteArrayView a)
371
0
    { return append(a); }
372
373
    QList<QByteArray> split(char sep) const;
374
375
    [[nodiscard]] QByteArray repeated(qsizetype times) const;
376
377
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
378
#if QT_CORE_REMOVED_SINCE(6, 8)
379
    QT_ASCII_CAST_WARN inline bool operator==(const QString &s2) const;
380
    QT_ASCII_CAST_WARN inline bool operator!=(const QString &s2) const;
381
    QT_ASCII_CAST_WARN inline bool operator<(const QString &s2) const;
382
    QT_ASCII_CAST_WARN inline bool operator>(const QString &s2) const;
383
    QT_ASCII_CAST_WARN inline bool operator<=(const QString &s2) const;
384
    QT_ASCII_CAST_WARN inline bool operator>=(const QString &s2) const;
385
#endif // QT_CORE_REMOVED_SINCE(6, 8)
386
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
387
388
    short toShort(bool *ok = nullptr, int base = 10) const;
389
    ushort toUShort(bool *ok = nullptr, int base = 10) const;
390
    int toInt(bool *ok = nullptr, int base = 10) const;
391
    uint toUInt(bool *ok = nullptr, int base = 10) const;
392
    long toLong(bool *ok = nullptr, int base = 10) const;
393
    ulong toULong(bool *ok = nullptr, int base = 10) const;
394
    qlonglong toLongLong(bool *ok = nullptr, int base = 10) const;
395
    qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;
396
    float toFloat(bool *ok = nullptr) const;
397
    double toDouble(bool *ok = nullptr) const;
398
    QByteArray toBase64(Base64Options options = Base64Encoding) const;
399
    QByteArray toHex(char separator = '\0') const;
400
    QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
401
                                 const QByteArray &include = QByteArray(),
402
                                 char percent = '%') const;
403
    [[nodiscard]] QByteArray percentDecoded(char percent = '%') const;
404
405
    inline QByteArray &setNum(short, int base = 10);
406
    inline QByteArray &setNum(ushort, int base = 10);
407
    inline QByteArray &setNum(int, int base = 10);
408
    inline QByteArray &setNum(uint, int base = 10);
409
    inline QByteArray &setNum(long, int base = 10);
410
    inline QByteArray &setNum(ulong, int base = 10);
411
    QByteArray &setNum(qlonglong, int base = 10);
412
    QByteArray &setNum(qulonglong, int base = 10);
413
    inline QByteArray &setNum(float, char format = 'g', int precision = 6);
414
    QByteArray &setNum(double, char format = 'g', int precision = 6);
415
    QByteArray &setRawData(const char *a, qsizetype n);
416
417
    [[nodiscard]] static QByteArray number(int, int base = 10);
418
    [[nodiscard]] static QByteArray number(uint, int base = 10);
419
    [[nodiscard]] static QByteArray number(long, int base = 10);
420
    [[nodiscard]] static QByteArray number(ulong, int base = 10);
421
    [[nodiscard]] static QByteArray number(qlonglong, int base = 10);
422
    [[nodiscard]] static QByteArray number(qulonglong, int base = 10);
423
    [[nodiscard]] static QByteArray number(double, char format = 'g', int precision = 6);
424
    [[nodiscard]] static QByteArray fromRawData(const char *data, qsizetype size)
425
19.8k
    {
426
19.8k
        return QByteArray(DataPointer::fromRawData(data, size));
427
19.8k
    }
428
429
    class FromBase64Result;
430
    [[nodiscard]] static FromBase64Result fromBase64Encoding(QByteArray &&base64, Base64Options options = Base64Encoding);
431
    [[nodiscard]] static FromBase64Result fromBase64Encoding(const QByteArray &base64, Base64Options options = Base64Encoding);
432
    [[nodiscard]] static QByteArray fromBase64(const QByteArray &base64, Base64Options options = Base64Encoding);
433
    [[nodiscard]] static QByteArray fromHex(const QByteArray &hexEncoded);
434
    [[nodiscard]] static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
435
436
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
437
    static QByteArray fromCFData(CFDataRef data);
438
    static QByteArray fromRawCFData(CFDataRef data);
439
    CFDataRef toCFData() const Q_DECL_CF_RETURNS_RETAINED;
440
    CFDataRef toRawCFData() const Q_DECL_CF_RETURNS_RETAINED;
441
    static QByteArray fromNSData(const NSData *data);
442
    static QByteArray fromRawNSData(const NSData *data);
443
    NSData *toNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
444
    NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
445
#endif
446
447
#if defined(Q_OS_WASM) || defined(Q_QDOC)
448
    static QByteArray fromEcmaUint8Array(emscripten::val uint8array);
449
    emscripten::val toEcmaUint8Array();
450
#endif
451
452
    typedef char *iterator;
453
    typedef const char *const_iterator;
454
    typedef iterator Iterator;
455
    typedef const_iterator ConstIterator;
456
    typedef std::reverse_iterator<iterator> reverse_iterator;
457
    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
458
15.4M
    iterator begin() { return data(); }
459
48.3M
    const_iterator begin() const noexcept { return d.data(); }
460
    const_iterator cbegin() const noexcept { return begin(); }
461
    const_iterator constBegin() const noexcept { return begin(); }
462
12.5M
    iterator end() { return begin() + size(); }
463
244k
    const_iterator end() const noexcept { return begin() + size(); }
464
    const_iterator cend() const noexcept { return end(); }
465
    const_iterator constEnd() const noexcept { return end(); }
466
0
    reverse_iterator rbegin() { return reverse_iterator(end()); }
467
0
    reverse_iterator rend() { return reverse_iterator(begin()); }
468
0
    const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator(end()); }
469
0
    const_reverse_iterator rend() const noexcept { return const_reverse_iterator(begin()); }
470
0
    const_reverse_iterator crbegin() const noexcept { return rbegin(); }
471
0
    const_reverse_iterator crend() const noexcept { return rend(); }
472
473
    // stl compatibility
474
    typedef qsizetype size_type;
475
    typedef qptrdiff difference_type;
476
    typedef const char & const_reference;
477
    typedef char & reference;
478
    typedef char *pointer;
479
    typedef const char *const_pointer;
480
    typedef char value_type;
481
    void push_back(char c)
482
0
    { append(c); }
483
    void push_back(const char *s)
484
0
    { append(s); }
485
    void push_back(const QByteArray &a)
486
0
    { append(a); }
487
    void push_back(QByteArrayView a)
488
0
    { append(a); }
489
    void push_front(char c)
490
0
    { prepend(c); }
491
    void push_front(const char *c)
492
0
    { prepend(c); }
493
    void push_front(const QByteArray &a)
494
0
    { prepend(a); }
495
    void push_front(QByteArrayView a)
496
0
    { prepend(a); }
497
0
    void shrink_to_fit() { squeeze(); }
498
    iterator erase(const_iterator first, const_iterator last);
499
0
    inline iterator erase(const_iterator it) { return erase(it, it + 1); }
500
    constexpr qsizetype max_size() const noexcept
501
0
    {
502
0
        return maxSize();
503
0
    }
504
505
    static QByteArray fromStdString(const std::string &s);
506
    std::string toStdString() const;
507
508
    static constexpr qsizetype maxSize() noexcept
509
    {
510
        // -1 to deal with the NUL terminator
511
        return Data::maxSize() - 1;
512
    }
513
    constexpr qsizetype size() const noexcept
514
2.63G
    {
515
#if __has_cpp_attribute(assume)
516
        constexpr size_t MaxSize = maxSize();
517
        [[assume(size_t(d.size) <= MaxSize)]];
518
#endif
519
2.63G
        return d.size;
520
2.63G
    }
521
#if QT_DEPRECATED_SINCE(6, 4)
522
    QT_DEPRECATED_VERSION_X_6_4("Use size() or length() instead.")
523
0
    constexpr qsizetype count() const noexcept { return size(); }
524
#endif
525
    constexpr qsizetype length() const noexcept { return size(); }
526
    QT_CORE_CONSTEXPR_INLINE_SINCE(6, 4)
527
    bool isNull() const noexcept;
528
529
0
    inline const DataPointer &data_ptr() const { return d; }
530
    inline DataPointer &data_ptr() { return d; }
531
#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
532
0
    explicit inline QByteArray(const DataPointer &dd) : d(dd) {}
533
#endif
534
126k
    explicit inline QByteArray(DataPointer &&dd) : d(std::move(dd)) {}
535
536
    [[nodiscard]] QByteArray nullTerminated() const &;
537
    [[nodiscard]] QByteArray nullTerminated() &&;
538
    QByteArray &nullTerminate();
539
540
private:
541
    friend bool comparesEqual(const QByteArray &lhs, const QByteArrayView &rhs) noexcept
542
21.9M
    { return QByteArrayView(lhs) == rhs; }
543
    friend Qt::strong_ordering
544
    compareThreeWay(const QByteArray &lhs, const QByteArrayView &rhs) noexcept
545
0
    {
546
0
        const int res = QtPrivate::compareMemory(QByteArrayView(lhs), rhs);
547
0
        return Qt::compareThreeWay(res, 0);
548
0
    }
549
    Q_DECLARE_STRONGLY_ORDERED(QByteArray)
550
    Q_DECLARE_STRONGLY_ORDERED(QByteArray, const char *)
551
#if defined(__GLIBCXX__) && defined(__cpp_lib_three_way_comparison)
552
    // libstdc++ has a bug [0] when `operator const void *()` is preferred over
553
    // `operator<=>()` when calling std::less<> and other similar methods.
554
    // Fix it by explicitly providing relational operators in such case.
555
    // [0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114153
556
    friend bool operator<(const QByteArray &lhs, const QByteArray &rhs) noexcept
557
    { return is_lt(compareThreeWay(lhs, rhs)); }
558
    friend bool operator<=(const QByteArray &lhs, const QByteArray &rhs) noexcept
559
    { return is_lteq(compareThreeWay(lhs, rhs)); }
560
    friend bool operator>(const QByteArray &lhs, const QByteArray &rhs) noexcept
561
    { return is_gt(compareThreeWay(lhs, rhs)); }
562
    friend bool operator>=(const QByteArray &lhs, const QByteArray &rhs) noexcept
563
    { return is_gteq(compareThreeWay(lhs, rhs)); }
564
#endif // defined(__GLIBCXX__) && defined(__cpp_lib_three_way_comparison)
565
566
    // Check isEmpty() instead of isNull() for backwards compatibility.
567
    friend bool comparesEqual(const QByteArray &lhs, std::nullptr_t) noexcept
568
0
    { return lhs.isEmpty(); }
569
    friend Qt::strong_ordering compareThreeWay(const QByteArray &lhs, std::nullptr_t) noexcept
570
0
    { return lhs.isEmpty() ? Qt::strong_ordering::equivalent : Qt::strong_ordering::greater; }
571
    Q_DECLARE_STRONGLY_ORDERED(QByteArray, std::nullptr_t)
572
573
    // defined in qstring.cpp
574
    friend Q_CORE_EXPORT bool comparesEqual(const QByteArray &lhs, const QChar &rhs) noexcept;
575
    friend Q_CORE_EXPORT Qt::strong_ordering
576
    compareThreeWay(const QByteArray &lhs, const QChar &rhs) noexcept;
577
    friend Q_CORE_EXPORT bool comparesEqual(const QByteArray &lhs, char16_t rhs) noexcept;
578
    friend Q_CORE_EXPORT Qt::strong_ordering
579
    compareThreeWay(const QByteArray &lhs, char16_t rhs) noexcept;
580
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
581
    Q_DECLARE_STRONGLY_ORDERED(QByteArray, QChar, QT_ASCII_CAST_WARN)
582
    Q_DECLARE_STRONGLY_ORDERED(QByteArray, char16_t, QT_ASCII_CAST_WARN)
583
#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
584
585
586
    void reallocData(qsizetype alloc, QArrayData::AllocationOption option);
587
    void reallocGrowData(qsizetype n);
588
    void expand(qsizetype i);
589
590
    Q_ALWAYS_INLINE constexpr void verify([[maybe_unused]] qsizetype pos = 0,
591
                                          [[maybe_unused]] qsizetype n = 1) const
592
1.29G
    {
593
1.29G
        Q_ASSERT(pos >= 0);
594
1.29G
        Q_ASSERT(pos <= d.size);
595
1.29G
        Q_ASSERT(n >= 0);
596
1.29G
        Q_ASSERT(n <= d.size - pos);
597
1.29G
    }
598
599
    static QByteArray sliced_helper(QByteArray &a, qsizetype pos, qsizetype n);
600
    static QByteArray toLower_helper(const QByteArray &a);
601
    static QByteArray toLower_helper(QByteArray &a);
602
    static QByteArray toUpper_helper(const QByteArray &a);
603
    static QByteArray toUpper_helper(QByteArray &a);
604
    static QByteArray trimmed_helper(const QByteArray &a);
605
    static QByteArray trimmed_helper(QByteArray &a);
606
    static QByteArray simplified_helper(const QByteArray &a);
607
    static QByteArray simplified_helper(QByteArray &a);
608
    template <typename Predicate>
609
    qsizetype removeIf_helper(Predicate pred)
610
    {
611
        const qsizetype result = d->eraseIf(pred);
612
        if (result > 0)
613
            d.data()[d.size] = '\0';
614
        return result;
615
    }
616
617
    friend class QString;
618
    friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, qsizetype nbytes);
619
620
    template <typename T> friend qsizetype erase(QByteArray &ba, const T &t);
621
    template <typename Predicate> friend qsizetype erase_if(QByteArray &ba, Predicate pred);
622
};
623
624
Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)
625
626
19.1M
inline constexpr QByteArray::QByteArray() noexcept {}
627
209M
inline QByteArray::~QByteArray() {}
628
629
inline char QByteArray::at(qsizetype i) const
630
1.18G
{ verify(i, 1); return d.data()[i]; }
631
inline char QByteArray::operator[](qsizetype i) const
632
0
{ verify(i, 1); return d.data()[i]; }
633
634
#ifndef QT_NO_CAST_FROM_BYTEARRAY
635
inline QByteArray::operator const char *() const
636
{ return data(); }
637
inline QByteArray::operator const void *() const
638
0
{ return data(); }
639
#endif
640
inline char *QByteArray::data()
641
376M
{
642
376M
    detach();
643
376M
    Q_ASSERT(d.data());
644
376M
    return d.data();
645
376M
}
646
inline const char *QByteArray::data() const noexcept
647
902M
{
648
902M
#if QT5_NULL_STRINGS == 1
649
902M
    return d.data() ? d.data() : &_empty;
650
#else
651
    return d.data();
652
#endif
653
902M
}
654
inline void QByteArray::detach()
655
376M
{ if (d.needsDetach()) reallocData(size(), QArrayData::KeepSize); }
656
inline bool QByteArray::isDetached() const
657
{ return !d.isShared(); }
658
1.30M
inline QByteArray::QByteArray(const QByteArray &a) noexcept : d(a.d)
659
1.30M
{}
660
661
182M
inline qsizetype QByteArray::capacity() const { return qsizetype(d.constAllocatedCapacity()); }
662
663
inline void QByteArray::reserve(qsizetype asize)
664
35
{
665
35
    if (d.needsDetach() || asize > capacity() - d.freeSpaceAtBegin())
666
35
        reallocData(qMax(size(), asize), QArrayData::KeepSize);
667
35
    if (d.constAllocatedCapacity())
668
35
        d.setFlag(Data::CapacityReserved);
669
35
}
670
671
inline void QByteArray::squeeze()
672
0
{
673
0
    if (!d.isMutable())
674
0
        return;
675
0
    if (d.needsDetach() || size() < capacity())
676
0
        reallocData(size(), QArrayData::KeepSize);
677
0
    if (d.constAllocatedCapacity())
678
0
        d.clearFlag(Data::CapacityReserved);
679
0
}
680
681
inline char &QByteArray::operator[](qsizetype i)
682
97.8M
{ verify(i, 1); return data()[i]; }
683
0
inline char &QByteArray::front() { return operator[](0); }
684
0
inline char &QByteArray::back() { return operator[](size() - 1); }
685
inline QByteArray &QByteArray::append(qsizetype n, char ch)
686
{ return insert(size(), n, ch); }
687
inline QByteArray &QByteArray::prepend(qsizetype n, char ch)
688
0
{ return insert(0, n, ch); }
689
inline bool QByteArray::contains(char c) const
690
{ return indexOf(c) != -1; }
691
inline bool QByteArray::contains(QByteArrayView bv) const
692
208
{ return indexOf(bv) != -1; }
693
inline int QByteArray::compare(QByteArrayView a, Qt::CaseSensitivity cs) const noexcept
694
0
{
695
0
    return cs == Qt::CaseSensitive ? QtPrivate::compareMemory(*this, a) :
696
0
                                     qstrnicmp(data(), size(), a.data(), a.size());
697
0
}
698
#if !defined(QT_USE_QSTRINGBUILDER)
699
inline QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
700
0
{ return QByteArray(a1) += a2; }
701
inline QByteArray operator+(QByteArray &&lhs, const QByteArray &rhs)
702
0
{ return std::move(lhs += rhs); }
703
inline QByteArray operator+(const QByteArray &a1, const char *a2)
704
0
{ return QByteArray(a1) += a2; }
705
inline QByteArray operator+(QByteArray &&lhs, const char *rhs)
706
0
{ return std::move(lhs += rhs); }
707
inline QByteArray operator+(const QByteArray &a1, char a2)
708
0
{ return QByteArray(a1) += a2; }
709
inline QByteArray operator+(QByteArray &&lhs, char rhs)
710
0
{ return std::move(lhs += rhs); }
711
inline QByteArray operator+(const char *a1, const QByteArray &a2)
712
0
{ return QByteArray(a1) += a2; }
713
inline QByteArray operator+(char a1, const QByteArray &a2)
714
0
{ return QByteArray(&a1, 1) += a2; }
715
Q_WEAK_OVERLOAD
716
inline QByteArray operator+(const QByteArray &lhs, QByteArrayView rhs)
717
{
718
    QByteArray tmp{lhs.size() + rhs.size(), Qt::Uninitialized};
719
    return tmp.assign(lhs).append(rhs);
720
}
721
Q_WEAK_OVERLOAD
722
inline QByteArray operator+(QByteArrayView lhs, const QByteArray &rhs)
723
{
724
    QByteArray tmp{lhs.size() + rhs.size(), Qt::Uninitialized};
725
    return tmp.assign(lhs).append(rhs);
726
}
727
#endif // QT_USE_QSTRINGBUILDER
728
729
inline QByteArray &QByteArray::setNum(short n, int base)
730
0
{ return setNum(qlonglong(n), base); }
731
inline QByteArray &QByteArray::setNum(ushort n, int base)
732
0
{ return setNum(qulonglong(n), base); }
733
inline QByteArray &QByteArray::setNum(int n, int base)
734
0
{ return setNum(qlonglong(n), base); }
735
inline QByteArray &QByteArray::setNum(uint n, int base)
736
0
{ return setNum(qulonglong(n), base); }
737
inline QByteArray &QByteArray::setNum(long n, int base)
738
0
{ return setNum(qlonglong(n), base); }
739
inline QByteArray &QByteArray::setNum(ulong n, int base)
740
0
{ return setNum(qulonglong(n), base); }
741
inline QByteArray &QByteArray::setNum(float n, char format, int precision)
742
0
{ return setNum(double(n), format, precision); }
743
744
#if QT_CORE_INLINE_IMPL_SINCE(6, 4)
745
QT_CORE_CONSTEXPR_INLINE_SINCE(6, 4)
746
bool QByteArray::isNull() const noexcept
747
{
748
    return d.isNull();
749
}
750
#endif
751
#if QT_CORE_INLINE_IMPL_SINCE(6, 8)
752
qsizetype QByteArray::indexOf(char ch, qsizetype from) const
753
{
754
    return qToByteArrayViewIgnoringNull(*this).indexOf(ch, from);
755
}
756
qsizetype QByteArray::lastIndexOf(char ch, qsizetype from) const
757
{
758
    return qToByteArrayViewIgnoringNull(*this).lastIndexOf(ch, from);
759
}
760
#endif
761
762
#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
763
Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QByteArray &);
764
Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QByteArray &);
765
#endif
766
767
#ifndef QT_NO_COMPRESS
768
Q_CORE_EXPORT QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel = -1);
769
Q_CORE_EXPORT QByteArray qUncompress(const uchar* data, qsizetype nbytes);
770
inline QByteArray qCompress(const QByteArray& data, int compressionLevel = -1)
771
0
{ return qCompress(reinterpret_cast<const uchar *>(data.constData()), data.size(), compressionLevel); }
772
inline QByteArray qUncompress(const QByteArray& data)
773
0
{ return qUncompress(reinterpret_cast<const uchar*>(data.constData()), data.size()); }
774
#endif
775
776
Q_DECLARE_SHARED(QByteArray)
777
778
class QByteArray::FromBase64Result
779
{
780
public:
781
    QByteArray decoded;
782
    QByteArray::Base64DecodingStatus decodingStatus;
783
784
    void swap(QByteArray::FromBase64Result &other) noexcept
785
0
    {
786
0
        decoded.swap(other.decoded);
787
0
        std::swap(decodingStatus, other.decodingStatus);
788
0
    }
789
790
0
    explicit operator bool() const noexcept { return decodingStatus == QByteArray::Base64DecodingStatus::Ok; }
791
792
#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(Q_QDOC)
793
0
    QByteArray &operator*() & noexcept { return decoded; }
794
0
    const QByteArray &operator*() const & noexcept { return decoded; }
795
0
    QByteArray &&operator*() && noexcept { return std::move(decoded); }
796
#else
797
    QByteArray &operator*() noexcept { return decoded; }
798
    const QByteArray &operator*() const noexcept { return decoded; }
799
#endif
800
801
    friend inline bool operator==(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
802
0
    {
803
0
        if (lhs.decodingStatus != rhs.decodingStatus)
804
0
            return false;
805
0
806
0
        if (lhs.decodingStatus == QByteArray::Base64DecodingStatus::Ok && lhs.decoded != rhs.decoded)
807
0
            return false;
808
0
809
0
        return true;
810
0
    }
811
812
    friend inline bool operator!=(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
813
0
    {
814
0
        return !(lhs == rhs);
815
0
    }
816
};
817
818
Q_DECLARE_SHARED(QByteArray::FromBase64Result)
819
820
821
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QByteArray::FromBase64Result &key, size_t seed = 0) noexcept;
822
823
template <typename T>
824
qsizetype erase(QByteArray &ba, const T &t)
825
{
826
    return ba.removeIf_helper([&t](const auto &e) { return t == e; });
827
}
828
829
template <typename Predicate>
830
qsizetype erase_if(QByteArray &ba, Predicate pred)
831
{
832
    return ba.removeIf_helper(pred);
833
}
834
835
//
836
// QByteArrayView members that require QByteArray:
837
//
838
QByteArray QByteArrayView::toByteArray() const
839
{
840
    return QByteArray(*this);
841
}
842
843
namespace Qt {
844
inline namespace Literals {
845
inline namespace StringLiterals {
846
847
inline QByteArray operator""_ba(const char *str, size_t size) noexcept
848
0
{
849
0
    return QByteArray(QByteArrayData(nullptr, const_cast<char *>(str), qsizetype(size)));
850
0
}
851
852
} // StringLiterals
853
} // Literals
854
} // Qt
855
856
inline namespace QtLiterals {
857
#if QT_DEPRECATED_SINCE(6, 8)
858
859
QT_DEPRECATED_VERSION_X_6_8("Use _ba from Qt::StringLiterals namespace instead.")
860
inline QByteArray operator""_qba(const char *str, size_t size) noexcept
861
0
{
862
0
    return Qt::StringLiterals::operator""_ba(str, size);
863
0
}
864
865
#endif // QT_DEPRECATED_SINCE(6, 8)
866
} // QtLiterals
867
868
QT_END_NAMESPACE
869
870
#endif // QBYTEARRAY_H