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