1/****************************************************************************
2**
3** Copyright (C) 2020 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#ifndef QBYTEARRAY_H
42#define QBYTEARRAY_H
43
44#include <QtCore/qrefcount.h>
45#include <QtCore/qnamespace.h>
46#include <QtCore/qarraydata.h>
47#include <QtCore/qarraydatapointer.h>
48#include <QtCore/qcontainerfwd.h>
49#include <QtCore/qbytearrayalgorithms.h>
50#include <QtCore/qbytearrayview.h>
51
52#include <stdlib.h>
53#include <string.h>
54#include <stdarg.h>
55
56#include <string>
57#include <iterator>
58
59#ifndef QT5_NULL_STRINGS
60// Would ideally be off, but in practice breaks too much (Qt 6.0).
61#define QT5_NULL_STRINGS 1
62#endif
63
64#ifdef truncate
65#error qbytearray.h must be included before any header file that defines truncate
66#endif
67
68#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
69Q_FORWARD_DECLARE_CF_TYPE(CFData);
70Q_FORWARD_DECLARE_OBJC_CLASS(NSData);
71#endif
72
73QT_BEGIN_NAMESPACE
74
75class QString;
76class QDataStream;
77
78using QByteArrayData = QArrayDataPointer<char>;
79
80# define QByteArrayLiteral(str) \
81 (QByteArray(QByteArrayData(nullptr, const_cast<char *>(str), sizeof(str) - 1))) \
82 /**/
83
84class Q_CORE_EXPORT QByteArray
85{
86public:
87 using DataPointer = QByteArrayData;
88private:
89 typedef QTypedArrayData<char> Data;
90
91 DataPointer d;
92 static const char _empty;
93public:
94
95 enum Base64Option {
96 Base64Encoding = 0,
97 Base64UrlEncoding = 1,
98
99 KeepTrailingEquals = 0,
100 OmitTrailingEquals = 2,
101
102 IgnoreBase64DecodingErrors = 0,
103 AbortOnBase64DecodingErrors = 4,
104 };
105 Q_DECLARE_FLAGS(Base64Options, Base64Option)
106
107 enum class Base64DecodingStatus {
108 Ok,
109 IllegalInputLength,
110 IllegalCharacter,
111 IllegalPadding,
112 };
113
114 inline constexpr QByteArray() noexcept;
115 QByteArray(const char *, qsizetype size = -1);
116 QByteArray(qsizetype size, char c);
117 QByteArray(qsizetype size, Qt::Initialization);
118 inline QByteArray(const QByteArray &) noexcept;
119 inline ~QByteArray();
120
121 QByteArray &operator=(const QByteArray &) noexcept;
122 QByteArray &operator=(const char *str);
123 inline QByteArray(QByteArray && other) noexcept
124 { qSwap(d, other.d); }
125 QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QByteArray)
126 inline void swap(QByteArray &other) noexcept
127 { qSwap(d, other.d); }
128
129 inline bool isEmpty() const;
130 void resize(qsizetype size);
131
132 QByteArray &fill(char c, qsizetype size = -1);
133
134 inline qsizetype capacity() const;
135 inline void reserve(qsizetype size);
136 inline void squeeze();
137
138#ifndef QT_NO_CAST_FROM_BYTEARRAY
139 inline operator const char *() const;
140 inline operator const void *() const;
141#endif
142 inline char *data();
143 inline const char *data() const;
144 inline const char *constData() const;
145 inline void detach();
146 inline bool isDetached() const;
147 inline bool isSharedWith(const QByteArray &other) const
148 { return data() == other.data() && size() == other.size(); }
149 void clear();
150
151 inline char at(qsizetype i) const;
152 inline char operator[](qsizetype i) const;
153 [[nodiscard]] inline char &operator[](qsizetype i);
154 [[nodiscard]] char front() const { return at(0); }
155 [[nodiscard]] inline char &front();
156 [[nodiscard]] char back() const { return at(size() - 1); }
157 [[nodiscard]] inline char &back();
158
159 qsizetype indexOf(char c, qsizetype from = 0) const;
160 qsizetype indexOf(QByteArrayView bv, qsizetype from = 0) const
161 { return QtPrivate::findByteArray(qToByteArrayViewIgnoringNull(*this), from, bv); }
162
163 qsizetype lastIndexOf(char c, qsizetype from = -1) const;
164 qsizetype lastIndexOf(QByteArrayView bv) const
165 { return lastIndexOf(bv, size()); }
166 qsizetype lastIndexOf(QByteArrayView bv, qsizetype from) const
167 { return QtPrivate::lastIndexOf(qToByteArrayViewIgnoringNull(*this), from, bv); }
168
169 inline bool contains(char c) const;
170 inline bool contains(QByteArrayView bv) const;
171 qsizetype count(char c) const;
172 qsizetype count(QByteArrayView bv) const
173 { return QtPrivate::count(qToByteArrayViewIgnoringNull(*this), bv); }
174
175 inline int compare(QByteArrayView a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
176
177 [[nodiscard]] QByteArray left(qsizetype len) const;
178 [[nodiscard]] QByteArray right(qsizetype len) const;
179 [[nodiscard]] QByteArray mid(qsizetype index, qsizetype len = -1) const;
180
181 [[nodiscard]] QByteArray first(qsizetype n) const
182 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return QByteArray(data(), n); }
183 [[nodiscard]] QByteArray last(qsizetype n) const
184 { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return QByteArray(data() + size() - n, n); }
185 [[nodiscard]] QByteArray sliced(qsizetype pos) const
186 { Q_ASSERT(pos >= 0); Q_ASSERT(pos <= size()); return QByteArray(data() + pos, size() - pos); }
187 [[nodiscard]] QByteArray sliced(qsizetype pos, qsizetype n) const
188 { Q_ASSERT(pos >= 0); Q_ASSERT(n >= 0); Q_ASSERT(size_t(pos) + size_t(n) <= size_t(size())); return QByteArray(data() + pos, n); }
189 [[nodiscard]] QByteArray chopped(qsizetype len) const
190 { Q_ASSERT(len >= 0); Q_ASSERT(len <= size()); return first(size() - len); }
191
192 bool startsWith(QByteArrayView bv) const
193 { return QtPrivate::startsWith(qToByteArrayViewIgnoringNull(*this), bv); }
194 bool startsWith(char c) const { return size() > 0 && front() == c; }
195
196 bool endsWith(char c) const { return size() > 0 && back() == c; }
197 bool endsWith(QByteArrayView bv) const
198 { return QtPrivate::endsWith(qToByteArrayViewIgnoringNull(*this), bv); }
199
200 bool isUpper() const;
201 bool isLower() const;
202
203 void truncate(qsizetype pos);
204 void chop(qsizetype n);
205
206#if !defined(Q_CLANG_QDOC)
207 [[nodiscard]] QByteArray toLower() const &
208 { return toLower_helper(*this); }
209 [[nodiscard]] QByteArray toLower() &&
210 { return toLower_helper(*this); }
211 [[nodiscard]] QByteArray toUpper() const &
212 { return toUpper_helper(*this); }
213 [[nodiscard]] QByteArray toUpper() &&
214 { return toUpper_helper(*this); }
215 [[nodiscard]] QByteArray trimmed() const &
216 { return trimmed_helper(*this); }
217 [[nodiscard]] QByteArray trimmed() &&
218 { return trimmed_helper(*this); }
219 [[nodiscard]] QByteArray simplified() const &
220 { return simplified_helper(*this); }
221 [[nodiscard]] QByteArray simplified() &&
222 { return simplified_helper(*this); }
223#else
224 [[nodiscard]] QByteArray toLower() const;
225 [[nodiscard]] QByteArray toUpper() const;
226 [[nodiscard]] QByteArray trimmed() const;
227 [[nodiscard]] QByteArray simplified() const;
228#endif
229
230 [[nodiscard]] QByteArray leftJustified(qsizetype width, char fill = ' ', bool truncate = false) const;
231 [[nodiscard]] QByteArray rightJustified(qsizetype width, char fill = ' ', bool truncate = false) const;
232
233 QByteArray &prepend(char c)
234 { return insert(0, QByteArrayView(&c, 1)); }
235 inline QByteArray &prepend(qsizetype count, char c);
236 QByteArray &prepend(const char *s)
237 { return insert(0, QByteArrayView(s, qsizetype(qstrlen(s)))); }
238 QByteArray &prepend(const char *s, qsizetype len)
239 { return insert(0, QByteArrayView(s, len)); }
240 QByteArray &prepend(const QByteArray &a);
241 QByteArray &prepend(QByteArrayView a)
242 { return insert(0, a); }
243
244 QByteArray &append(char c);
245 inline QByteArray &append(qsizetype count, char c);
246 QByteArray &append(const char *s)
247 { return append(QByteArrayView(s, qsizetype(qstrlen(s)))); }
248 QByteArray &append(const char *s, qsizetype len)
249 { return append(QByteArrayView(s, len)); }
250 QByteArray &append(const QByteArray &a);
251 QByteArray &append(QByteArrayView a)
252 { return insert(size(), a); }
253
254 QByteArray &insert(qsizetype i, QByteArrayView data);
255 inline QByteArray &insert(qsizetype i, const char *s)
256 { return insert(i, QByteArrayView(s)); }
257 inline QByteArray &insert(qsizetype i, const QByteArray &data)
258 { return insert(i, QByteArrayView(data)); }
259 QByteArray &insert(qsizetype i, qsizetype count, char c);
260 QByteArray &insert(qsizetype i, char c)
261 { return insert(i, QByteArrayView(&c, 1)); }
262 QByteArray &insert(qsizetype i, const char *s, qsizetype len)
263 { return insert(i, QByteArrayView(s, len)); }
264
265 QByteArray &remove(qsizetype index, qsizetype len);
266 template <typename Predicate>
267 QByteArray &removeIf(Predicate pred)
268 {
269 QtPrivate::sequential_erase_if(*this, pred);
270 return *this;
271 }
272
273 QByteArray &replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
274 { return replace(index, len, QByteArrayView(s, alen)); }
275 QByteArray &replace(qsizetype index, qsizetype len, QByteArrayView s);
276 QByteArray &replace(char before, QByteArrayView after)
277 { return replace(QByteArrayView(&before, 1), after); }
278 QByteArray &replace(const char *before, qsizetype bsize, const char *after, qsizetype asize)
279 { return replace(QByteArrayView(before, bsize), QByteArrayView(after, asize)); }
280 QByteArray &replace(QByteArrayView before, QByteArrayView after);
281 QByteArray &replace(char before, char after);
282
283 QByteArray &operator+=(char c)
284 { return append(c); }
285 QByteArray &operator+=(const char *s)
286 { return append(s); }
287 QByteArray &operator+=(const QByteArray &a)
288 { return append(a); }
289 QByteArray &operator+=(QByteArrayView a)
290 { return append(a); }
291
292 QList<QByteArray> split(char sep) const;
293
294 [[nodiscard]] QByteArray repeated(qsizetype times) const;
295
296#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
297 QT_ASCII_CAST_WARN inline bool operator==(const QString &s2) const;
298 QT_ASCII_CAST_WARN inline bool operator!=(const QString &s2) const;
299 QT_ASCII_CAST_WARN inline bool operator<(const QString &s2) const;
300 QT_ASCII_CAST_WARN inline bool operator>(const QString &s2) const;
301 QT_ASCII_CAST_WARN inline bool operator<=(const QString &s2) const;
302 QT_ASCII_CAST_WARN inline bool operator>=(const QString &s2) const;
303#endif
304 friend inline bool operator==(const QByteArray &a1, const QByteArray &a2) noexcept
305 { return QByteArrayView(a1) == QByteArrayView(a2); }
306 friend inline bool operator==(const QByteArray &a1, const char *a2) noexcept
307 { return a2 ? QtPrivate::compareMemory(a1, a2) == 0 : a1.isEmpty(); }
308 friend inline bool operator==(const char *a1, const QByteArray &a2) noexcept
309 { return a1 ? QtPrivate::compareMemory(a1, a2) == 0 : a2.isEmpty(); }
310 friend inline bool operator!=(const QByteArray &a1, const QByteArray &a2) noexcept
311 { return !(a1==a2); }
312 friend inline bool operator!=(const QByteArray &a1, const char *a2) noexcept
313 { return a2 ? QtPrivate::compareMemory(a1, a2) != 0 : !a1.isEmpty(); }
314 friend inline bool operator!=(const char *a1, const QByteArray &a2) noexcept
315 { return a1 ? QtPrivate::compareMemory(a1, a2) != 0 : !a2.isEmpty(); }
316 friend inline bool operator<(const QByteArray &a1, const QByteArray &a2) noexcept
317 { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) < 0; }
318 friend inline bool operator<(const QByteArray &a1, const char *a2) noexcept
319 { return QtPrivate::compareMemory(a1, a2) < 0; }
320 friend inline bool operator<(const char *a1, const QByteArray &a2) noexcept
321 { return QtPrivate::compareMemory(a1, a2) < 0; }
322 friend inline bool operator<=(const QByteArray &a1, const QByteArray &a2) noexcept
323 { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) <= 0; }
324 friend inline bool operator<=(const QByteArray &a1, const char *a2) noexcept
325 { return QtPrivate::compareMemory(a1, a2) <= 0; }
326 friend inline bool operator<=(const char *a1, const QByteArray &a2) noexcept
327 { return QtPrivate::compareMemory(a1, a2) <= 0; }
328 friend inline bool operator>(const QByteArray &a1, const QByteArray &a2) noexcept
329 { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) > 0; }
330 friend inline bool operator>(const QByteArray &a1, const char *a2) noexcept
331 { return QtPrivate::compareMemory(a1, a2) > 0; }
332 friend inline bool operator>(const char *a1, const QByteArray &a2) noexcept
333 { return QtPrivate::compareMemory(a1, a2) > 0; }
334 friend inline bool operator>=(const QByteArray &a1, const QByteArray &a2) noexcept
335 { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) >= 0; }
336 friend inline bool operator>=(const QByteArray &a1, const char *a2) noexcept
337 { return QtPrivate::compareMemory(a1, a2) >= 0; }
338 friend inline bool operator>=(const char *a1, const QByteArray &a2) noexcept
339 { return QtPrivate::compareMemory(a1, a2) >= 0; }
340
341 // Check isEmpty() instead of isNull() for backwards compatibility.
342 friend inline bool operator==(const QByteArray &a1, std::nullptr_t) noexcept { return a1.isEmpty(); }
343 friend inline bool operator!=(const QByteArray &a1, std::nullptr_t) noexcept { return !a1.isEmpty(); }
344 friend inline bool operator< (const QByteArray & , std::nullptr_t) noexcept { return false; }
345 friend inline bool operator> (const QByteArray &a1, std::nullptr_t) noexcept { return !a1.isEmpty(); }
346 friend inline bool operator<=(const QByteArray &a1, std::nullptr_t) noexcept { return a1.isEmpty(); }
347 friend inline bool operator>=(const QByteArray & , std::nullptr_t) noexcept { return true; }
348
349 friend inline bool operator==(std::nullptr_t, const QByteArray &a2) noexcept { return a2 == nullptr; }
350 friend inline bool operator!=(std::nullptr_t, const QByteArray &a2) noexcept { return a2 != nullptr; }
351 friend inline bool operator< (std::nullptr_t, const QByteArray &a2) noexcept { return a2 > nullptr; }
352 friend inline bool operator> (std::nullptr_t, const QByteArray &a2) noexcept { return a2 < nullptr; }
353 friend inline bool operator<=(std::nullptr_t, const QByteArray &a2) noexcept { return a2 >= nullptr; }
354 friend inline bool operator>=(std::nullptr_t, const QByteArray &a2) noexcept { return a2 <= nullptr; }
355
356 short toShort(bool *ok = nullptr, int base = 10) const;
357 ushort toUShort(bool *ok = nullptr, int base = 10) const;
358 int toInt(bool *ok = nullptr, int base = 10) const;
359 uint toUInt(bool *ok = nullptr, int base = 10) const;
360 long toLong(bool *ok = nullptr, int base = 10) const;
361 ulong toULong(bool *ok = nullptr, int base = 10) const;
362 qlonglong toLongLong(bool *ok = nullptr, int base = 10) const;
363 qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;
364 float toFloat(bool *ok = nullptr) const;
365 double toDouble(bool *ok = nullptr) const;
366 QByteArray toBase64(Base64Options options = Base64Encoding) const;
367 QByteArray toHex(char separator = '\0') const;
368 QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
369 const QByteArray &include = QByteArray(),
370 char percent = '%') const;
371
372 inline QByteArray &setNum(short, int base = 10);
373 inline QByteArray &setNum(ushort, int base = 10);
374 inline QByteArray &setNum(int, int base = 10);
375 inline QByteArray &setNum(uint, int base = 10);
376 inline QByteArray &setNum(long, int base = 10);
377 inline QByteArray &setNum(ulong, int base = 10);
378 QByteArray &setNum(qlonglong, int base = 10);
379 QByteArray &setNum(qulonglong, int base = 10);
380 inline QByteArray &setNum(float, char format = 'g', int precision = 6);
381 QByteArray &setNum(double, char format = 'g', int precision = 6);
382 QByteArray &setRawData(const char *a, qsizetype n);
383
384 [[nodiscard]] static QByteArray number(int, int base = 10);
385 [[nodiscard]] static QByteArray number(uint, int base = 10);
386 [[nodiscard]] static QByteArray number(long, int base = 10);
387 [[nodiscard]] static QByteArray number(ulong, int base = 10);
388 [[nodiscard]] static QByteArray number(qlonglong, int base = 10);
389 [[nodiscard]] static QByteArray number(qulonglong, int base = 10);
390 [[nodiscard]] static QByteArray number(double, char format = 'g', int precision = 6);
391 [[nodiscard]] static QByteArray fromRawData(const char *data, qsizetype size)
392 {
393 return QByteArray(DataPointer(nullptr, const_cast<char *>(data), size));
394 }
395
396 class FromBase64Result;
397 [[nodiscard]] static FromBase64Result fromBase64Encoding(QByteArray &&base64, Base64Options options = Base64Encoding);
398 [[nodiscard]] static FromBase64Result fromBase64Encoding(const QByteArray &base64, Base64Options options = Base64Encoding);
399 [[nodiscard]] static QByteArray fromBase64(const QByteArray &base64, Base64Options options = Base64Encoding);
400 [[nodiscard]] static QByteArray fromHex(const QByteArray &hexEncoded);
401 [[nodiscard]] static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
402
403#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
404 static QByteArray fromCFData(CFDataRef data);
405 static QByteArray fromRawCFData(CFDataRef data);
406 CFDataRef toCFData() const Q_DECL_CF_RETURNS_RETAINED;
407 CFDataRef toRawCFData() const Q_DECL_CF_RETURNS_RETAINED;
408 static QByteArray fromNSData(const NSData *data);
409 static QByteArray fromRawNSData(const NSData *data);
410 NSData *toNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
411 NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
412#endif
413
414 typedef char *iterator;
415 typedef const char *const_iterator;
416 typedef iterator Iterator;
417 typedef const_iterator ConstIterator;
418 typedef std::reverse_iterator<iterator> reverse_iterator;
419 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
420 inline iterator begin();
421 inline const_iterator begin() const;
422 inline const_iterator cbegin() const;
423 inline const_iterator constBegin() const;
424 inline iterator end();
425 inline const_iterator end() const;
426 inline const_iterator cend() const;
427 inline const_iterator constEnd() const;
428 reverse_iterator rbegin() { return reverse_iterator(end()); }
429 reverse_iterator rend() { return reverse_iterator(begin()); }
430 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
431 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
432 const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
433 const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
434
435 // stl compatibility
436 typedef qsizetype size_type;
437 typedef qptrdiff difference_type;
438 typedef const char & const_reference;
439 typedef char & reference;
440 typedef char *pointer;
441 typedef const char *const_pointer;
442 typedef char value_type;
443 void push_back(char c)
444 { append(c); }
445 void push_back(const char *s)
446 { append(s); }
447 void push_back(const QByteArray &a)
448 { append(a); }
449 void push_back(QByteArrayView a)
450 { append(a); }
451 void push_front(char c)
452 { prepend(c); }
453 void push_front(const char *c)
454 { prepend(c); }
455 void push_front(const QByteArray &a)
456 { prepend(a); }
457 void push_front(QByteArrayView a)
458 { prepend(a); }
459 void shrink_to_fit() { squeeze(); }
460 iterator erase(const_iterator first, const_iterator last);
461
462 static inline QByteArray fromStdString(const std::string &s);
463 inline std::string toStdString() const;
464
465 inline qsizetype size() const { return d->size; }
466 inline qsizetype count() const { return size(); }
467 inline qsizetype length() const { return size(); }
468 bool isNull() const;
469
470 inline DataPointer &data_ptr() { return d; }
471 explicit inline QByteArray(const DataPointer &dd)
472 : d(dd)
473 {
474 }
475
476private:
477 void reallocData(qsizetype alloc, QArrayData::AllocationOption option);
478 void reallocGrowData(qsizetype n);
479 void expand(qsizetype i);
480 QByteArray nulTerminated() const;
481
482 static QByteArray toLower_helper(const QByteArray &a);
483 static QByteArray toLower_helper(QByteArray &a);
484 static QByteArray toUpper_helper(const QByteArray &a);
485 static QByteArray toUpper_helper(QByteArray &a);
486 static QByteArray trimmed_helper(const QByteArray &a);
487 static QByteArray trimmed_helper(QByteArray &a);
488 static QByteArray simplified_helper(const QByteArray &a);
489 static QByteArray simplified_helper(QByteArray &a);
490
491 friend class QString;
492 friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, qsizetype nbytes);
493};
494
495Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)
496
497inline constexpr QByteArray::QByteArray() noexcept {}
498inline QByteArray::~QByteArray() {}
499
500inline char QByteArray::at(qsizetype i) const
501{ Q_ASSERT(size_t(i) < size_t(size())); return d.data()[i]; }
502inline char QByteArray::operator[](qsizetype i) const
503{ Q_ASSERT(size_t(i) < size_t(size())); return d.data()[i]; }
504
505inline bool QByteArray::isEmpty() const
506{ return size() == 0; }
507#ifndef QT_NO_CAST_FROM_BYTEARRAY
508inline QByteArray::operator const char *() const
509{ return data(); }
510inline QByteArray::operator const void *() const
511{ return data(); }
512#endif
513inline char *QByteArray::data()
514{
515 detach();
516 Q_ASSERT(d.data());
517 return d.data();
518}
519inline const char *QByteArray::data() const
520{
521#if QT5_NULL_STRINGS == 1
522 return d.data() ? d.data() : &_empty;
523#else
524 return d.data();
525#endif
526}
527inline const char *QByteArray::constData() const
528{ return data(); }
529inline void QByteArray::detach()
530{ if (d->needsDetach()) reallocData(size(), QArrayData::KeepSize); }
531inline bool QByteArray::isDetached() const
532{ return !d->isShared(); }
533inline QByteArray::QByteArray(const QByteArray &a) noexcept : d(a.d)
534{}
535
536inline qsizetype QByteArray::capacity() const { return qsizetype(d->constAllocatedCapacity()); }
537
538inline void QByteArray::reserve(qsizetype asize)
539{
540 if (d->needsDetach() || asize > capacity() - d->freeSpaceAtBegin())
541 reallocData(qMax(size(), asize), QArrayData::KeepSize);
542 if (d->constAllocatedCapacity())
543 d->setFlag(Data::CapacityReserved);
544}
545
546inline void QByteArray::squeeze()
547{
548 if (!d.isMutable())
549 return;
550 if (d->needsDetach() || size() < capacity())
551 reallocData(size(), QArrayData::KeepSize);
552 if (d->constAllocatedCapacity())
553 d->clearFlag(Data::CapacityReserved);
554}
555
556inline char &QByteArray::operator[](qsizetype i)
557{ Q_ASSERT(i >= 0 && i < size()); return data()[i]; }
558inline char &QByteArray::front() { return operator[](0); }
559inline char &QByteArray::back() { return operator[](size() - 1); }
560inline QByteArray::iterator QByteArray::begin()
561{ return data(); }
562inline QByteArray::const_iterator QByteArray::begin() const
563{ return data(); }
564inline QByteArray::const_iterator QByteArray::cbegin() const
565{ return data(); }
566inline QByteArray::const_iterator QByteArray::constBegin() const
567{ return data(); }
568inline QByteArray::iterator QByteArray::end()
569{ return data() + size(); }
570inline QByteArray::const_iterator QByteArray::end() const
571{ return data() + size(); }
572inline QByteArray::const_iterator QByteArray::cend() const
573{ return data() + size(); }
574inline QByteArray::const_iterator QByteArray::constEnd() const
575{ return data() + size(); }
576inline QByteArray &QByteArray::append(qsizetype n, char ch)
577{ return insert(size(), n, ch); }
578inline QByteArray &QByteArray::prepend(qsizetype n, char ch)
579{ return insert(0, n, ch); }
580inline bool QByteArray::contains(char c) const
581{ return indexOf(c) != -1; }
582inline bool QByteArray::contains(QByteArrayView bv) const
583{ return indexOf(bv) != -1; }
584inline int QByteArray::compare(QByteArrayView a, Qt::CaseSensitivity cs) const noexcept
585{
586 return cs == Qt::CaseSensitive ? QtPrivate::compareMemory(*this, a) :
587 qstrnicmp(data(), size(), a.data(), a.size());
588}
589#if !defined(QT_USE_QSTRINGBUILDER)
590inline const QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
591{ return QByteArray(a1) += a2; }
592inline const QByteArray operator+(const QByteArray &a1, const char *a2)
593{ return QByteArray(a1) += a2; }
594inline const QByteArray operator+(const QByteArray &a1, char a2)
595{ return QByteArray(a1) += a2; }
596inline const QByteArray operator+(const char *a1, const QByteArray &a2)
597{ return QByteArray(a1) += a2; }
598inline const QByteArray operator+(char a1, const QByteArray &a2)
599{ return QByteArray(&a1, 1) += a2; }
600#endif // QT_USE_QSTRINGBUILDER
601
602inline QByteArray &QByteArray::setNum(short n, int base)
603{ return setNum(qlonglong(n), base); }
604inline QByteArray &QByteArray::setNum(ushort n, int base)
605{ return setNum(qulonglong(n), base); }
606inline QByteArray &QByteArray::setNum(int n, int base)
607{ return setNum(qlonglong(n), base); }
608inline QByteArray &QByteArray::setNum(uint n, int base)
609{ return setNum(qulonglong(n), base); }
610inline QByteArray &QByteArray::setNum(long n, int base)
611{ return setNum(qlonglong(n), base); }
612inline QByteArray &QByteArray::setNum(ulong n, int base)
613{ return setNum(qulonglong(n), base); }
614inline QByteArray &QByteArray::setNum(float n, char format, int precision)
615{ return setNum(double(n), format, precision); }
616
617inline std::string QByteArray::toStdString() const
618{ return std::string(constData(), length()); }
619
620inline QByteArray QByteArray::fromStdString(const std::string &s)
621{ return QByteArray(s.data(), qsizetype(s.size())); }
622
623#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
624Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QByteArray &);
625Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QByteArray &);
626#endif
627
628#ifndef QT_NO_COMPRESS
629Q_CORE_EXPORT QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel = -1);
630Q_CORE_EXPORT QByteArray qUncompress(const uchar* data, qsizetype nbytes);
631inline QByteArray qCompress(const QByteArray& data, int compressionLevel = -1)
632{ return qCompress(reinterpret_cast<const uchar *>(data.constData()), data.size(), compressionLevel); }
633inline QByteArray qUncompress(const QByteArray& data)
634{ return qUncompress(reinterpret_cast<const uchar*>(data.constData()), data.size()); }
635#endif
636
637Q_DECLARE_SHARED(QByteArray)
638
639class QByteArray::FromBase64Result
640{
641public:
642 QByteArray decoded;
643 QByteArray::Base64DecodingStatus decodingStatus;
644
645 void swap(QByteArray::FromBase64Result &other) noexcept
646 {
647 qSwap(decoded, other.decoded);
648 qSwap(decodingStatus, other.decodingStatus);
649 }
650
651 explicit operator bool() const noexcept { return decodingStatus == QByteArray::Base64DecodingStatus::Ok; }
652
653#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(Q_QDOC)
654 QByteArray &operator*() & noexcept { return decoded; }
655 const QByteArray &operator*() const & noexcept { return decoded; }
656 QByteArray &&operator*() && noexcept { return std::move(decoded); }
657#else
658 QByteArray &operator*() noexcept { return decoded; }
659 const QByteArray &operator*() const noexcept { return decoded; }
660#endif
661
662 friend inline bool operator==(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
663 {
664 if (lhs.decodingStatus != rhs.decodingStatus)
665 return false;
666
667 if (lhs.decodingStatus == QByteArray::Base64DecodingStatus::Ok && lhs.decoded != rhs.decoded)
668 return false;
669
670 return true;
671 }
672
673 friend inline bool operator!=(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept
674 {
675 return !(lhs == rhs);
676 }
677};
678
679Q_DECLARE_SHARED(QByteArray::FromBase64Result)
680
681
682Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QByteArray::FromBase64Result &key, size_t seed = 0) noexcept;
683
684template <typename T>
685qsizetype erase(QByteArray &ba, const T &t)
686{
687 return QtPrivate::sequential_erase(ba, t);
688}
689
690template <typename Predicate>
691qsizetype erase_if(QByteArray &ba, Predicate pred)
692{
693 return QtPrivate::sequential_erase_if(ba, pred);
694}
695
696//
697// QByteArrayView members that require QByteArray:
698//
699QByteArray QByteArrayView::toByteArray() const
700{
701 return QByteArray(data(), size());
702}
703
704inline namespace QtLiterals {
705inline QByteArray operator"" _qba(const char *str, size_t size) noexcept
706{
707 return QByteArray(QByteArrayData(nullptr, const_cast<char *>(str), qsizetype(size)));
708}
709} // QtLiterals
710
711QT_END_NAMESPACE
712
713#endif // QBYTEARRAY_H
714

source code of qtbase/src/corelib/text/qbytearray.h