Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qbytearray.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
4// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
5
6#include "qbytearray.h"
7#include "qbytearraymatcher.h"
8#include "private/qtools_p.h"
9#include "qhashfunctions.h"
10#include "qlist.h"
11#include "qlocale_p.h"
12#include "qlocale_tools_p.h"
13#include "private/qnumeric_p.h"
14#include "private/qsimd_p.h"
15#include "qstringalgorithms_p.h"
16#include "qscopedpointer.h"
17#include "qstringconverter_p.h"
18#include <qdatastream.h>
19#include <qmath.h>
20#if defined(Q_OS_WASM)
21#include "private/qstdweb_p.h"
22#endif
23
24#ifndef QT_NO_COMPRESS
25#include <zconf.h>
26#include <zlib.h>
27#include <qxpfunctional.h>
28#endif
29#include <ctype.h>
30#include <limits.h>
31#include <string.h>
32#include <stdlib.h>
33
34#include <algorithm>
35
36#ifdef Q_OS_WIN
37# if !defined(QT_BOOTSTRAPPED) && (defined(QT_NO_CAST_FROM_ASCII) || defined(QT_NO_CAST_FROM_BYTEARRAY))
38// MSVC requires this, but let's apply it to MinGW compilers too, just in case
39# error "This file cannot be compiled with QT_NO_CAST_{TO,FROM}_ASCII, " \
40 "otherwise some QByteArray functions will not get exported."
41# endif
42#endif
43
45
46Q_CONSTINIT const char QByteArray::_empty = '\0';
47
48// ASCII case system, used by QByteArray::to{Upper,Lower}() and qstr(n)icmp():
49static constexpr inline uchar asciiUpper(uchar c)
50{
51 return c >= 'a' && c <= 'z' ? c & ~0x20 : c;
52}
53
54static constexpr inline uchar asciiLower(uchar c)
55{
56 return c >= 'A' && c <= 'Z' ? c | 0x20 : c;
57}
58
60 const char *haystack0, qsizetype haystackLen, qsizetype from,
61 const char *needle0, qsizetype needleLen);
62
63/*****************************************************************************
64 Safe and portable C string functions; extensions to standard string.h
65 *****************************************************************************/
66
79char *qstrdup(const char *src)
80{
81 if (!src)
82 return nullptr;
83 char *dst = new char[strlen(src) + 1];
84 return qstrcpy(dst, src);
85}
86
101char *qstrcpy(char *dst, const char *src)
102{
103 if (!src)
104 return nullptr;
105#ifdef Q_CC_MSVC
106 const size_t len = strlen(src);
107 // This is actually not secure!!! It will be fixed
108 // properly in a later release!
109 if (len >= 0 && strcpy_s(dst, len+1, src) == 0)
110 return dst;
111 return nullptr;
112#else
113 return strcpy(dst, src);
114#endif
115}
116
138char *qstrncpy(char *dst, const char *src, size_t len)
139{
140 if (dst && len > 0) {
141 *dst = '\0';
142 if (src)
143 std::strncat(dst, src, len - 1);
144 }
145 return src ? dst : nullptr;
146}
147
187int qstrcmp(const char *str1, const char *str2)
188{
189 return (str1 && str2) ? strcmp(str1, str2)
190 : (str1 ? 1 : (str2 ? -1 : 0));
191}
192
232int qstricmp(const char *str1, const char *str2)
233{
234 const uchar *s1 = reinterpret_cast<const uchar *>(str1);
235 const uchar *s2 = reinterpret_cast<const uchar *>(str2);
236 if (!s1)
237 return s2 ? -1 : 0;
238 if (!s2)
239 return 1;
240
241 enum { Incomplete = 256 };
242 qptrdiff offset = 0;
243 auto innerCompare = [=, &offset](qptrdiff max, bool unlimited) {
244 max += offset;
245 do {
246 uchar c = s1[offset];
248 return res;
249 if (!c)
250 return 0;
251 ++offset;
252 } while (unlimited || offset < max);
253 return int(Incomplete);
254 };
255
256#if defined(__SSE4_1__) && !(defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer))
257 enum { PageSize = 4096, PageMask = PageSize - 1 };
258 const __m128i zero = _mm_setzero_si128();
259 forever {
260 // Calculate how many bytes we can load until we cross a page boundary
261 // for either source. This isn't an exact calculation, just something
262 // very quick.
265 size_t n = PageSize - ((u1 | u2) & PageMask);
266
267 qptrdiff maxoffset = offset + n;
268 for ( ; offset + 16 <= maxoffset; offset += sizeof(__m128i)) {
269 // load 16 bytes from either source
270 __m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s1 + offset));
271 __m128i b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s2 + offset));
272
273 // compare the two against each other
274 __m128i cmp = _mm_cmpeq_epi8(a, b);
275
276 // find NUL terminators too
277 cmp = _mm_min_epu8(cmp, a);
278 cmp = _mm_cmpeq_epi8(cmp, zero);
279
280 // was there any difference or a NUL?
281 uint mask = _mm_movemask_epi8(cmp);
282 if (mask) {
283 // yes, find out where
285 uint end = sizeof(mask) * 8 - qCountLeadingZeroBits(mask);
286 Q_ASSERT(end >= start);
287 offset += start;
288 n = end - start;
289 break;
290 }
291 }
292
293 // using SIMD could cause a page fault, so iterate byte by byte
294 int res = innerCompare(n, false);
295 if (res != Incomplete)
296 return res;
297 }
298#endif
299
300 return innerCompare(-1, true);
301}
302
322int qstrnicmp(const char *str1, const char *str2, size_t len)
323{
324 const uchar *s1 = reinterpret_cast<const uchar *>(str1);
325 const uchar *s2 = reinterpret_cast<const uchar *>(str2);
326 if (!s1 || !s2)
327 return s1 ? 1 : (s2 ? -1 : 0);
328 for (; len--; ++s1, ++s2) {
329 const uchar c = *s1;
331 return res;
332 if (!c) // strings are equal
333 break;
334 }
335 return 0;
336}
337
346int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
347{
348 Q_ASSERT(len1 >= 0);
349 Q_ASSERT(len2 >= -1);
350 const uchar *s1 = reinterpret_cast<const uchar *>(str1);
351 const uchar *s2 = reinterpret_cast<const uchar *>(str2);
352 if (!s1 || !len1) {
353 if (len2 == 0)
354 return 0;
355 if (len2 == -1)
356 return (!s2 || !*s2) ? 0 : -1;
357 Q_ASSERT(s2);
358 return -1;
359 }
360 if (!s2)
361 return len1 == 0 ? 0 : 1;
362
363 if (len2 == -1) {
364 // null-terminated str2
365 qsizetype i;
366 for (i = 0; i < len1; ++i) {
367 const uchar c = s2[i];
368 if (!c)
369 return 1;
370
372 return res;
373 }
374 return s2[i] ? -1 : 0;
375 } else {
376 // not null-terminated
377 const qsizetype len = qMin(len1, len2);
378 for (qsizetype i = 0; i < len; ++i) {
380 return res;
381 }
382 if (len1 == len2)
383 return 0;
384 return len1 < len2 ? -1 : 1;
385 }
386}
387
392{
393 if (!lhs.isNull() && !rhs.isNull()) {
394 int ret = memcmp(lhs.data(), rhs.data(), qMin(lhs.size(), rhs.size()));
395 if (ret != 0)
396 return ret;
397 }
398
399 // they matched qMin(l1, l2) bytes
400 // so the longer one is lexically after the shorter one
401 return lhs.size() == rhs.size() ? 0 : lhs.size() > rhs.size() ? 1 : -1;
402}
403
408{
409 return QUtf8::isValidUtf8(s).isValidUtf8;
410}
411
412// the CRC table below is created by the following piece of code
413#if 0
414static void createCRC16Table() // build CRC16 lookup table
415{
416 unsigned int i;
417 unsigned int j;
418 unsigned short crc_tbl[16];
419 unsigned int v0, v1, v2, v3;
420 for (i = 0; i < 16; i++) {
421 v0 = i & 1;
422 v1 = (i >> 1) & 1;
423 v2 = (i >> 2) & 1;
424 v3 = (i >> 3) & 1;
425 j = 0;
426#undef SET_BIT
427#define SET_BIT(x, b, v) (x) |= (v) << (b)
428 SET_BIT(j, 0, v0);
429 SET_BIT(j, 7, v0);
430 SET_BIT(j, 12, v0);
431 SET_BIT(j, 1, v1);
432 SET_BIT(j, 8, v1);
433 SET_BIT(j, 13, v1);
434 SET_BIT(j, 2, v2);
435 SET_BIT(j, 9, v2);
436 SET_BIT(j, 14, v2);
437 SET_BIT(j, 3, v3);
438 SET_BIT(j, 10, v3);
439 SET_BIT(j, 15, v3);
440 crc_tbl[i] = j;
441 }
442 printf("static const quint16 crc_tbl[16] = {\n");
443 for (int i = 0; i < 16; i +=4)
444 printf(" 0x%04x, 0x%04x, 0x%04x, 0x%04x,\n", crc_tbl[i], crc_tbl[i+1], crc_tbl[i+2], crc_tbl[i+3]);
445 printf("};\n");
446}
447#endif
448
449static const quint16 crc_tbl[16] = {
450 0x0000, 0x1081, 0x2102, 0x3183,
451 0x4204, 0x5285, 0x6306, 0x7387,
452 0x8408, 0x9489, 0xa50a, 0xb58b,
453 0xc60c, 0xd68d, 0xe70e, 0xf78f
454};
455
470{
471 quint16 crc = 0x0000;
472 switch (standard) {
474 crc = 0xffff;
475 break;
477 crc = 0x6363;
478 break;
479 }
480 uchar c;
481 const uchar *p = reinterpret_cast<const uchar *>(data.data());
482 qsizetype len = data.size();
483 while (len--) {
484 c = *p++;
485 crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
486 c >>= 4;
487 crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
488 }
489 switch (standard) {
491 crc = ~crc;
492 break;
494 break;
495 }
496 return crc & 0xffff;
497}
498
529#ifndef QT_NO_COMPRESS
530using CompressSizeHint_t = quint32; // 32-bit BE, historically
531
532enum class ZLibOp : bool { Compression, Decompression };
533
535static const char *zlibOpAsString(ZLibOp op)
536{
537 switch (op) {
538 case ZLibOp::Compression: return "qCompress";
539 case ZLibOp::Decompression: return "qUncompress";
540 }
541 Q_UNREACHABLE_RETURN(nullptr);
542}
543
545static QByteArray zlibError(ZLibOp op, const char *what)
546{
547 qWarning("%s: %s", zlibOpAsString(op), what);
548 return QByteArray();
549}
550
553{
554 return zlibError(op, "Data is null");
555}
556
559{
560 return zlibError(op, "Input length is negative");
561}
562
565{
566 return zlibError(op, "Not enough memory");
567}
568
571{
572 return zlibError(ZLibOp::Decompression, "Input data is corrupted");
573}
574
576static QByteArray unexpectedZlibError(ZLibOp op, int err, const char *msg)
577{
578 qWarning("%s unexpected zlib error: %s (%d)",
579 zlibOpAsString(op),
580 msg ? msg : "",
581 err);
582 return QByteArray();
583}
584
585static QByteArray xxflate(ZLibOp op, QArrayDataPointer<char> out, QByteArrayView input,
586 qxp::function_ref<int(z_stream *) const> init,
587 qxp::function_ref<int(z_stream *, size_t) const> processChunk,
588 qxp::function_ref<void(z_stream *) const> deinit)
589{
590 if (out.data() == nullptr) // allocation failed
591 return tooMuchData(op);
592 qsizetype capacity = out.allocatedCapacity();
593
594 const auto initalSize = out.size;
595
596 z_stream zs = {};
597 zs.next_in = reinterpret_cast<uchar *>(const_cast<char *>(input.data())); // 1980s C API...
598 if (const int err = init(&zs); err != Z_OK)
599 return unexpectedZlibError(op, err, zs.msg);
600 const auto sg = qScopeGuard([&] { deinit(&zs); });
601
602 using ZlibChunkSize_t = decltype(zs.avail_in);
603 static_assert(!std::is_signed_v<ZlibChunkSize_t>);
604 static_assert(std::is_same_v<ZlibChunkSize_t, decltype(zs.avail_out)>);
605 constexpr auto MaxChunkSize = std::numeric_limits<ZlibChunkSize_t>::max();
606 [[maybe_unused]]
607 constexpr auto MaxStatisticsSize = std::numeric_limits<decltype(zs.total_out)>::max();
608
609 size_t inputLeft = size_t(input.size());
610
611 int res;
612 do {
613 Q_ASSERT(out.freeSpaceAtBegin() == 0); // ensure prepend optimization stays out of the way
614 Q_ASSERT(capacity == out.allocatedCapacity());
615
616 if (zs.avail_out == 0) {
617 Q_ASSERT(size_t(out.size) - initalSize > MaxStatisticsSize || // total_out overflow
618 size_t(out.size) - initalSize == zs.total_out);
619 Q_ASSERT(out.size <= capacity);
620
621 qsizetype avail_out = capacity - out.size;
622 if (avail_out == 0) {
623 out->reallocateAndGrow(QArrayData::GrowsAtEnd, 1); // grow to next natural capacity
624 if (out.data() == nullptr) // reallocation failed
625 return tooMuchData(op);
626 capacity = out.allocatedCapacity();
627 avail_out = capacity - out.size;
628 }
629 zs.next_out = reinterpret_cast<uchar *>(out.data()) + out.size;
630 zs.avail_out = size_t(avail_out) > size_t(MaxChunkSize) ? MaxChunkSize
631 : ZlibChunkSize_t(avail_out);
632 out.size += zs.avail_out;
633
634 Q_ASSERT(zs.avail_out > 0);
635 }
636
637 if (zs.avail_in == 0) {
638 // zs.next_in is kept up-to-date by processChunk(), so nothing to do
639 zs.avail_in = inputLeft > MaxChunkSize ? MaxChunkSize : ZlibChunkSize_t(inputLeft);
640 inputLeft -= zs.avail_in;
641 }
642
643 res = processChunk(&zs, inputLeft);
644 } while (res == Z_OK);
645
646 switch (res) {
647 case Z_STREAM_END:
648 out.size -= zs.avail_out;
649 Q_ASSERT(size_t(out.size) - initalSize > MaxStatisticsSize || // total_out overflow
650 size_t(out.size) - initalSize == zs.total_out);
651 Q_ASSERT(out.size <= out.allocatedCapacity());
652 out.data()[out.size] = '\0';
653 return QByteArray(std::move(out));
654
655 case Z_MEM_ERROR:
656 return tooMuchData(op);
657
658 case Z_BUF_ERROR:
659 Q_UNREACHABLE(); // cannot happen - we supply a buffer that can hold the result,
660 // or else error out early
661
662 case Z_DATA_ERROR: // can only happen on decompression
664 return invalidCompressedData();
665
666 default:
667 return unexpectedZlibError(op, res, zs.msg);
668 }
669}
670
671QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel)
672{
673 constexpr qsizetype HeaderSize = sizeof(CompressSizeHint_t);
674 if (nbytes == 0) {
675 return QByteArray(HeaderSize, '\0');
676 }
677 if (!data)
679
680 if (nbytes < 0)
682
683 if (compressionLevel < -1 || compressionLevel > 9)
684 compressionLevel = -1;
685
686 QArrayDataPointer out = [&] {
687 constexpr qsizetype SingleAllocLimit = 256 * 1024; // the maximum size for which we use
688 // zlib's compressBound() to guarantee
689 // the output buffer size is sufficient
690 // to hold result
692 if (nbytes < SingleAllocLimit) {
693 // use maximum size
694 capacity += compressBound(uLong(nbytes)); // cannot overflow (both times)!
695 return QArrayDataPointer<char>(capacity);
696 }
697
698 // for larger buffers, assume it compresses optimally, and
699 // grow geometrically from there:
700 constexpr qsizetype MaxCompressionFactor = 1024; // max theoretical factor is 1032
701 // cf. http://www.zlib.org/zlib_tech.html,
702 // but use a nearby power-of-two (faster)
703 capacity += std::max(qsizetype(compressBound(uLong(SingleAllocLimit))),
704 nbytes / MaxCompressionFactor);
705 return QArrayDataPointer<char>(capacity, 0, QArrayData::Grow);
706 }();
707
708 if (out.data() == nullptr) // allocation failed
710
711 qToBigEndian(qt_saturate<CompressSizeHint_t>(nbytes), out.data());
712 out.size = HeaderSize;
713
714 return xxflate(ZLibOp::Compression, std::move(out), {data, nbytes},
715 [=] (z_stream *zs) { return deflateInit(zs, compressionLevel); },
716 [] (z_stream *zs, size_t inputLeft) {
717 return deflate(zs, inputLeft ? Z_NO_FLUSH : Z_FINISH);
718 },
719 [] (z_stream *zs) { deflateEnd(zs); });
720}
721#endif
722
755#ifndef QT_NO_COMPRESS
764{
765 if (!data)
767
768 if (nbytes < 0)
770
771 constexpr qsizetype HeaderSize = sizeof(CompressSizeHint_t);
772 if (nbytes < HeaderSize)
773 return invalidCompressedData();
774
775 const auto expectedSize = qFromBigEndian<CompressSizeHint_t>(data);
776 if (nbytes == HeaderSize) {
777 if (expectedSize != 0)
778 return invalidCompressedData();
779 return QByteArray();
780 }
781
782 constexpr auto MaxDecompressedSize = size_t(QByteArray::max_size());
783 if constexpr (MaxDecompressedSize < std::numeric_limits<CompressSizeHint_t>::max()) {
784 if (expectedSize > MaxDecompressedSize)
786 }
787
788 // expectedSize may be truncated, so always use at least nbytes
789 // (larger by at most 1%, according to zlib docs)
790 qsizetype capacity = std::max(qsizetype(expectedSize), // cannot overflow!
791 nbytes);
792
793 QArrayDataPointer<char> d(capacity);
794 return xxflate(ZLibOp::Decompression, std::move(d), {data + HeaderSize, nbytes - HeaderSize},
795 [] (z_stream *zs) { return inflateInit(zs); },
796 [] (z_stream *zs, size_t) { return inflate(zs, Z_NO_FLUSH); },
797 [] (z_stream *zs) { inflateEnd(zs); });
798}
799#endif
800
1090
1093
1282{
1283 const auto start = std::distance(cbegin(), first);
1284 const auto len = std::distance(first, last);
1285 remove(start, len);
1286 return begin() + start;
1287}
1288
1342{
1343 d = other.d;
1344 return *this;
1345}
1346
1347
1358{
1359 if (!str) {
1360 d.clear();
1361 } else if (!*str) {
1362 d = DataPointer::fromRawData(&_empty, 0);
1363 } else {
1364 assign(str);
1365 }
1366 return *this;
1367}
1368
1489
1492
1708{
1709 if (pos < size())
1710 resize(pos);
1711}
1712
1727{
1728 if (n > 0)
1729 resize(size() - n);
1730}
1731
1732
1815{
1816 if (!data) {
1817 d = DataPointer();
1818 } else {
1819 if (size < 0)
1820 size = qstrlen(data);
1821 if (!size) {
1822 d = DataPointer::fromRawData(&_empty, 0);
1823 } else {
1824 d = DataPointer(size, size);
1825 Q_CHECK_PTR(d.data());
1826 memcpy(d.data(), data, size);
1827 d.data()[size] = '\0';
1828 }
1829 }
1830}
1831
1839{
1840 if (size <= 0) {
1841 d = DataPointer::fromRawData(&_empty, 0);
1842 } else {
1843 d = DataPointer(size, size);
1844 Q_CHECK_PTR(d.data());
1845 memset(d.data(), ch, size);
1846 d.data()[size] = '\0';
1847 }
1848}
1849
1855{
1856 if (size <= 0) {
1857 d = DataPointer::fromRawData(&_empty, 0);
1858 } else {
1859 d = DataPointer(size, size);
1860 Q_CHECK_PTR(d.data());
1861 d.data()[size] = '\0';
1862 }
1863}
1864
1881{
1882 if (size < 0)
1883 size = 0;
1884
1885 const auto capacityAtEnd = capacity() - d.freeSpaceAtBegin();
1886 if (d->needsDetach() || size > capacityAtEnd)
1887 reallocData(size, QArrayData::Grow);
1888 d.size = size;
1889 if (d->allocatedCapacity())
1890 d.data()[size] = 0;
1891}
1892
1910void QByteArray::resize(qsizetype newSize, char c)
1911{
1912 const auto old = d.size;
1913 resize(newSize);
1914 if (old < d.size)
1915 memset(d.data() + old, c, d.size - old);
1916}
1917
1932
1944{
1945 resize(size < 0 ? this->size() : size);
1946 if (this->size())
1947 memset(d.data(), ch, this->size());
1948 return *this;
1949}
1950
1951void QByteArray::reallocData(qsizetype alloc, QArrayData::AllocationOption option)
1952{
1953 if (!alloc) {
1954 d = DataPointer::fromRawData(&_empty, 0);
1955 return;
1956 }
1957
1958 // don't use reallocate path when reducing capacity and there's free space
1959 // at the beginning: might shift data pointer outside of allocated space
1960 const bool cannotUseReallocate = d.freeSpaceAtBegin() > 0;
1961
1962 if (d->needsDetach() || cannotUseReallocate) {
1963 DataPointer dd(alloc, qMin(alloc, d.size), option);
1964 Q_CHECK_PTR(dd.data());
1965 if (dd.size > 0)
1966 ::memcpy(dd.data(), d.data(), dd.size);
1967 dd.data()[dd.size] = 0;
1968 d = dd;
1969 } else {
1970 d->reallocate(alloc, option);
1971 }
1972}
1973
1974void QByteArray::reallocGrowData(qsizetype n)
1975{
1976 if (!n) // expected to always allocate
1977 n = 1;
1978
1979 if (d->needsDetach()) {
1981 Q_CHECK_PTR(dd.data());
1982 dd->copyAppend(d.data(), d.data() + d.size);
1983 dd.data()[dd.size] = 0;
1984 d = dd;
1985 } else {
1986 d->reallocate(d.constAllocatedCapacity() + n, QArrayData::Grow);
1987 }
1988}
1989
1990void QByteArray::expand(qsizetype i)
1991{
1992 resize(qMax(i + 1, size()));
1993}
1994
2020{
2021 if (size() == 0 && ba.size() > d.constAllocatedCapacity() && ba.d.isMutable())
2022 return (*this = ba);
2023 return prepend(QByteArrayView(ba));
2024}
2025
2082{
2083 if (!ba.isNull()) {
2084 if (isNull()) {
2085 if (Q_UNLIKELY(!ba.d.isMutable()))
2086 assign(ba); // fromRawData, so we do a deep copy
2087 else
2088 operator=(ba);
2089 } else if (ba.size()) {
2091 }
2092 }
2093 return *this;
2094}
2095
2144{
2145 d.detachAndGrow(QArrayData::GrowsAtEnd, 1, nullptr, nullptr);
2146 d->copyAppend(1, ch);
2147 d.data()[d.size] = '\0';
2148 return *this;
2149}
2150
2202{
2203 const auto len = v.size();
2204
2205 if (len <= capacity() && isDetached()) {
2206 const auto offset = d.freeSpaceAtBegin();
2207 if (offset)
2208 d.setBegin(d.begin() - offset);
2209 std::memcpy(d.begin(), v.data(), len);
2210 d.size = len;
2211 d.data()[d.size] = '\0';
2212 } else {
2213 *this = v.toByteArray();
2214 }
2215 return *this;
2216}
2217
2231
2235
2239{
2240 const char *str = data.data();
2241 qsizetype size = data.size();
2242 if (i < 0 || size <= 0)
2243 return *this;
2244
2245 // handle this specially, as QArrayDataOps::insert() doesn't handle out of
2246 // bounds positions
2247 if (i >= d->size) {
2248 // In case when data points into the range or is == *this, we need to
2249 // defer a call to free() so that it comes after we copied the data from
2250 // the old memory:
2251 DataPointer detached{}; // construction is free
2252 d.detachAndGrow(Data::GrowsAtEnd, (i - d.size) + size, &str, &detached);
2253 Q_CHECK_PTR(d.data());
2254 d->copyAppend(i - d->size, ' ');
2255 d->copyAppend(str, str + size);
2256 d.data()[d.size] = '\0';
2257 return *this;
2258 }
2259
2260 if (!d->needsDetach() && QtPrivate::q_points_into_range(str, d)) {
2262 return insert(i, a);
2263 }
2264
2265 d->insert(i, str, size);
2266 d.data()[d.size] = '\0';
2267 return *this;
2268}
2269
2324{
2325 if (i < 0 || count <= 0)
2326 return *this;
2327
2328 if (i >= d->size) {
2329 // handle this specially, as QArrayDataOps::insert() doesn't handle out of bounds positions
2330 d.detachAndGrow(Data::GrowsAtEnd, (i - d.size) + count, nullptr, nullptr);
2331 Q_CHECK_PTR(d.data());
2332 d->copyAppend(i - d->size, ' ');
2333 d->copyAppend(count, ch);
2334 d.data()[d.size] = '\0';
2335 return *this;
2336 }
2337
2338 d->insert(i, count, ch);
2339 d.data()[d.size] = '\0';
2340 return *this;
2341}
2342
2362{
2363 if (len <= 0 || pos < 0 || size_t(pos) >= size_t(size()))
2364 return *this;
2365 if (pos + len > d->size)
2366 len = d->size - pos;
2367
2368 auto begin = d.begin();
2369 if (!d->isShared()) {
2370 d->erase(begin + pos, len);
2371 d.data()[d.size] = '\0';
2372 } else {
2374 const auto toRemove_start = d.begin() + pos;
2375 copy.d->copyRanges({{d.begin(), toRemove_start},
2376 {toRemove_start + len, d.end()}});
2377 swap(copy);
2378 }
2379 return *this;
2380}
2381
2435{
2436 if (QtPrivate::q_points_into_range(after.data(), d)) {
2437 QVarLengthArray copy(after.data(), after.data() + after.size());
2438 return replace(pos, len, QByteArrayView{copy});
2439 }
2440 if (len == after.size() && (pos + len <= size())) {
2441 // same size: in-place replacement possible
2442 if (len > 0) {
2443 detach();
2444 memcpy(d.data() + pos, after.data(), len*sizeof(char));
2445 }
2446 return *this;
2447 } else {
2448 // ### optimize me
2449 remove(pos, len);
2450 return insert(pos, after);
2451 }
2452}
2453
2486{
2487 const char *b = before.data();
2488 qsizetype bsize = before.size();
2489 const char *a = after.data();
2490 qsizetype asize = after.size();
2491
2492 if (isNull() || (b == a && bsize == asize))
2493 return *this;
2494
2495 // protect against before or after being part of this
2497 QVarLengthArray copy(a, a + asize);
2498 return replace(before, QByteArrayView{copy});
2499 }
2501 QVarLengthArray copy(b, b + bsize);
2502 return replace(QByteArrayView{copy}, after);
2503 }
2504
2505 QByteArrayMatcher matcher(b, bsize);
2506 qsizetype index = 0;
2507 qsizetype len = size();
2508 char *d = data(); // detaches
2509
2510 if (bsize == asize) {
2511 if (bsize) {
2512 while ((index = matcher.indexIn(*this, index)) != -1) {
2513 memcpy(d + index, a, asize);
2514 index += bsize;
2515 }
2516 }
2517 } else if (asize < bsize) {
2518 size_t to = 0;
2519 size_t movestart = 0;
2520 size_t num = 0;
2521 while ((index = matcher.indexIn(*this, index)) != -1) {
2522 if (num) {
2523 qsizetype msize = index - movestart;
2524 if (msize > 0) {
2525 memmove(d + to, d + movestart, msize);
2526 to += msize;
2527 }
2528 } else {
2529 to = index;
2530 }
2531 if (asize) {
2532 memcpy(d + to, a, asize);
2533 to += asize;
2534 }
2535 index += bsize;
2536 movestart = index;
2537 num++;
2538 }
2539 if (num) {
2540 qsizetype msize = len - movestart;
2541 if (msize > 0)
2542 memmove(d + to, d + movestart, msize);
2543 resize(len - num*(bsize-asize));
2544 }
2545 } else {
2546 // the most complex case. We don't want to lose performance by doing repeated
2547 // copies and reallocs of the data.
2548 while (index != -1) {
2549 size_t indices[4096];
2550 size_t pos = 0;
2551 while(pos < 4095) {
2552 index = matcher.indexIn(*this, index);
2553 if (index == -1)
2554 break;
2555 indices[pos++] = index;
2556 index += bsize;
2557 // avoid infinite loop
2558 if (!bsize)
2559 index++;
2560 }
2561 if (!pos)
2562 break;
2563
2564 // we have a table of replacement positions, use them for fast replacing
2565 qsizetype adjust = pos*(asize-bsize);
2566 // index has to be adjusted in case we get back into the loop above.
2567 if (index != -1)
2568 index += adjust;
2569 qsizetype newlen = len + adjust;
2570 qsizetype moveend = len;
2571 if (newlen > len) {
2572 resize(newlen);
2573 len = newlen;
2574 }
2575 d = this->d.data(); // data(), without the detach() check
2576
2577 while(pos) {
2578 pos--;
2579 qsizetype movestart = indices[pos] + bsize;
2580 qsizetype insertstart = indices[pos] + pos*(asize-bsize);
2581 qsizetype moveto = insertstart + asize;
2582 memmove(d + moveto, d + movestart, (moveend - movestart));
2583 if (asize)
2584 memcpy(d + insertstart, a, asize);
2585 moveend = movestart - bsize;
2586 }
2587 }
2588 }
2589 return *this;
2590}
2591
2606QByteArray &QByteArray::replace(char before, char after)
2607{
2608 if (before != after) {
2609 if (const auto pos = indexOf(before); pos >= 0) {
2610 const auto detachedData = data();
2611 std::replace(detachedData + pos, detachedData + size(), before, after);
2612 }
2613 }
2614 return *this;
2615}
2616
2624QList<QByteArray> QByteArray::split(char sep) const
2625{
2626 QList<QByteArray> list;
2627 qsizetype start = 0;
2628 qsizetype end;
2629 while ((end = indexOf(sep, start)) != -1) {
2631 start = end + 1;
2632 }
2633 list.append(mid(start));
2634 return list;
2635}
2636
2649{
2650 if (isEmpty())
2651 return *this;
2652
2653 if (times <= 1) {
2654 if (times == 1)
2655 return *this;
2656 return QByteArray();
2657 }
2658
2659 const qsizetype resultSize = times * size();
2660
2662 result.reserve(resultSize);
2663 if (result.capacity() != resultSize)
2664 return QByteArray(); // not enough memory
2665
2666 memcpy(result.d.data(), data(), size());
2667
2668 qsizetype sizeSoFar = size();
2669 char *end = result.d.data() + sizeSoFar;
2670
2671 const qsizetype halfResultSize = resultSize >> 1;
2672 while (sizeSoFar <= halfResultSize) {
2673 memcpy(end, result.d.data(), sizeSoFar);
2674 end += sizeSoFar;
2675 sizeSoFar <<= 1;
2676 }
2677 memcpy(end, result.d.data(), resultSize - sizeSoFar);
2678 result.d.data()[resultSize] = '\0';
2679 result.d.size = resultSize;
2680 return result;
2681}
2682
2683#define REHASH(a) \
2684 if (ol_minus_1 < sizeof(std::size_t) * CHAR_BIT) \
2685 hashHaystack -= std::size_t(a) << ol_minus_1; \
2686 hashHaystack <<= 1
2687
2689{
2690 const auto ol = needle.size();
2691 const auto l = haystack.size();
2692 if (ol == 0) {
2693 if (from < 0)
2694 return qMax(from + l, 0);
2695 else
2696 return from > l ? -1 : from;
2697 }
2698
2699 if (ol == 1)
2700 return findByteArray(haystack, from, needle.front());
2701
2702 if (from > l || ol + from > l)
2703 return -1;
2704
2705 return qFindByteArray(haystack.data(), haystack.size(), from, needle.data(), ol);
2706}
2707
2735static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char *needle,
2736 qsizetype ol, qsizetype from)
2737{
2738 auto delta = l - ol;
2739 if (from < 0)
2740 from = delta;
2741 if (from < 0 || from > l)
2742 return -1;
2743 if (from > delta)
2744 from = delta;
2745
2746 const char *end = haystack;
2747 haystack += from;
2748 const auto ol_minus_1 = std::size_t(ol - 1);
2749 const char *n = needle + ol_minus_1;
2750 const char *h = haystack + ol_minus_1;
2751 std::size_t hashNeedle = 0, hashHaystack = 0;
2752 qsizetype idx;
2753 for (idx = 0; idx < ol; ++idx) {
2754 hashNeedle = ((hashNeedle<<1) + *(n-idx));
2755 hashHaystack = ((hashHaystack<<1) + *(h-idx));
2756 }
2757 hashHaystack -= *haystack;
2758 while (haystack >= end) {
2759 hashHaystack += *haystack;
2760 if (hashHaystack == hashNeedle && memcmp(needle, haystack, ol) == 0)
2761 return haystack - end;
2762 --haystack;
2763 REHASH(*(haystack + ol));
2764 }
2765 return -1;
2766
2767}
2768
2769static inline qsizetype lastIndexOfCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept
2770{
2771 if (haystack.size() == 0)
2772 return -1;
2773 if (from < 0)
2774 from += haystack.size();
2775 else if (from > haystack.size())
2776 from = haystack.size() - 1;
2777 if (from >= 0) {
2778 const char *b = haystack.data();
2779 const char *n = b + from + 1;
2780 while (n-- != b) {
2781 if (*n == needle)
2782 return n - b;
2783 }
2784 }
2785 return -1;
2786}
2787
2788qsizetype QtPrivate::lastIndexOf(QByteArrayView haystack, qsizetype from, char needle) noexcept
2789{
2790 return lastIndexOfCharHelper(haystack, from, needle);
2791}
2792
2794{
2795 if (haystack.isEmpty()) {
2796 if (needle.isEmpty() && from == 0)
2797 return 0;
2798 return -1;
2799 }
2800 const auto ol = needle.size();
2801 if (ol == 1)
2802 return lastIndexOfCharHelper(haystack, from, needle.front());
2803
2804 return lastIndexOfHelper(haystack.data(), haystack.size(), needle.data(), ol, from);
2805}
2806
2860static inline qsizetype countCharHelper(QByteArrayView haystack, char needle) noexcept
2861{
2862 qsizetype num = 0;
2863 for (char ch : haystack) {
2864 if (ch == needle)
2865 ++num;
2866 }
2867 return num;
2868}
2869
2871{
2872 if (needle.size() == 0)
2873 return haystack.size() + 1;
2874
2875 if (needle.size() == 1)
2876 return countCharHelper(haystack, needle[0]);
2877
2878 qsizetype num = 0;
2879 qsizetype i = -1;
2880 if (haystack.size() > 500 && needle.size() > 5) {
2881 QByteArrayMatcher matcher(needle);
2882 while ((i = matcher.indexIn(haystack, i + 1)) != -1)
2883 ++num;
2884 } else {
2885 while ((i = haystack.indexOf(needle, i + 1)) != -1)
2886 ++num;
2887 }
2888 return num;
2889}
2890
2909{
2910 return countCharHelper(*this, ch);
2911}
2912
2913#if QT_DEPRECATED_SINCE(6, 4)
2920#endif
2921
2935{
2936 if (haystack.size() < needle.size())
2937 return false;
2938 if (haystack.data() == needle.data() || needle.size() == 0)
2939 return true;
2940 return memcmp(haystack.data(), needle.data(), needle.size()) == 0;
2941}
2942
2964{
2965 if (haystack.size() < needle.size())
2966 return false;
2967 if (haystack.end() == needle.end() || needle.size() == 0)
2968 return true;
2969 return memcmp(haystack.end() - needle.size(), needle.data(), needle.size()) == 0;
2970}
2971
2993/*
2994 Returns true if \a c is an uppercase ASCII letter.
2995 */
2996static constexpr inline bool isUpperCaseAscii(char c)
2997{
2998 return c >= 'A' && c <= 'Z';
2999}
3000
3001/*
3002 Returns true if \a c is an lowercase ASCII letter.
3003 */
3004static constexpr inline bool isLowerCaseAscii(char c)
3005{
3006 return c >= 'a' && c <= 'z';
3007}
3008
3021{
3022 return std::none_of(begin(), end(), isLowerCaseAscii);
3023}
3024
3037{
3038 return std::none_of(begin(), end(), isUpperCaseAscii);
3039}
3040
3103{
3104 qsizetype p = pos;
3105 qsizetype l = len;
3106 using namespace QtPrivate;
3107 switch (QContainerImplHelper::mid(size(), &p, &l)) {
3108 case QContainerImplHelper::Null:
3109 return QByteArray();
3110 case QContainerImplHelper::Empty:
3111 {
3112 return QByteArray(DataPointer::fromRawData(&_empty, 0));
3113 }
3114 case QContainerImplHelper::Full:
3115 return *this;
3116 case QContainerImplHelper::Subset:
3117 return sliced(p, l);
3118 }
3119 Q_UNREACHABLE_RETURN(QByteArray());
3120}
3121
3123{
3124 qsizetype p = pos;
3125 qsizetype l = len;
3126 using namespace QtPrivate;
3127 switch (QContainerImplHelper::mid(size(), &p, &l)) {
3128 case QContainerImplHelper::Null:
3129 return QByteArray();
3130 case QContainerImplHelper::Empty:
3131 resize(0); // keep capacity if we've reserve()d
3132 [[fallthrough]];
3133 case QContainerImplHelper::Full:
3134 return std::move(*this);
3135 case QContainerImplHelper::Subset:
3136 return std::move(*this).sliced(p, l);
3137 }
3138 Q_UNREACHABLE_RETURN(QByteArray());
3139}
3140
3187QByteArray QByteArray::sliced_helper(QByteArray &a, qsizetype pos, qsizetype n)
3188{
3189 if (n == 0)
3190 return fromRawData(&_empty, 0);
3191 DataPointer d = std::move(a.d).sliced(pos, n);
3192 d.data()[n] = 0;
3193 return QByteArray(std::move(d));
3194}
3195
3264template <typename T>
3266{
3267 // find the first bad character in input
3268 const char *orig_begin = input.constBegin();
3269 const char *firstBad = orig_begin;
3270 const char *e = input.constEnd();
3271 for ( ; firstBad != e ; ++firstBad) {
3272 uchar ch = uchar(*firstBad);
3273 uchar converted = lookup(ch);
3274 if (ch != converted)
3275 break;
3276 }
3277
3278 if (firstBad == e)
3279 return std::move(input);
3280
3281 // transform the rest
3282 QByteArray s = std::move(input); // will copy if T is const QByteArray
3283 char *b = s.begin(); // will detach if necessary
3284 char *p = b + (firstBad - orig_begin);
3285 e = b + s.size();
3286 for ( ; p != e; ++p)
3287 *p = char(lookup(uchar(*p)));
3288 return s;
3289}
3290
3291QByteArray QByteArray::toLower_helper(const QByteArray &a)
3292{
3293 return toCase_template(a, asciiLower);
3294}
3295
3296QByteArray QByteArray::toLower_helper(QByteArray &a)
3297{
3298 return toCase_template(a, asciiLower);
3299}
3300
3313QByteArray QByteArray::toUpper_helper(const QByteArray &a)
3314{
3315 return toCase_template(a, asciiUpper);
3316}
3317
3318QByteArray QByteArray::toUpper_helper(QByteArray &a)
3319{
3320 return toCase_template(a, asciiUpper);
3321}
3322
3331{
3332 d.clear();
3333}
3334
3335#if !defined(QT_NO_DATASTREAM)
3336
3346{
3347 if (ba.isNull() && out.version() >= 6) {
3348 QDataStream::writeQSizeType(out, -1);
3349 return out;
3350 }
3351 return out.writeBytes(ba.constData(), ba.size());
3352}
3353
3363{
3364 ba.clear();
3365
3366 qint64 size = QDataStream::readQSizeType(in);
3367 qsizetype len = size;
3368 if (size != len || size < -1) {
3369 ba.clear();
3370 in.setStatus(QDataStream::SizeLimitExceeded);
3371 return in;
3372 }
3373 if (len == -1) { // null byte-array
3374 ba = QByteArray();
3375 return in;
3376 }
3377
3378 constexpr qsizetype Step = 1024 * 1024;
3379 qsizetype allocated = 0;
3380
3381 do {
3382 qsizetype blockSize = qMin(Step, len - allocated);
3383 ba.resize(allocated + blockSize);
3384 if (in.readRawData(ba.data() + allocated, blockSize) != blockSize) {
3385 ba.clear();
3386 in.setStatus(QDataStream::ReadPastEnd);
3387 return in;
3388 }
3389 allocated += blockSize;
3390 } while (allocated < len);
3391
3392 return in;
3393}
3394#endif // QT_NO_DATASTREAM
3395
3620QByteArray QByteArray::simplified_helper(const QByteArray &a)
3621{
3623}
3624
3625QByteArray QByteArray::simplified_helper(QByteArray &a)
3626{
3628}
3629
3649QByteArray QByteArray::trimmed_helper(const QByteArray &a)
3650{
3652}
3653
3654QByteArray QByteArray::trimmed_helper(QByteArray &a)
3655{
3657}
3658
3664
3684{
3686 qsizetype len = size();
3687 qsizetype padlen = width - len;
3688 if (padlen > 0) {
3689 result.resize(len+padlen);
3690 if (len)
3691 memcpy(result.d.data(), data(), len);
3692 memset(result.d.data()+len, fill, padlen);
3693 } else {
3694 if (truncate)
3695 result = left(width);
3696 else
3697 result = *this;
3698 }
3699 return result;
3700}
3701
3721{
3723 qsizetype len = size();
3724 qsizetype padlen = width - len;
3725 if (padlen > 0) {
3726 result.resize(len+padlen);
3727 if (len)
3728 memcpy(result.d.data()+padlen, data(), len);
3729 memset(result.d.data(), fill, padlen);
3730 } else {
3731 if (truncate)
3732 result = left(width);
3733 else
3734 result = *this;
3735 }
3736 return result;
3737}
3738
3739auto QtPrivate::toSignedInteger(QByteArrayView data, int base) -> ParsedNumber<qlonglong>
3740{
3741#if defined(QT_CHECK_RANGE)
3742 if (base != 0 && (base < 2 || base > 36)) {
3743 qWarning("QByteArray::toIntegral: Invalid base %d", base);
3744 base = 10;
3745 }
3746#endif
3747 if (data.isEmpty())
3748 return {};
3749
3751 if (r.ok())
3752 return ParsedNumber(r.result);
3753 return {};
3754}
3755
3756auto QtPrivate::toUnsignedInteger(QByteArrayView data, int base) -> ParsedNumber<qulonglong>
3757{
3758#if defined(QT_CHECK_RANGE)
3759 if (base != 0 && (base < 2 || base > 36)) {
3760 qWarning("QByteArray::toIntegral: Invalid base %d", base);
3761 base = 10;
3762 }
3763#endif
3764 if (data.isEmpty())
3765 return {};
3766
3768 if (r.ok())
3769 return ParsedNumber(r.result);
3770 return {};
3771}
3772
3799{
3800 return QtPrivate::toIntegral<qlonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3801}
3802
3829{
3830 return QtPrivate::toIntegral<qulonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3831}
3832
3860int QByteArray::toInt(bool *ok, int base) const
3861{
3862 return QtPrivate::toIntegral<int>(qToByteArrayViewIgnoringNull(*this), ok, base);
3863}
3864
3891{
3892 return QtPrivate::toIntegral<uint>(qToByteArrayViewIgnoringNull(*this), ok, base);
3893}
3894
3923long QByteArray::toLong(bool *ok, int base) const
3924{
3925 return QtPrivate::toIntegral<long>(qToByteArrayViewIgnoringNull(*this), ok, base);
3926}
3927
3955{
3956 return QtPrivate::toIntegral<ulong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3957}
3958
3984short QByteArray::toShort(bool *ok, int base) const
3985{
3986 return QtPrivate::toIntegral<short>(qToByteArrayViewIgnoringNull(*this), ok, base);
3987}
3988
4015{
4016 return QtPrivate::toIntegral<ushort>(qToByteArrayViewIgnoringNull(*this), ok, base);
4017}
4018
4044double QByteArray::toDouble(bool *ok) const
4045{
4046 return QByteArrayView(*this).toDouble(ok);
4047}
4048
4049auto QtPrivate::toDouble(QByteArrayView a) noexcept -> ParsedNumber<double>
4050{
4051 auto r = qt_asciiToDouble(a.data(), a.size(), WhitespacesAllowed);
4052 if (r.ok())
4053 return ParsedNumber{r.result};
4054 else
4055 return {};
4056}
4057
4083float QByteArray::toFloat(bool *ok) const
4084{
4086}
4087
4088auto QtPrivate::toFloat(QByteArrayView a) noexcept -> ParsedNumber<float>
4089{
4090 if (const auto r = toDouble(a)) {
4091 bool ok = true;
4092 const auto f = QLocaleData::convertDoubleToFloat(*r, &ok);
4093 if (ok)
4094 return ParsedNumber(f);
4095 }
4096 return {};
4097}
4098
4110QByteArray QByteArray::toBase64(Base64Options options) const
4111{
4112 constexpr char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
4113 "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
4114 constexpr char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
4115 "ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
4116 const char *const alphabet = options & Base64UrlEncoding ? alphabet_base64url : alphabet_base64;
4117 constexpr char padchar = '=';
4118 qsizetype padlen = 0;
4119
4120 const qsizetype sz = size();
4121
4122 QByteArray tmp((sz + 2) / 3 * 4, Qt::Uninitialized);
4123
4124 qsizetype i = 0;
4125 char *out = tmp.data();
4126 while (i < sz) {
4127 // encode 3 bytes at a time
4128 int chunk = 0;
4129 chunk |= int(uchar(data()[i++])) << 16;
4130 if (i == sz) {
4131 padlen = 2;
4132 } else {
4133 chunk |= int(uchar(data()[i++])) << 8;
4134 if (i == sz)
4135 padlen = 1;
4136 else
4137 chunk |= int(uchar(data()[i++]));
4138 }
4139
4140 int j = (chunk & 0x00fc0000) >> 18;
4141 int k = (chunk & 0x0003f000) >> 12;
4142 int l = (chunk & 0x00000fc0) >> 6;
4143 int m = (chunk & 0x0000003f);
4144 *out++ = alphabet[j];
4145 *out++ = alphabet[k];
4146
4147 if (padlen > 1) {
4148 if ((options & OmitTrailingEquals) == 0)
4149 *out++ = padchar;
4150 } else {
4151 *out++ = alphabet[l];
4152 }
4153 if (padlen > 0) {
4154 if ((options & OmitTrailingEquals) == 0)
4155 *out++ = padchar;
4156 } else {
4157 *out++ = alphabet[m];
4158 }
4159 }
4160 Q_ASSERT((options & OmitTrailingEquals) || (out == tmp.size() + tmp.data()));
4161 if (options & OmitTrailingEquals)
4162 tmp.truncate(out - tmp.data());
4163 return tmp;
4164}
4165
4221static char *qulltoa2(char *p, qulonglong n, int base)
4222{
4223#if defined(QT_CHECK_RANGE)
4224 if (base < 2 || base > 36) {
4225 qWarning("QByteArray::setNum: Invalid base %d", base);
4226 base = 10;
4227 }
4228#endif
4229 constexpr char b = 'a' - 10;
4230 do {
4231 const int c = n % base;
4232 n /= base;
4233 *--p = c + (c < 10 ? '0' : b);
4234 } while (n);
4235
4236 return p;
4237}
4238
4245{
4246 constexpr int buffsize = 66; // big enough for MAX_ULLONG in base 2
4247 char buff[buffsize];
4248 char *p;
4249
4250 if (n < 0) {
4251 // Take care to avoid overflow on negating min value:
4252 p = qulltoa2(buff + buffsize, qulonglong(-(1 + n)) + 1, base);
4253 *--p = '-';
4254 } else {
4255 p = qulltoa2(buff + buffsize, qulonglong(n), base);
4256 }
4257
4258 clear();
4259 append(p, buffsize - (p - buff));
4260 return *this;
4261}
4262
4270{
4271 constexpr int buffsize = 66; // big enough for MAX_ULLONG in base 2
4272 char buff[buffsize];
4273 char *p = qulltoa2(buff + buffsize, n, base);
4274
4275 clear();
4276 append(p, buffsize - (p - buff));
4277 return *this;
4278}
4279
4293{
4294 return *this = QByteArray::number(n, format, precision);
4295}
4296
4327{
4328 QByteArray s;
4329 s.setNum(n, base);
4330 return s;
4331}
4332
4339{
4340 QByteArray s;
4341 s.setNum(n, base);
4342 return s;
4343}
4344
4351{
4352 QByteArray s;
4353 s.setNum(n, base);
4354 return s;
4355}
4356
4363{
4364 QByteArray s;
4365 s.setNum(n, base);
4366 return s;
4367}
4368
4375{
4376 QByteArray s;
4377 s.setNum(n, base);
4378 return s;
4379}
4380
4387{
4388 QByteArray s;
4389 s.setNum(n, base);
4390 return s;
4391}
4392
4406{
4408
4410 case 'f':
4412 break;
4413 case 'e':
4415 break;
4416 case 'g':
4418 break;
4419 default:
4420#if defined(QT_CHECK_RANGE)
4421 qWarning("QByteArray::setNum: Invalid format char '%c'", format);
4422#endif
4423 break;
4424 }
4425
4427}
4428
4480{
4481 if (!data || !size)
4482 clear();
4483 else
4484 *this = fromRawData(data, size);
4485 return *this;
4486}
4487
4488namespace {
4489struct fromBase64_helper_result {
4490 qsizetype decodedLength;
4492};
4493
4494fromBase64_helper_result fromBase64_helper(const char *input, qsizetype inputSize,
4495 char *output /* may alias input */,
4496 QByteArray::Base64Options options)
4497{
4498 fromBase64_helper_result result{ 0, QByteArray::Base64DecodingStatus::Ok };
4499
4500 unsigned int buf = 0;
4501 int nbits = 0;
4502
4503 qsizetype offset = 0;
4504 for (qsizetype i = 0; i < inputSize; ++i) {
4505 int ch = input[i];
4506 int d;
4507
4508 if (ch >= 'A' && ch <= 'Z') {
4509 d = ch - 'A';
4510 } else if (ch >= 'a' && ch <= 'z') {
4511 d = ch - 'a' + 26;
4512 } else if (ch >= '0' && ch <= '9') {
4513 d = ch - '0' + 52;
4514 } else if (ch == '+' && (options & QByteArray::Base64UrlEncoding) == 0) {
4515 d = 62;
4516 } else if (ch == '-' && (options & QByteArray::Base64UrlEncoding) != 0) {
4517 d = 62;
4518 } else if (ch == '/' && (options & QByteArray::Base64UrlEncoding) == 0) {
4519 d = 63;
4520 } else if (ch == '_' && (options & QByteArray::Base64UrlEncoding) != 0) {
4521 d = 63;
4522 } else {
4524 if (ch == '=') {
4525 // can have 1 or 2 '=' signs, in both cases padding base64Size to
4526 // a multiple of 4. Any other case is illegal.
4527 if ((inputSize % 4) != 0) {
4529 return result;
4530 } else if ((i == inputSize - 1) ||
4531 (i == inputSize - 2 && input[++i] == '=')) {
4532 d = -1; // ... and exit the loop, normally
4533 } else {
4535 return result;
4536 }
4537 } else {
4539 return result;
4540 }
4541 } else {
4542 d = -1;
4543 }
4544 }
4545
4546 if (d != -1) {
4547 buf = (buf << 6) | d;
4548 nbits += 6;
4549 if (nbits >= 8) {
4550 nbits -= 8;
4551 Q_ASSERT(offset < i);
4552 output[offset++] = buf >> nbits;
4553 buf &= (1 << nbits) - 1;
4554 }
4555 }
4556 }
4557
4558 result.decodedLength = offset;
4559 return result;
4560}
4561} // anonymous namespace
4562
4591{
4592 // try to avoid a detach when calling data(), as it would over-allocate
4593 // (we need less space when decoding than the one required by the full copy)
4594 if (base64.isDetached()) {
4595 const auto base64result = fromBase64_helper(base64.data(),
4596 base64.size(),
4597 base64.data(), // in-place
4598 options);
4599 base64.truncate(base64result.decodedLength);
4600 return { std::move(base64), base64result.status };
4601 }
4602
4603 return fromBase64Encoding(base64, options);
4604}
4605
4606
4608{
4609 const auto base64Size = base64.size();
4610 QByteArray result((base64Size * 3) / 4, Qt::Uninitialized);
4611 const auto base64result = fromBase64_helper(base64.data(),
4612 base64Size,
4613 const_cast<char *>(result.constData()),
4614 options);
4615 result.truncate(base64result.decodedLength);
4616 return { std::move(result), base64result.status };
4617}
4618
4643QByteArray QByteArray::fromBase64(const QByteArray &base64, Base64Options options)
4644{
4645 if (auto result = fromBase64Encoding(base64, options))
4646 return std::move(result.decoded);
4647 return QByteArray();
4648}
4649
4662{
4663 QByteArray res((hexEncoded.size() + 1)/ 2, Qt::Uninitialized);
4664 uchar *result = (uchar *)res.data() + res.size();
4665
4666 bool odd_digit = true;
4667 for (qsizetype i = hexEncoded.size() - 1; i >= 0; --i) {
4668 uchar ch = uchar(hexEncoded.at(i));
4669 int tmp = QtMiscUtils::fromHex(ch);
4670 if (tmp == -1)
4671 continue;
4672 if (odd_digit) {
4673 --result;
4674 *result = tmp;
4675 odd_digit = false;
4676 } else {
4677 *result |= tmp << 4;
4678 odd_digit = true;
4679 }
4680 }
4681
4682 res.remove(0, result - (const uchar *)res.constData());
4683 return res;
4684}
4685
4700QByteArray QByteArray::toHex(char separator) const
4701{
4702 if (isEmpty())
4703 return QByteArray();
4704
4705 const qsizetype length = separator ? (size() * 3 - 1) : (size() * 2);
4707 char *hexData = hex.data();
4708 const uchar *data = (const uchar *)this->data();
4709 for (qsizetype i = 0, o = 0; i < size(); ++i) {
4710 hexData[o++] = QtMiscUtils::toHexLower(data[i] >> 4);
4711 hexData[o++] = QtMiscUtils::toHexLower(data[i] & 0xf);
4712
4713 if ((separator) && (o < length))
4714 hexData[o++] = separator;
4715 }
4716 return hex;
4717}
4718
4719static void q_fromPercentEncoding(QByteArray *ba, char percent)
4720{
4721 if (ba->isEmpty())
4722 return;
4723
4724 char *data = ba->data();
4725 const char *inputPtr = data;
4726
4727 qsizetype i = 0;
4728 qsizetype len = ba->size();
4729 qsizetype outlen = 0;
4730 int a, b;
4731 char c;
4732 while (i < len) {
4733 c = inputPtr[i];
4734 if (c == percent && i + 2 < len) {
4735 a = inputPtr[++i];
4736 b = inputPtr[++i];
4737
4738 if (a >= '0' && a <= '9') a -= '0';
4739 else if (a >= 'a' && a <= 'f') a = a - 'a' + 10;
4740 else if (a >= 'A' && a <= 'F') a = a - 'A' + 10;
4741
4742 if (b >= '0' && b <= '9') b -= '0';
4743 else if (b >= 'a' && b <= 'f') b = b - 'a' + 10;
4744 else if (b >= 'A' && b <= 'F') b = b - 'A' + 10;
4745
4746 *data++ = (char)((a << 4) | b);
4747 } else {
4748 *data++ = c;
4749 }
4750
4751 ++i;
4752 ++outlen;
4753 }
4754
4755 if (outlen != len)
4756 ba->truncate(outlen);
4757}
4758
4778{
4779 if (isEmpty())
4780 return *this; // Preserves isNull().
4781
4782 QByteArray tmp = *this;
4783 q_fromPercentEncoding(&tmp, percent);
4784 return tmp;
4785}
4786
4802{
4803 return input.percentDecoded(percent);
4804}
4805
4814{
4815 return QByteArray(s.data(), qsizetype(s.size()));
4816}
4817
4830std::string QByteArray::toStdString() const
4831{
4832 return std::string(data(), size_t(size()));
4833}
4834
4860 char percent) const
4861{
4862 if (isNull())
4863 return QByteArray(); // preserve null
4864 if (isEmpty())
4865 return QByteArray(data(), 0);
4866
4867 const auto contains = [](const QByteArray &view, char c) {
4868 // As view.contains(c), but optimised to bypass a lot of overhead:
4869 return view.size() > 0 && memchr(view.data(), c, view.size()) != nullptr;
4870 };
4871
4872 QByteArray result = *this;
4873 char *output = nullptr;
4874 qsizetype length = 0;
4875
4876 for (unsigned char c : *this) {
4877 if (char(c) != percent
4878 && ((c >= 0x61 && c <= 0x7A) // ALPHA
4879 || (c >= 0x41 && c <= 0x5A) // ALPHA
4880 || (c >= 0x30 && c <= 0x39) // DIGIT
4881 || c == 0x2D // -
4882 || c == 0x2E // .
4883 || c == 0x5F // _
4884 || c == 0x7E // ~
4885 || contains(exclude, c))
4886 && !contains(include, c)) {
4887 if (output)
4888 output[length] = c;
4889 ++length;
4890 } else {
4891 if (!output) {
4892 // detach now
4893 result.resize(size() * 3); // worst case
4894 output = result.data();
4895 }
4896 output[length++] = percent;
4897 output[length++] = QtMiscUtils::toHexUpper((c & 0xf0) >> 4);
4899 }
4900 }
4901 if (output)
4902 result.truncate(length);
4903
4904 return result;
4905}
4906
4907#if defined(Q_OS_WASM) || defined(Q_QDOC)
4908
4932QByteArray QByteArray::fromEcmaUint8Array(emscripten::val uint8array)
4933{
4934 return qstdweb::Uint8Array(uint8array).copyToQByteArray();
4935}
4936
4954emscripten::val QByteArray::toEcmaUint8Array()
4955{
4956 return qstdweb::Uint8Array::copyFrom(*this).val();
4957}
4958
4959#endif
4960
5057#if QT_DEPRECATED_SINCE(6, 8)
5081#endif // QT_DEPRECATED_SINCE(6, 8)
5082
5182size_t qHash(const QByteArray::FromBase64Result &key, size_t seed) noexcept
5183{
5184 return qHashMulti(seed, key.decoded, static_cast<int>(key.decodingStatus));
5185}
5186
5209
5210#undef REHASH
\inmodule QtCore
constexpr bool isNull() const noexcept
constexpr qsizetype size() const noexcept
constexpr const_pointer data() const noexcept
double toDouble(bool *ok=nullptr) const
size_t qHash(const QByteArray::FromBase64Result &key, size_t seed) noexcept
Returns the hash value for key, using seed to seed the calculation.
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:611
qulonglong toULongLong(bool *ok=nullptr, int base=10) const
Returns the byte array converted to an {unsigned long long} using base base, which is ten by default.
qlonglong toLongLong(bool *ok=nullptr, int base=10) const
Returns the byte array converted to a {long long} using base base, which is ten by default.
char * iterator
This typedef provides an STL-style non-const iterator for QByteArray.
Definition qbytearray.h:437
char * qstrncpy(char *dst, const char *src, size_t len)
A safe strncpy() function.
QByteArray & prepend(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qbytearray.h:280
size_t qstrlen(const char *str)
A safe strlen() function.
QByteArray repeated(qsizetype times) const
QDataStream & operator<<(QDataStream &out, const QByteArray &ba)
Writes byte array ba to the stream out and returns a reference to the stream.
QDataStream & operator>>(QDataStream &in, QByteArray &ba)
Reads a byte array into ba from the stream in and returns a reference to the stream.
QByteArray & operator=(const QByteArray &) noexcept
Assigns other to this byte array and returns a reference to this byte array.
uint toUInt(bool *ok=nullptr, int base=10) const
Returns the byte array converted to an {unsigned int} using base base, which is ten by default.
QByteArray & fill(char c, qsizetype size=-1)
Sets every byte in the byte array to ch.
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:494
quint16 qChecksum(QByteArrayView data, Qt::ChecksumType standard)
static QByteArray fromHex(const QByteArray &hexEncoded)
Returns a decoded copy of the hex encoded array hexEncoded.
std::string toStdString() const
void reserve(qsizetype size)
Attempts to allocate memory for at least size bytes.
Definition qbytearray.h:634
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
QByteArray & setNum(short, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qbytearray.h:688
int toInt(bool *ok=nullptr, int base=10) const
Returns the byte array converted to an int using base base, which is ten by default.
bool isLower() const
Returns true if this byte array is lowercase, that is, if it's identical to its toLower() folding.
friend qsizetype erase(QByteArray &ba, const T &t)
Definition qbytearray.h:782
QList< QByteArray > split(char sep) const
Splits the byte array into subarrays wherever sep occurs, and returns the list of those arrays.
int qstricmp(const char *str1, const char *str2)
A safe stricmp() function.
static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent='%')
qsizetype indexOf(char c, qsizetype from=0) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void chop(qsizetype n)
Removes n bytes from the end of the byte array.
qsizetype length() const noexcept
Same as size().
Definition qbytearray.h:499
bool isDetached() const
Definition qbytearray.h:627
bool isUpper() const
Returns true if this byte array is uppercase, that is, if it's identical to its toUpper() folding.
static constexpr qsizetype max_size() noexcept
Definition qbytearray.h:485
static QByteArray fromStdString(const std::string &s)
ushort toUShort(bool *ok=nullptr, int base=10) const
Returns the byte array converted to an {unsigned short} using base base, which is ten by default.
iterator end()
Returns an \l{STL-style iterators}{STL-style iterator} pointing just after the last byte in the byte-...
Definition qbytearray.h:447
const char * const_iterator
This typedef provides an STL-style const iterator for QByteArray.
Definition qbytearray.h:438
long toLong(bool *ok=nullptr, int base=10) const
void truncate(qsizetype pos)
Truncates the byte array at index position pos.
double toDouble(bool *ok=nullptr) const
Returns the byte array converted to a double value.
QByteArray percentDecoded(char percent='%') const
static QByteArray fromBase64(const QByteArray &base64, Base64Options options=Base64Encoding)
@ Base64UrlEncoding
Definition qbytearray.h:74
@ AbortOnBase64DecodingErrors
Definition qbytearray.h:80
@ OmitTrailingEquals
Definition qbytearray.h:77
QByteArray toPercentEncoding(const QByteArray &exclude=QByteArray(), const QByteArray &include=QByteArray(), char percent='%') const
int qstrnicmp(const char *str1, const char *str2, size_t len)
A safe strnicmp() function.
void swap(QByteArray &other) noexcept
Definition qbytearray.h:104
QByteArray & insert(qsizetype i, QByteArrayView data)
bool contains(char c) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qbytearray.h:660
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:107
constexpr QByteArray() noexcept
Constructs an empty byte array.
Definition qbytearray.h:597
short toShort(bool *ok=nullptr, int base=10) const
Returns the byte array converted to a short using base base, which is ten by default.
void detach()
Definition qbytearray.h:625
const_iterator cbegin() const noexcept
Definition qbytearray.h:445
ulong toULong(bool *ok=nullptr, int base=10) const
static QByteArray number(int, int base=10)
Returns a byte-array representing the whole number n as text.
float toFloat(bool *ok=nullptr) const
Returns the byte array converted to a float value.
char * qstrcpy(char *dst, const char *src)
Copies all the characters up to and including the '\0' from src into dst and returns a pointer to dst...
QByteArray leftJustified(qsizetype width, char fill=' ', bool truncate=false) const
Returns a byte array of size width that contains this byte array padded with the fill byte.
QByteArrayData DataPointer
Definition qbytearray.h:59
void clear()
Clears the contents of the byte array and makes it null.
int qstrcmp(const char *str1, const char *str2)
A safe strcmp() function.
QByteArray rightJustified(qsizetype width, char fill=' ', bool truncate=false) const
Returns a byte array of size width that contains the fill byte followed by this byte array.
QByteArray last(qsizetype n) const &
Definition qbytearray.h:198
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first byte in the byte-array.
Definition qbytearray.h:443
qsizetype capacity() const
Returns the maximum number of bytes that can be stored in the byte array without forcing a reallocati...
Definition qbytearray.h:632
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
QByteArray & remove(qsizetype index, qsizetype len)
Removes len bytes from the array, starting at index position pos, and returns a reference to the arra...
QByteArray & append(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QByteArray toBase64(Base64Options options=Base64Encoding) const
char * qstrdup(const char *src)
Returns a duplicate string.
qsizetype count(char c) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
void resizeForOverwrite(qsizetype size)
QByteArray mid(qsizetype index, qsizetype len=-1) const &
QByteArray & setRawData(const char *a, qsizetype n)
QByteArray toHex(char separator='\0') const
Returns a hex encoded copy of the byte array.
bool isNull() const noexcept
Returns true if this byte array is null; otherwise returns false.
static FromBase64Result fromBase64Encoding(QByteArray &&base64, Base64Options options=Base64Encoding)
QByteArray & assign(QByteArrayView v)
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:409
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qbytearray.h:339
\inmodule QtCore\reentrant
Definition qdatastream.h:46
void append(parameter_type t)
Definition qlist.h:458
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1240
QByteArray copyToQByteArray() const
Definition qstdweb.cpp:672
static Uint8Array copyFrom(const char *buffer, uint32_t size)
Definition qstdweb.cpp:690
QString str
[2]
a resize(100000)
Combined button and popup list for selecting options.
constexpr int caseCompareAscii(char lhs, char rhs) noexcept
Definition qtools_p.h:97
constexpr char toHexUpper(char32_t value) noexcept
Definition qtools_p.h:27
constexpr char toHexLower(char32_t value) noexcept
Definition qtools_p.h:32
constexpr int fromHex(char32_t c) noexcept
Definition qtools_p.h:44
constexpr char toAsciiLower(char ch) noexcept
Definition qtools_p.h:87
\macro QT_NO_KEYWORDS >
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype lastIndexOf(QByteArrayView haystack, qsizetype from, char needle) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool endsWith(QByteArrayView haystack, QByteArrayView needle) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION ParsedNumber< qulonglong > toUnsignedInteger(QByteArrayView data, int base)
qsizetype findByteArray(QByteArrayView haystack, qsizetype from, char needle) noexcept
static constexpr bool q_points_into_range(const T *p, const T *b, const T *e, Cmp less={}) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION QByteArrayView trimmed(QByteArrayView s) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION ParsedNumber< qlonglong > toSignedInteger(QByteArrayView data, int base)
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool startsWith(QByteArrayView haystack, QByteArrayView needle) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype count(QByteArrayView haystack, QByteArrayView needle) noexcept
Q_CORE_EXPORT int compareMemory(QByteArrayView lhs, QByteArrayView rhs)
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION ParsedNumber< float > toFloat(QByteArrayView a) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION ParsedNumber< double > toDouble(QByteArrayView a) noexcept
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isValidUtf8(QByteArrayView s) noexcept
ChecksumType
@ ChecksumIso3309
@ ChecksumItuV41
constexpr Initialization Uninitialized
Initialization
QT_POPCOUNT_RELAXED_CONSTEXPR uint qCountLeadingZeroBits(quint32 v) noexcept
constexpr uint qCountTrailingZeroBits(quint32 v) noexcept
static jboolean copy(JNIEnv *, jobject)
const int blockSize
static constexpr bool isLowerCaseAscii(char c)
static char * qulltoa2(char *p, qulonglong n, int base)
QByteArray qCompress(const uchar *data, qsizetype nbytes, int compressionLevel)
ZLibOp
@ Decompression
@ Compression
static Q_DECL_COLD_FUNCTION QByteArray tooMuchData(ZLibOp op)
static Q_DECL_COLD_FUNCTION QByteArray lengthIsNegative(ZLibOp op)
static Q_DECL_COLD_FUNCTION QByteArray invalidCompressedData()
static qsizetype lastIndexOfCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept
static Q_DECL_COLD_FUNCTION const char * zlibOpAsString(ZLibOp op)
static QByteArray toCase_template(T &input, uchar(*lookup)(uchar))
static Q_DECL_COLD_FUNCTION QByteArray zlibError(ZLibOp op, const char *what)
#define REHASH(a)
static void q_fromPercentEncoding(QByteArray *ba, char percent)
int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char *needle, qsizetype ol, qsizetype from)
static Q_DECL_COLD_FUNCTION QByteArray dataIsNull(ZLibOp op)
static constexpr bool isUpperCaseAscii(char c)
static const quint16 crc_tbl[16]
static QByteArray xxflate(ZLibOp op, QArrayDataPointer< char > out, QByteArrayView input, qxp::function_ref< int(z_stream *) const > init, qxp::function_ref< int(z_stream *, size_t) const > processChunk, qxp::function_ref< void(z_stream *) const > deinit)
qsizetype qFindByteArray(const char *haystack0, qsizetype haystackLen, qsizetype from, const char *needle0, qsizetype needleLen)
quint32 CompressSizeHint_t
static constexpr uchar asciiLower(uchar c)
static qsizetype countCharHelper(QByteArrayView haystack, char needle) noexcept
static Q_DECL_COLD_FUNCTION QByteArray unexpectedZlibError(ZLibOp op, int err, const char *msg)
static constexpr uchar asciiUpper(uchar c)
Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, qsizetype nbytes)
Q_CORE_EXPORT char * qstrcpy(char *dst, const char *src)
QByteArrayView qToByteArrayViewIgnoringNull(const QByteArrayLike &b) noexcept
#define Q_UNLIKELY(x)
#define Q_DECL_COLD_FUNCTION
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
constexpr T qToBigEndian(T source)
Definition qendian.h:172
#define forever
Definition qforeach.h:78
constexpr QtPrivate::QHashMultiReturnType< T... > qHashMulti(size_t seed, const T &... args) noexcept(std::conjunction_v< QtPrivate::QNothrowHashable< T >... >)
NSUInteger capacity
QByteArray qdtoAscii(double d, QLocaleData::DoubleForm form, int precision, bool uppercase)
QSimpleParsedNumber< double > qt_asciiToDouble(const char *num, qsizetype numLen, StrayCharacterMode strayCharMode)
@ WhitespacesAllowed
#define qWarning
Definition qlogging.h:166
return ret
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLint GLfloat GLfloat GLfloat v2
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * v
[13]
const GLfloat * m
GLuint64 key
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLboolean r
[2]
GLuint GLuint end
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLenum GLuint GLenum GLsizei length
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLenum src
GLint GLsizei width
GLint left
GLenum GLenum dst
GLint GLfloat v0
GLenum GLuint GLenum GLsizei const GLchar * buf
GLint GLfloat GLfloat v1
GLuint start
GLenum GLuint GLintptr offset
GLint GLfloat GLfloat GLfloat GLfloat v3
GLint first
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
GLfloat n
GLint GLsizei GLsizei GLenum format
GLsizei GLenum const void * indices
GLfloat GLfloat GLfloat GLfloat h
GLdouble s
[6]
Definition qopenglext.h:235
GLfixed GLfixed u2
GLuint res
const GLubyte * c
GLuint in
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLuint GLenum option
GLenum GLsizei len
GLfixed u1
GLuint num
GLenum GLenum GLenum input
GLenum GLint GLint * precision
static constexpr qint64 HeaderSize
static Q_CONSTINIT QBasicAtomicInteger< unsigned > seed
Definition qrandom.cpp:196
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
static constexpr QChar sep
#define zero
#define s2
#define v1
#define s1
#define v0
static QT_BEGIN_NAMESPACE void init(QTextBoundaryFinder::BoundaryType type, QStringView str, QCharAttributes *attributes)
unsigned int quint32
Definition qtypes.h:50
unsigned char uchar
Definition qtypes.h:32
unsigned short quint16
Definition qtypes.h:48
size_t quintptr
Definition qtypes.h:167
unsigned long ulong
Definition qtypes.h:35
ptrdiff_t qptrdiff
Definition qtypes.h:164
quint64 qulonglong
Definition qtypes.h:64
ptrdiff_t qsizetype
Definition qtypes.h:165
unsigned int uint
Definition qtypes.h:34
long long qint64
Definition qtypes.h:60
unsigned short ushort
Definition qtypes.h:33
qint64 qlonglong
Definition qtypes.h:63
static const uint base
Definition qurlidna.cpp:20
static double toDouble(Value v)
QT_BEGIN_NAMESPACE typedef uchar * output
static int inflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)
Definition qzip.cpp:92
static int deflate(Bytef *dest, ulong *destLen, const Bytef *source, ulong sourceLen)
Definition qzip.cpp:127
QList< int > list
[14]
Q_CHECK_PTR(a=new int[80])
QByteArray ba
[0]
QTextStream out(stdout)
[7]
static const auto matcher
[0]
ba fill(true)
QSharedPointer< T > other(t)
[5]
QQuickView * view
[0]
void detachAndGrow(QArrayData::GrowthPosition where, qsizetype n, const T **data, QArrayDataPointer *old)
qsizetype freeSpaceAtBegin() const noexcept
void setBegin(T *begin) noexcept
qsizetype constAllocatedCapacity() const noexcept
void clear() noexcept(std::is_nothrow_destructible< T >::value)
static QArrayDataPointer allocateGrow(const QArrayDataPointer &from, qsizetype n, QArrayData::GrowthPosition position)
QArrayDataPointer sliced(qsizetype pos, qsizetype n) const &
bool isMutable() const noexcept
static Q_NODISCARD_CTOR QArrayDataPointer fromRawData(const T *rawData, qsizetype length) noexcept
static float convertDoubleToFloat(double d, bool *ok)
Definition qlocale_p.h:309
static QSimpleParsedNumber< quint64 > bytearrayToUnsLongLong(QByteArrayView num, int base)
Definition qlocale.cpp:4524
@ DFSignificantDigits
Definition qlocale_p.h:253
static Q_CORE_EXPORT QSimpleParsedNumber< qint64 > bytearrayToLongLong(QByteArrayView num, int base)
Definition qlocale.cpp:4516
static TrimPositions trimmed_helper_positions(const StringType &str)
static StringType trimmed_helper(StringType &str)
static StringType simplified_helper(StringType &str)
static ValidUtf8Result isValidUtf8(QByteArrayView in)