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) |
69 | Q_FORWARD_DECLARE_CF_TYPE(CFData); |
70 | Q_FORWARD_DECLARE_OBJC_CLASS(NSData); |
71 | #endif |
72 | |
73 | QT_BEGIN_NAMESPACE |
74 | |
75 | |
76 | /***************************************************************************** |
77 | Safe and portable C string functions; extensions to standard string.h |
78 | *****************************************************************************/ |
79 | |
80 | Q_CORE_EXPORT char *qstrdup(const char *); |
81 | |
82 | inline size_t qstrlen(const char *str) |
83 | { return str ? strlen(str) : 0; } |
84 | |
85 | inline size_t qstrnlen(const char *str, size_t maxlen) |
86 | { |
87 | size_t length = 0; |
88 | if (str) { |
89 | while (length < maxlen && *str++) |
90 | length++; |
91 | } |
92 | return length; |
93 | } |
94 | |
95 | Q_CORE_EXPORT char *qstrcpy(char *dst, const char *src); |
96 | Q_CORE_EXPORT char *qstrncpy(char *dst, const char *src, size_t len); |
97 | |
98 | Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2); |
99 | |
100 | inline int qstrncmp(const char *str1, const char *str2, size_t len) |
101 | { |
102 | return (str1 && str2) ? strncmp(str1, str2, len) |
103 | : (str1 ? 1 : (str2 ? -1 : 0)); |
104 | } |
105 | Q_CORE_EXPORT int qstricmp(const char *, const char *); |
106 | Q_CORE_EXPORT int qstrnicmp(const char *, const char *, size_t len); |
107 | Q_CORE_EXPORT int qstrnicmp(const char *, qsizetype, const char *, qsizetype = -1); |
108 | |
109 | // implemented in qvsnprintf.cpp |
110 | Q_CORE_EXPORT int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap); |
111 | Q_CORE_EXPORT int qsnprintf(char *str, size_t n, const char *fmt, ...); |
112 | |
113 | // qChecksum: Internet checksum |
114 | Q_CORE_EXPORT quint16 qChecksum(QByteArrayView data, Qt::ChecksumType standard = Qt::ChecksumIso3309); |
115 | |
116 | #if QT_DEPRECATED_SINCE(6, 0) |
117 | QT_DEPRECATED_VERSION_X_6_0("Use the QByteArrayView overload." ) |
118 | inline quint16 qChecksum(const char *s, qsizetype len, |
119 | Qt::ChecksumType standard = Qt::ChecksumIso3309) |
120 | { return qChecksum(QByteArrayView(s, len), standard); } |
121 | #endif |
122 | |
123 | class QString; |
124 | class QDataStream; |
125 | |
126 | using QByteArrayData = QArrayDataPointer<char>; |
127 | |
128 | # define QByteArrayLiteral(str) \ |
129 | (QByteArray(QByteArrayData(nullptr, const_cast<char *>(str), sizeof(str) - 1))) \ |
130 | /**/ |
131 | |
132 | class Q_CORE_EXPORT QByteArray |
133 | { |
134 | public: |
135 | using DataPointer = QByteArrayData; |
136 | private: |
137 | typedef QTypedArrayData<char> Data; |
138 | |
139 | DataPointer d; |
140 | static const char _empty; |
141 | public: |
142 | |
143 | enum Base64Option { |
144 | Base64Encoding = 0, |
145 | Base64UrlEncoding = 1, |
146 | |
147 | KeepTrailingEquals = 0, |
148 | OmitTrailingEquals = 2, |
149 | |
150 | IgnoreBase64DecodingErrors = 0, |
151 | AbortOnBase64DecodingErrors = 4, |
152 | }; |
153 | Q_DECLARE_FLAGS(Base64Options, Base64Option) |
154 | |
155 | enum class Base64DecodingStatus { |
156 | Ok, |
157 | IllegalInputLength, |
158 | IllegalCharacter, |
159 | IllegalPadding, |
160 | }; |
161 | |
162 | inline constexpr QByteArray() noexcept; |
163 | QByteArray(const char *, qsizetype size = -1); |
164 | QByteArray(qsizetype size, char c); |
165 | QByteArray(qsizetype size, Qt::Initialization); |
166 | inline QByteArray(const QByteArray &) noexcept; |
167 | inline ~QByteArray(); |
168 | |
169 | QByteArray &operator=(const QByteArray &) noexcept; |
170 | QByteArray &operator=(const char *str); |
171 | inline QByteArray(QByteArray && other) noexcept |
172 | { qSwap(d, other.d); } |
173 | QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QByteArray) |
174 | inline void swap(QByteArray &other) noexcept |
175 | { qSwap(d, other.d); } |
176 | |
177 | inline bool isEmpty() const; |
178 | void resize(qsizetype size); |
179 | |
180 | QByteArray &fill(char c, qsizetype size = -1); |
181 | |
182 | inline qsizetype capacity() const; |
183 | inline void reserve(qsizetype size); |
184 | inline void squeeze(); |
185 | |
186 | #ifndef QT_NO_CAST_FROM_BYTEARRAY |
187 | inline operator const char *() const; |
188 | inline operator const void *() const; |
189 | #endif |
190 | inline char *data(); |
191 | inline const char *data() const; |
192 | inline const char *constData() const; |
193 | inline void detach(); |
194 | inline bool isDetached() const; |
195 | inline bool isSharedWith(const QByteArray &other) const |
196 | { return data() == other.data() && size() == other.size(); } |
197 | void clear(); |
198 | |
199 | inline char at(qsizetype i) const; |
200 | inline char operator[](qsizetype i) const; |
201 | [[nodiscard]] inline char &operator[](qsizetype i); |
202 | [[nodiscard]] char front() const { return at(0); } |
203 | [[nodiscard]] inline char &front(); |
204 | [[nodiscard]] char back() const { return at(size() - 1); } |
205 | [[nodiscard]] inline char &back(); |
206 | |
207 | qsizetype indexOf(char c, qsizetype from = 0) const; |
208 | qsizetype indexOf(QByteArrayView bv, qsizetype from = 0) const |
209 | { return QtPrivate::findByteArray(qToByteArrayViewIgnoringNull(*this), from, bv); } |
210 | |
211 | qsizetype lastIndexOf(char c, qsizetype from = -1) const; |
212 | qsizetype lastIndexOf(QByteArrayView bv, qsizetype from = -1) const |
213 | { return QtPrivate::lastIndexOf(qToByteArrayViewIgnoringNull(*this), from, bv); } |
214 | |
215 | inline bool contains(char c) const; |
216 | inline bool contains(QByteArrayView bv) const; |
217 | qsizetype count(char c) const; |
218 | qsizetype count(QByteArrayView bv) const |
219 | { return QtPrivate::count(qToByteArrayViewIgnoringNull(*this), bv); } |
220 | |
221 | inline int compare(QByteArrayView a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept; |
222 | |
223 | [[nodiscard]] QByteArray left(qsizetype len) const; |
224 | [[nodiscard]] QByteArray right(qsizetype len) const; |
225 | [[nodiscard]] QByteArray mid(qsizetype index, qsizetype len = -1) const; |
226 | |
227 | [[nodiscard]] QByteArray first(qsizetype n) const |
228 | { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return QByteArray(data(), n); } |
229 | [[nodiscard]] QByteArray last(qsizetype n) const |
230 | { Q_ASSERT(n >= 0); Q_ASSERT(n <= size()); return QByteArray(data() + size() - n, n); } |
231 | [[nodiscard]] QByteArray sliced(qsizetype pos) const |
232 | { Q_ASSERT(pos >= 0); Q_ASSERT(pos <= size()); return QByteArray(data() + pos, size() - pos); } |
233 | [[nodiscard]] QByteArray sliced(qsizetype pos, qsizetype n) const |
234 | { Q_ASSERT(pos >= 0); Q_ASSERT(n >= 0); Q_ASSERT(size_t(pos) + size_t(n) <= size_t(size())); return QByteArray(data() + pos, n); } |
235 | [[nodiscard]] QByteArray chopped(qsizetype len) const |
236 | { Q_ASSERT(len >= 0); Q_ASSERT(len <= size()); return first(size() - len); } |
237 | |
238 | bool startsWith(QByteArrayView bv) const |
239 | { return QtPrivate::startsWith(qToByteArrayViewIgnoringNull(*this), bv); } |
240 | bool startsWith(char c) const { return size() > 0 && front() == c; } |
241 | |
242 | bool endsWith(char c) const { return size() > 0 && back() == c; } |
243 | bool endsWith(QByteArrayView bv) const |
244 | { return QtPrivate::endsWith(qToByteArrayViewIgnoringNull(*this), bv); } |
245 | |
246 | bool isUpper() const; |
247 | bool isLower() const; |
248 | |
249 | void truncate(qsizetype pos); |
250 | void chop(qsizetype n); |
251 | |
252 | #if !defined(Q_CLANG_QDOC) |
253 | [[nodiscard]] QByteArray toLower() const & |
254 | { return toLower_helper(*this); } |
255 | [[nodiscard]] QByteArray toLower() && |
256 | { return toLower_helper(*this); } |
257 | [[nodiscard]] QByteArray toUpper() const & |
258 | { return toUpper_helper(*this); } |
259 | [[nodiscard]] QByteArray toUpper() && |
260 | { return toUpper_helper(*this); } |
261 | [[nodiscard]] QByteArray trimmed() const & |
262 | { return trimmed_helper(*this); } |
263 | [[nodiscard]] QByteArray trimmed() && |
264 | { return trimmed_helper(*this); } |
265 | [[nodiscard]] QByteArray simplified() const & |
266 | { return simplified_helper(*this); } |
267 | [[nodiscard]] QByteArray simplified() && |
268 | { return simplified_helper(*this); } |
269 | #else |
270 | [[nodiscard]] QByteArray toLower() const; |
271 | [[nodiscard]] QByteArray toUpper() const; |
272 | [[nodiscard]] QByteArray trimmed() const; |
273 | [[nodiscard]] QByteArray simplified() const; |
274 | #endif |
275 | |
276 | [[nodiscard]] QByteArray leftJustified(qsizetype width, char fill = ' ', bool truncate = false) const; |
277 | [[nodiscard]] QByteArray rightJustified(qsizetype width, char fill = ' ', bool truncate = false) const; |
278 | |
279 | QByteArray &prepend(char c) |
280 | { return insert(0, QByteArrayView(&c, 1)); } |
281 | inline QByteArray &prepend(qsizetype count, char c); |
282 | QByteArray &prepend(const char *s) |
283 | { return insert(0, QByteArrayView(s, qsizetype(qstrlen(s)))); } |
284 | QByteArray &prepend(const char *s, qsizetype len) |
285 | { return insert(0, QByteArrayView(s, len)); } |
286 | QByteArray &prepend(const QByteArray &a) |
287 | { return insert(0, a); } |
288 | QByteArray &prepend(QByteArrayView a) |
289 | { return insert(0, a); } |
290 | |
291 | QByteArray &append(char c); |
292 | inline QByteArray &append(qsizetype count, char c); |
293 | QByteArray &append(const char *s) |
294 | { return append(QByteArrayView(s, qsizetype(qstrlen(s)))); } |
295 | QByteArray &append(const char *s, qsizetype len) |
296 | { return append(QByteArrayView(s, len)); } |
297 | QByteArray &append(const QByteArray &a); |
298 | QByteArray &append(QByteArrayView a) |
299 | { return insert(size(), a); } |
300 | |
301 | QByteArray &insert(qsizetype i, QByteArrayView data); |
302 | QByteArray &insert(qsizetype i, qsizetype count, char c); |
303 | QByteArray &insert(qsizetype i, char c) |
304 | { return insert(i, QByteArrayView(&c, 1)); } |
305 | QByteArray &insert(qsizetype i, const char *s, qsizetype len) |
306 | { return insert(i, QByteArrayView(s, len)); } |
307 | |
308 | QByteArray &remove(qsizetype index, qsizetype len); |
309 | |
310 | QByteArray &replace(qsizetype index, qsizetype len, const char *s, qsizetype alen) |
311 | { return replace(index, len, QByteArrayView(s, alen)); } |
312 | QByteArray &replace(qsizetype index, qsizetype len, QByteArrayView s); |
313 | QByteArray &replace(char before, QByteArrayView after) |
314 | { return replace(QByteArrayView(&before, 1), after); } |
315 | QByteArray &replace(const char *before, qsizetype bsize, const char *after, qsizetype asize) |
316 | { return replace(QByteArrayView(before, bsize), QByteArrayView(after, asize)); } |
317 | QByteArray &replace(QByteArrayView before, QByteArrayView after); |
318 | QByteArray &replace(char before, char after); |
319 | |
320 | QByteArray &operator+=(char c) |
321 | { return append(c); } |
322 | QByteArray &operator+=(const char *s) |
323 | { return append(s); } |
324 | QByteArray &operator+=(const QByteArray &a) |
325 | { return append(a); } |
326 | QByteArray &operator+=(QByteArrayView a) |
327 | { return append(a); } |
328 | |
329 | QList<QByteArray> split(char sep) const; |
330 | |
331 | [[nodiscard]] QByteArray repeated(qsizetype times) const; |
332 | |
333 | #if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII) |
334 | QT_ASCII_CAST_WARN inline bool operator==(const QString &s2) const; |
335 | QT_ASCII_CAST_WARN inline bool operator!=(const QString &s2) const; |
336 | QT_ASCII_CAST_WARN inline bool operator<(const QString &s2) const; |
337 | QT_ASCII_CAST_WARN inline bool operator>(const QString &s2) const; |
338 | QT_ASCII_CAST_WARN inline bool operator<=(const QString &s2) const; |
339 | QT_ASCII_CAST_WARN inline bool operator>=(const QString &s2) const; |
340 | #endif |
341 | |
342 | short toShort(bool *ok = nullptr, int base = 10) const; |
343 | ushort toUShort(bool *ok = nullptr, int base = 10) const; |
344 | int toInt(bool *ok = nullptr, int base = 10) const; |
345 | uint toUInt(bool *ok = nullptr, int base = 10) const; |
346 | long toLong(bool *ok = nullptr, int base = 10) const; |
347 | ulong toULong(bool *ok = nullptr, int base = 10) const; |
348 | qlonglong toLongLong(bool *ok = nullptr, int base = 10) const; |
349 | qulonglong toULongLong(bool *ok = nullptr, int base = 10) const; |
350 | float toFloat(bool *ok = nullptr) const; |
351 | double toDouble(bool *ok = nullptr) const; |
352 | QByteArray toBase64(Base64Options options = Base64Encoding) const; |
353 | QByteArray toHex(char separator = '\0') const; |
354 | QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(), |
355 | const QByteArray &include = QByteArray(), |
356 | char percent = '%') const; |
357 | |
358 | inline QByteArray &setNum(short, int base = 10); |
359 | inline QByteArray &setNum(ushort, int base = 10); |
360 | inline QByteArray &setNum(int, int base = 10); |
361 | inline QByteArray &setNum(uint, int base = 10); |
362 | inline QByteArray &setNum(long, int base = 10); |
363 | inline QByteArray &setNum(ulong, int base = 10); |
364 | QByteArray &setNum(qlonglong, int base = 10); |
365 | QByteArray &setNum(qulonglong, int base = 10); |
366 | inline QByteArray &setNum(float, char f = 'g', int prec = 6); |
367 | QByteArray &setNum(double, char f = 'g', int prec = 6); |
368 | QByteArray &setRawData(const char *a, qsizetype n); |
369 | |
370 | [[nodiscard]] static QByteArray number(int, int base = 10); |
371 | [[nodiscard]] static QByteArray number(uint, int base = 10); |
372 | [[nodiscard]] static QByteArray number(long, int base = 10); |
373 | [[nodiscard]] static QByteArray number(ulong, int base = 10); |
374 | [[nodiscard]] static QByteArray number(qlonglong, int base = 10); |
375 | [[nodiscard]] static QByteArray number(qulonglong, int base = 10); |
376 | [[nodiscard]] static QByteArray number(double, char f = 'g', int prec = 6); |
377 | [[nodiscard]] static QByteArray fromRawData(const char *data, qsizetype size) |
378 | { |
379 | return QByteArray(DataPointer(nullptr, const_cast<char *>(data), size)); |
380 | } |
381 | |
382 | class FromBase64Result; |
383 | [[nodiscard]] static FromBase64Result fromBase64Encoding(QByteArray &&base64, Base64Options options = Base64Encoding); |
384 | [[nodiscard]] static FromBase64Result fromBase64Encoding(const QByteArray &base64, Base64Options options = Base64Encoding); |
385 | [[nodiscard]] static QByteArray fromBase64(const QByteArray &base64, Base64Options options = Base64Encoding); |
386 | [[nodiscard]] static QByteArray fromHex(const QByteArray &hexEncoded); |
387 | [[nodiscard]] static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%'); |
388 | |
389 | #if defined(Q_OS_DARWIN) || defined(Q_QDOC) |
390 | static QByteArray fromCFData(CFDataRef data); |
391 | static QByteArray fromRawCFData(CFDataRef data); |
392 | CFDataRef toCFData() const Q_DECL_CF_RETURNS_RETAINED; |
393 | CFDataRef toRawCFData() const Q_DECL_CF_RETURNS_RETAINED; |
394 | static QByteArray fromNSData(const NSData *data); |
395 | static QByteArray fromRawNSData(const NSData *data); |
396 | NSData *toNSData() const Q_DECL_NS_RETURNS_AUTORELEASED; |
397 | NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED; |
398 | #endif |
399 | |
400 | typedef char *iterator; |
401 | typedef const char *const_iterator; |
402 | typedef iterator Iterator; |
403 | typedef const_iterator ConstIterator; |
404 | typedef std::reverse_iterator<iterator> reverse_iterator; |
405 | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
406 | inline iterator begin(); |
407 | inline const_iterator begin() const; |
408 | inline const_iterator cbegin() const; |
409 | inline const_iterator constBegin() const; |
410 | inline iterator end(); |
411 | inline const_iterator end() const; |
412 | inline const_iterator cend() const; |
413 | inline const_iterator constEnd() const; |
414 | reverse_iterator rbegin() { return reverse_iterator(end()); } |
415 | reverse_iterator rend() { return reverse_iterator(begin()); } |
416 | const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } |
417 | const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } |
418 | const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); } |
419 | const_reverse_iterator crend() const { return const_reverse_iterator(begin()); } |
420 | |
421 | // stl compatibility |
422 | typedef qsizetype size_type; |
423 | typedef qptrdiff difference_type; |
424 | typedef const char & const_reference; |
425 | typedef char & reference; |
426 | typedef char *pointer; |
427 | typedef const char *const_pointer; |
428 | typedef char value_type; |
429 | void push_back(char c) |
430 | { append(c); } |
431 | void push_back(const char *s) |
432 | { append(s); } |
433 | void push_back(const QByteArray &a) |
434 | { append(a); } |
435 | void push_back(QByteArrayView a) |
436 | { append(a); } |
437 | void push_front(char c) |
438 | { prepend(c); } |
439 | void push_front(const char *c) |
440 | { prepend(c); } |
441 | void push_front(const QByteArray &a) |
442 | { prepend(a); } |
443 | void push_front(QByteArrayView a) |
444 | { prepend(a); } |
445 | void shrink_to_fit() { squeeze(); } |
446 | |
447 | static inline QByteArray fromStdString(const std::string &s); |
448 | inline std::string toStdString() const; |
449 | |
450 | inline qsizetype size() const { return d->size; } |
451 | inline qsizetype count() const { return size(); } |
452 | inline qsizetype length() const { return size(); } |
453 | bool isNull() const; |
454 | |
455 | inline DataPointer &data_ptr() { return d; } |
456 | explicit inline QByteArray(const DataPointer &dd) |
457 | : d(dd) |
458 | { |
459 | } |
460 | |
461 | private: |
462 | void reallocData(qsizetype alloc, Data::ArrayOptions options); |
463 | void reallocGrowData(qsizetype alloc, Data::ArrayOptions options); |
464 | void expand(qsizetype i); |
465 | QByteArray nulTerminated() const; |
466 | |
467 | static QByteArray toLower_helper(const QByteArray &a); |
468 | static QByteArray toLower_helper(QByteArray &a); |
469 | static QByteArray toUpper_helper(const QByteArray &a); |
470 | static QByteArray toUpper_helper(QByteArray &a); |
471 | static QByteArray trimmed_helper(const QByteArray &a); |
472 | static QByteArray trimmed_helper(QByteArray &a); |
473 | static QByteArray simplified_helper(const QByteArray &a); |
474 | static QByteArray simplified_helper(QByteArray &a); |
475 | |
476 | friend class QString; |
477 | friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, qsizetype nbytes); |
478 | }; |
479 | |
480 | Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options) |
481 | |
482 | inline constexpr QByteArray::QByteArray() noexcept {} |
483 | inline QByteArray::~QByteArray() {} |
484 | |
485 | inline char QByteArray::at(qsizetype i) const |
486 | { Q_ASSERT(size_t(i) < size_t(size())); return d.data()[i]; } |
487 | inline char QByteArray::operator[](qsizetype i) const |
488 | { Q_ASSERT(size_t(i) < size_t(size())); return d.data()[i]; } |
489 | |
490 | inline bool QByteArray::isEmpty() const |
491 | { return size() == 0; } |
492 | #ifndef QT_NO_CAST_FROM_BYTEARRAY |
493 | inline QByteArray::operator const char *() const |
494 | { return data(); } |
495 | inline QByteArray::operator const void *() const |
496 | { return data(); } |
497 | #endif |
498 | inline char *QByteArray::data() |
499 | { |
500 | detach(); |
501 | Q_ASSERT(d.data()); |
502 | return d.data(); |
503 | } |
504 | inline const char *QByteArray::data() const |
505 | { |
506 | #if QT5_NULL_STRINGS == 1 |
507 | return d.data() ? d.data() : &_empty; |
508 | #else |
509 | return d.data(); |
510 | #endif |
511 | } |
512 | inline const char *QByteArray::constData() const |
513 | { return data(); } |
514 | inline void QByteArray::detach() |
515 | { if (d->needsDetach()) reallocData(size(), d->detachFlags()); } |
516 | inline bool QByteArray::isDetached() const |
517 | { return !d->isShared(); } |
518 | inline QByteArray::QByteArray(const QByteArray &a) noexcept : d(a.d) |
519 | {} |
520 | |
521 | inline qsizetype QByteArray::capacity() const { return qsizetype(d->constAllocatedCapacity()); } |
522 | |
523 | inline void QByteArray::reserve(qsizetype asize) |
524 | { |
525 | if (d->needsDetach() || asize > capacity() - d->freeSpaceAtBegin()) { |
526 | reallocData(qMax(size(), asize), d->detachFlags() | Data::CapacityReserved); |
527 | } else { |
528 | d->setFlag(Data::CapacityReserved); |
529 | } |
530 | } |
531 | |
532 | inline void QByteArray::squeeze() |
533 | { |
534 | if (!d.isMutable()) |
535 | return; |
536 | if (d->needsDetach() || size() < capacity()) { |
537 | reallocData(size(), d->detachFlags() & ~Data::CapacityReserved); |
538 | } else { |
539 | d->clearFlag(Data::CapacityReserved); |
540 | } |
541 | } |
542 | |
543 | inline char &QByteArray::operator[](qsizetype i) |
544 | { Q_ASSERT(i >= 0 && i < size()); return data()[i]; } |
545 | inline char &QByteArray::front() { return operator[](0); } |
546 | inline char &QByteArray::back() { return operator[](size() - 1); } |
547 | inline QByteArray::iterator QByteArray::begin() |
548 | { return data(); } |
549 | inline QByteArray::const_iterator QByteArray::begin() const |
550 | { return data(); } |
551 | inline QByteArray::const_iterator QByteArray::cbegin() const |
552 | { return data(); } |
553 | inline QByteArray::const_iterator QByteArray::constBegin() const |
554 | { return data(); } |
555 | inline QByteArray::iterator QByteArray::end() |
556 | { return data() + size(); } |
557 | inline QByteArray::const_iterator QByteArray::end() const |
558 | { return data() + size(); } |
559 | inline QByteArray::const_iterator QByteArray::cend() const |
560 | { return data() + size(); } |
561 | inline QByteArray::const_iterator QByteArray::constEnd() const |
562 | { return data() + size(); } |
563 | inline QByteArray &QByteArray::append(qsizetype n, char ch) |
564 | { return insert(size(), n, ch); } |
565 | inline QByteArray &QByteArray::prepend(qsizetype n, char ch) |
566 | { return insert(0, n, ch); } |
567 | inline bool QByteArray::contains(char c) const |
568 | { return indexOf(c) != -1; } |
569 | inline bool QByteArray::contains(QByteArrayView bv) const |
570 | { return indexOf(bv) != -1; } |
571 | inline int QByteArray::compare(QByteArrayView a, Qt::CaseSensitivity cs) const noexcept |
572 | { |
573 | return cs == Qt::CaseSensitive ? QtPrivate::compareMemory(*this, a) : |
574 | qstrnicmp(data(), size(), a.data(), a.size()); |
575 | } |
576 | inline bool operator==(const QByteArray &a1, const QByteArray &a2) noexcept |
577 | { return QByteArrayView(a1) == QByteArrayView(a2); } |
578 | inline bool operator==(const QByteArray &a1, const char *a2) noexcept |
579 | { return a2 ? QtPrivate::compareMemory(a1, a2) == 0 : a1.isEmpty(); } |
580 | inline bool operator==(const char *a1, const QByteArray &a2) noexcept |
581 | { return a1 ? QtPrivate::compareMemory(a1, a2) == 0 : a2.isEmpty(); } |
582 | inline bool operator!=(const QByteArray &a1, const QByteArray &a2) noexcept |
583 | { return !(a1==a2); } |
584 | inline bool operator!=(const QByteArray &a1, const char *a2) noexcept |
585 | { return a2 ? QtPrivate::compareMemory(a1, a2) != 0 : !a1.isEmpty(); } |
586 | inline bool operator!=(const char *a1, const QByteArray &a2) noexcept |
587 | { return a1 ? QtPrivate::compareMemory(a1, a2) != 0 : !a2.isEmpty(); } |
588 | inline bool operator<(const QByteArray &a1, const QByteArray &a2) noexcept |
589 | { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) < 0; } |
590 | inline bool operator<(const QByteArray &a1, const char *a2) noexcept |
591 | { return QtPrivate::compareMemory(a1, a2) < 0; } |
592 | inline bool operator<(const char *a1, const QByteArray &a2) noexcept |
593 | { return QtPrivate::compareMemory(a1, a2) < 0; } |
594 | inline bool operator<=(const QByteArray &a1, const QByteArray &a2) noexcept |
595 | { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) <= 0; } |
596 | inline bool operator<=(const QByteArray &a1, const char *a2) noexcept |
597 | { return QtPrivate::compareMemory(a1, a2) <= 0; } |
598 | inline bool operator<=(const char *a1, const QByteArray &a2) noexcept |
599 | { return QtPrivate::compareMemory(a1, a2) <= 0; } |
600 | inline bool operator>(const QByteArray &a1, const QByteArray &a2) noexcept |
601 | { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) > 0; } |
602 | inline bool operator>(const QByteArray &a1, const char *a2) noexcept |
603 | { return QtPrivate::compareMemory(a1, a2) > 0; } |
604 | inline bool operator>(const char *a1, const QByteArray &a2) noexcept |
605 | { return QtPrivate::compareMemory(a1, a2) > 0; } |
606 | inline bool operator>=(const QByteArray &a1, const QByteArray &a2) noexcept |
607 | { return QtPrivate::compareMemory(QByteArrayView(a1), QByteArrayView(a2)) >= 0; } |
608 | inline bool operator>=(const QByteArray &a1, const char *a2) noexcept |
609 | { return QtPrivate::compareMemory(a1, a2) >= 0; } |
610 | inline bool operator>=(const char *a1, const QByteArray &a2) noexcept |
611 | { return QtPrivate::compareMemory(a1, a2) >= 0; } |
612 | #if !defined(QT_USE_QSTRINGBUILDER) |
613 | inline const QByteArray operator+(const QByteArray &a1, const QByteArray &a2) |
614 | { return QByteArray(a1) += a2; } |
615 | inline const QByteArray operator+(const QByteArray &a1, const char *a2) |
616 | { return QByteArray(a1) += a2; } |
617 | inline const QByteArray operator+(const QByteArray &a1, char a2) |
618 | { return QByteArray(a1) += a2; } |
619 | inline const QByteArray operator+(const char *a1, const QByteArray &a2) |
620 | { return QByteArray(a1) += a2; } |
621 | inline const QByteArray operator+(char a1, const QByteArray &a2) |
622 | { return QByteArray(&a1, 1) += a2; } |
623 | #endif // QT_USE_QSTRINGBUILDER |
624 | |
625 | inline QByteArray &QByteArray::setNum(short n, int base) |
626 | { return base == 10 ? setNum(qlonglong(n), base) : setNum(qulonglong(ushort(n)), base); } |
627 | inline QByteArray &QByteArray::setNum(ushort n, int base) |
628 | { return setNum(qulonglong(n), base); } |
629 | inline QByteArray &QByteArray::setNum(int n, int base) |
630 | { return base == 10 ? setNum(qlonglong(n), base) : setNum(qulonglong(uint(n)), base); } |
631 | inline QByteArray &QByteArray::setNum(uint n, int base) |
632 | { return setNum(qulonglong(n), base); } |
633 | inline QByteArray &QByteArray::setNum(long n, int base) |
634 | { return base == 10 ? setNum(qlonglong(n), base) : setNum(qulonglong(ulong(n)), base); } |
635 | inline QByteArray &QByteArray::setNum(ulong n, int base) |
636 | { return setNum(qulonglong(n), base); } |
637 | inline QByteArray &QByteArray::setNum(float n, char f, int prec) |
638 | { return setNum(double(n),f,prec); } |
639 | |
640 | inline std::string QByteArray::toStdString() const |
641 | { return std::string(constData(), length()); } |
642 | |
643 | inline QByteArray QByteArray::fromStdString(const std::string &s) |
644 | { return QByteArray(s.data(), qsizetype(s.size())); } |
645 | |
646 | #if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE)) |
647 | Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QByteArray &); |
648 | Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QByteArray &); |
649 | #endif |
650 | |
651 | #ifndef QT_NO_COMPRESS |
652 | Q_CORE_EXPORT QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel = -1); |
653 | Q_CORE_EXPORT QByteArray qUncompress(const uchar* data, qsizetype nbytes); |
654 | inline QByteArray qCompress(const QByteArray& data, int compressionLevel = -1) |
655 | { return qCompress(reinterpret_cast<const uchar *>(data.constData()), data.size(), compressionLevel); } |
656 | inline QByteArray qUncompress(const QByteArray& data) |
657 | { return qUncompress(reinterpret_cast<const uchar*>(data.constData()), data.size()); } |
658 | #endif |
659 | |
660 | Q_DECLARE_SHARED(QByteArray) |
661 | |
662 | class QByteArray::FromBase64Result |
663 | { |
664 | public: |
665 | QByteArray decoded; |
666 | QByteArray::Base64DecodingStatus decodingStatus; |
667 | |
668 | void swap(QByteArray::FromBase64Result &other) noexcept |
669 | { |
670 | qSwap(decoded, other.decoded); |
671 | qSwap(decodingStatus, other.decodingStatus); |
672 | } |
673 | |
674 | explicit operator bool() const noexcept { return decodingStatus == QByteArray::Base64DecodingStatus::Ok; } |
675 | |
676 | #if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(Q_QDOC) |
677 | QByteArray &operator*() & noexcept { return decoded; } |
678 | const QByteArray &operator*() const & noexcept { return decoded; } |
679 | QByteArray &&operator*() && noexcept { return std::move(decoded); } |
680 | #else |
681 | QByteArray &operator*() noexcept { return decoded; } |
682 | const QByteArray &operator*() const noexcept { return decoded; } |
683 | #endif |
684 | }; |
685 | |
686 | Q_DECLARE_SHARED(QByteArray::FromBase64Result) |
687 | |
688 | inline bool operator==(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept |
689 | { |
690 | if (lhs.decodingStatus != rhs.decodingStatus) |
691 | return false; |
692 | |
693 | if (lhs.decodingStatus == QByteArray::Base64DecodingStatus::Ok && lhs.decoded != rhs.decoded) |
694 | return false; |
695 | |
696 | return true; |
697 | } |
698 | |
699 | inline bool operator!=(const QByteArray::FromBase64Result &lhs, const QByteArray::FromBase64Result &rhs) noexcept |
700 | { |
701 | return !operator==(lhs, rhs); |
702 | } |
703 | |
704 | Q_CORE_EXPORT Q_DECL_PURE_FUNCTION size_t qHash(const QByteArray::FromBase64Result &key, size_t seed = 0) noexcept; |
705 | |
706 | // |
707 | // QByteArrayView members that require QByteArray: |
708 | // |
709 | QByteArray QByteArrayView::toByteArray() const |
710 | { |
711 | return QByteArray(data(), size()); |
712 | } |
713 | |
714 | QT_END_NAMESPACE |
715 | |
716 | #endif // QBYTEARRAY_H |
717 | |