Qt 6.x
The Qt SDK
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 "qbytearray_p.h"
18#include "qstringconverter_p.h"
19#include <qdatastream.h>
20#include <qmath.h>
21#if defined(Q_OS_WASM)
22#include "private/qstdweb_p.h"
23#endif
24
25#ifndef QT_NO_COMPRESS
26#include <zconf.h>
27#include <zlib.h>
28#include <qxpfunctional.h>
29#endif
30#include <ctype.h>
31#include <limits.h>
32#include <string.h>
33#include <stdlib.h>
34
35#include <algorithm>
36
38
39Q_CONSTINIT const char QByteArray::_empty = '\0';
40
41// ASCII case system, used by QByteArray::to{Upper,Lower}() and qstr(n)icmp():
42static constexpr inline uchar asciiUpper(uchar c)
43{
44 return c >= 'a' && c <= 'z' ? c & ~0x20 : c;
45}
46
47static constexpr inline uchar asciiLower(uchar c)
48{
49 return c >= 'A' && c <= 'Z' ? c | 0x20 : c;
50}
51
53 const char *haystack0, qsizetype haystackLen, qsizetype from,
54 const char *needle0, qsizetype needleLen);
55
56/*****************************************************************************
57 Safe and portable C string functions; extensions to standard string.h
58 *****************************************************************************/
59
72char *qstrdup(const char *src)
73{
74 if (!src)
75 return nullptr;
76 char *dst = new char[strlen(src) + 1];
77 return qstrcpy(dst, src);
78}
79
94char *qstrcpy(char *dst, const char *src)
95{
96 if (!src)
97 return nullptr;
98#ifdef Q_CC_MSVC
99 const size_t len = strlen(src);
100 // This is actually not secure!!! It will be fixed
101 // properly in a later release!
102 if (len >= 0 && strcpy_s(dst, len+1, src) == 0)
103 return dst;
104 return nullptr;
105#else
106 return strcpy(dst, src);
107#endif
108}
109
131char *qstrncpy(char *dst, const char *src, size_t len)
132{
133 if (dst && len > 0) {
134 *dst = '\0';
135 if (src)
136 std::strncat(dst, src, len - 1);
137 }
138 return src ? dst : nullptr;
139}
140
180int qstrcmp(const char *str1, const char *str2)
181{
182 return (str1 && str2) ? strcmp(str1, str2)
183 : (str1 ? 1 : (str2 ? -1 : 0));
184}
185
225int qstricmp(const char *str1, const char *str2)
226{
227 const uchar *s1 = reinterpret_cast<const uchar *>(str1);
228 const uchar *s2 = reinterpret_cast<const uchar *>(str2);
229 if (!s1)
230 return s2 ? -1 : 0;
231 if (!s2)
232 return 1;
233
234 enum { Incomplete = 256 };
235 qptrdiff offset = 0;
236 auto innerCompare = [=, &offset](qptrdiff max, bool unlimited) {
237 max += offset;
238 do {
239 uchar c = s1[offset];
241 return res;
242 if (!c)
243 return 0;
244 ++offset;
245 } while (unlimited || offset < max);
246 return int(Incomplete);
247 };
248
249#if defined(__SSE4_1__) && !(defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer))
250 enum { PageSize = 4096, PageMask = PageSize - 1 };
251 const __m128i zero = _mm_setzero_si128();
252 forever {
253 // Calculate how many bytes we can load until we cross a page boundary
254 // for either source. This isn't an exact calculation, just something
255 // very quick.
258 size_t n = PageSize - ((u1 | u2) & PageMask);
259
260 qptrdiff maxoffset = offset + n;
261 for ( ; offset + 16 <= maxoffset; offset += sizeof(__m128i)) {
262 // load 16 bytes from either source
263 __m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s1 + offset));
264 __m128i b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s2 + offset));
265
266 // compare the two against each other
267 __m128i cmp = _mm_cmpeq_epi8(a, b);
268
269 // find NUL terminators too
270 cmp = _mm_min_epu8(cmp, a);
271 cmp = _mm_cmpeq_epi8(cmp, zero);
272
273 // was there any difference or a NUL?
274 uint mask = _mm_movemask_epi8(cmp);
275 if (mask) {
276 // yes, find out where
278 uint end = sizeof(mask) * 8 - qCountLeadingZeroBits(mask);
279 Q_ASSUME(end >= start);
280 offset += start;
281 n = end - start;
282 break;
283 }
284 }
285
286 // using SIMD could cause a page fault, so iterate byte by byte
287 int res = innerCompare(n, false);
288 if (res != Incomplete)
289 return res;
290 }
291#endif
292
293 return innerCompare(-1, true);
294}
295
315int qstrnicmp(const char *str1, const char *str2, size_t len)
316{
317 const uchar *s1 = reinterpret_cast<const uchar *>(str1);
318 const uchar *s2 = reinterpret_cast<const uchar *>(str2);
319 if (!s1 || !s2)
320 return s1 ? 1 : (s2 ? -1 : 0);
321 for (; len--; ++s1, ++s2) {
322 const uchar c = *s1;
324 return res;
325 if (!c) // strings are equal
326 break;
327 }
328 return 0;
329}
330
339int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
340{
341 Q_ASSERT(len1 >= 0);
342 Q_ASSERT(len2 >= -1);
343 const uchar *s1 = reinterpret_cast<const uchar *>(str1);
344 const uchar *s2 = reinterpret_cast<const uchar *>(str2);
345 if (!s1 || !len1) {
346 if (len2 == 0)
347 return 0;
348 if (len2 == -1)
349 return (!s2 || !*s2) ? 0 : -1;
350 Q_ASSERT(s2);
351 return -1;
352 }
353 if (!s2)
354 return len1 == 0 ? 0 : 1;
355
356 if (len2 == -1) {
357 // null-terminated str2
358 qsizetype i;
359 for (i = 0; i < len1; ++i) {
360 const uchar c = s2[i];
361 if (!c)
362 return 1;
363
365 return res;
366 }
367 return s2[i] ? -1 : 0;
368 } else {
369 // not null-terminated
370 const qsizetype len = qMin(len1, len2);
371 for (qsizetype i = 0; i < len; ++i) {
373 return res;
374 }
375 if (len1 == len2)
376 return 0;
377 return len1 < len2 ? -1 : 1;
378 }
379}
380
385{
386 if (!lhs.isNull() && !rhs.isNull()) {
387 int ret = memcmp(lhs.data(), rhs.data(), qMin(lhs.size(), rhs.size()));
388 if (ret != 0)
389 return ret;
390 }
391
392 // they matched qMin(l1, l2) bytes
393 // so the longer one is lexically after the shorter one
394 return lhs.size() == rhs.size() ? 0 : lhs.size() > rhs.size() ? 1 : -1;
395}
396
401{
403}
404
405// the CRC table below is created by the following piece of code
406#if 0
407static void createCRC16Table() // build CRC16 lookup table
408{
409 unsigned int i;
410 unsigned int j;
411 unsigned short crc_tbl[16];
412 unsigned int v0, v1, v2, v3;
413 for (i = 0; i < 16; i++) {
414 v0 = i & 1;
415 v1 = (i >> 1) & 1;
416 v2 = (i >> 2) & 1;
417 v3 = (i >> 3) & 1;
418 j = 0;
419#undef SET_BIT
420#define SET_BIT(x, b, v) (x) |= (v) << (b)
421 SET_BIT(j, 0, v0);
422 SET_BIT(j, 7, v0);
423 SET_BIT(j, 12, v0);
424 SET_BIT(j, 1, v1);
425 SET_BIT(j, 8, v1);
426 SET_BIT(j, 13, v1);
427 SET_BIT(j, 2, v2);
428 SET_BIT(j, 9, v2);
429 SET_BIT(j, 14, v2);
430 SET_BIT(j, 3, v3);
431 SET_BIT(j, 10, v3);
432 SET_BIT(j, 15, v3);
433 crc_tbl[i] = j;
434 }
435 printf("static const quint16 crc_tbl[16] = {\n");
436 for (int i = 0; i < 16; i +=4)
437 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]);
438 printf("};\n");
439}
440#endif
441
442static const quint16 crc_tbl[16] = {
443 0x0000, 0x1081, 0x2102, 0x3183,
444 0x4204, 0x5285, 0x6306, 0x7387,
445 0x8408, 0x9489, 0xa50a, 0xb58b,
446 0xc60c, 0xd68d, 0xe70e, 0xf78f
447};
448
463{
464 quint16 crc = 0x0000;
465 switch (standard) {
467 crc = 0xffff;
468 break;
470 crc = 0x6363;
471 break;
472 }
473 uchar c;
474 const uchar *p = reinterpret_cast<const uchar *>(data.data());
475 qsizetype len = data.size();
476 while (len--) {
477 c = *p++;
478 crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
479 c >>= 4;
480 crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
481 }
482 switch (standard) {
484 crc = ~crc;
485 break;
487 break;
488 }
489 return crc & 0xffff;
490}
491
522#ifndef QT_NO_COMPRESS
523using CompressSizeHint_t = quint32; // 32-bit BE, historically
524
525enum class ZLibOp : bool { Compression, Decompression };
526
528static const char *zlibOpAsString(ZLibOp op)
529{
530 switch (op) {
531 case ZLibOp::Compression: return "qCompress";
532 case ZLibOp::Decompression: return "qUncompress";
533 }
534 Q_UNREACHABLE_RETURN(nullptr);
535}
536
538static QByteArray zlibError(ZLibOp op, const char *what)
539{
540 qWarning("%s: %s", zlibOpAsString(op), what);
541 return QByteArray();
542}
543
546{
547 return zlibError(op, "Data is null");
548}
549
552{
553 return zlibError(op, "Input length is negative");
554}
555
558{
559 return zlibError(op, "Not enough memory");
560}
561
564{
565 return zlibError(ZLibOp::Decompression, "Input data is corrupted");
566}
567
569static QByteArray unexpectedZlibError(ZLibOp op, int err, const char *msg)
570{
571 qWarning("%s unexpected zlib error: %s (%d)",
572 zlibOpAsString(op),
573 msg ? msg : "",
574 err);
575 return QByteArray();
576}
577
579 qxp::function_ref<int(z_stream *) const> init,
580 qxp::function_ref<int(z_stream *, size_t) const> processChunk,
581 qxp::function_ref<void(z_stream *) const> deinit)
582{
583 if (out.data() == nullptr) // allocation failed
584 return tooMuchData(op);
585 qsizetype capacity = out.allocatedCapacity();
586
587 const auto initalSize = out.size;
588
589 z_stream zs = {};
590 zs.next_in = reinterpret_cast<uchar *>(const_cast<char *>(input.data())); // 1980s C API...
591 if (const int err = init(&zs); err != Z_OK)
592 return unexpectedZlibError(op, err, zs.msg);
593 const auto sg = qScopeGuard([&] { deinit(&zs); });
594
595 using ZlibChunkSize_t = decltype(zs.avail_in);
596 static_assert(!std::is_signed_v<ZlibChunkSize_t>);
597 static_assert(std::is_same_v<ZlibChunkSize_t, decltype(zs.avail_out)>);
598 constexpr auto MaxChunkSize = std::numeric_limits<ZlibChunkSize_t>::max();
599 [[maybe_unused]]
600 constexpr auto MaxStatisticsSize = std::numeric_limits<decltype(zs.total_out)>::max();
601
602 size_t inputLeft = size_t(input.size());
603
604 int res;
605 do {
606 Q_ASSERT(out.freeSpaceAtBegin() == 0); // ensure prepend optimization stays out of the way
607 Q_ASSERT(capacity == out.allocatedCapacity());
608
609 if (zs.avail_out == 0) {
610 Q_ASSERT(size_t(out.size) - initalSize > MaxStatisticsSize || // total_out overflow
611 size_t(out.size) - initalSize == zs.total_out);
612 Q_ASSERT(out.size <= capacity);
613
614 qsizetype avail_out = capacity - out.size;
615 if (avail_out == 0) {
616 out->reallocateAndGrow(QArrayData::GrowsAtEnd, 1); // grow to next natural capacity
617 if (out.data() == nullptr) // reallocation failed
618 return tooMuchData(op);
619 capacity = out.allocatedCapacity();
620 avail_out = capacity - out.size;
621 }
622 zs.next_out = reinterpret_cast<uchar *>(out.data()) + out.size;
623 zs.avail_out = size_t(avail_out) > size_t(MaxChunkSize) ? MaxChunkSize
624 : ZlibChunkSize_t(avail_out);
625 out.size += zs.avail_out;
626
627 Q_ASSERT(zs.avail_out > 0);
628 }
629
630 if (zs.avail_in == 0) {
631 // zs.next_in is kept up-to-date by processChunk(), so nothing to do
632 zs.avail_in = inputLeft > MaxChunkSize ? MaxChunkSize : ZlibChunkSize_t(inputLeft);
633 inputLeft -= zs.avail_in;
634 }
635
636 res = processChunk(&zs, inputLeft);
637 } while (res == Z_OK);
638
639 switch (res) {
640 case Z_STREAM_END:
641 out.size -= zs.avail_out;
642 Q_ASSERT(size_t(out.size) - initalSize > MaxStatisticsSize || // total_out overflow
643 size_t(out.size) - initalSize == zs.total_out);
644 Q_ASSERT(out.size <= out.allocatedCapacity());
645 out.data()[out.size] = '\0';
646 return QByteArray(std::move(out));
647
648 case Z_MEM_ERROR:
649 return tooMuchData(op);
650
651 case Z_BUF_ERROR:
652 Q_UNREACHABLE(); // cannot happen - we supply a buffer that can hold the result,
653 // or else error out early
654
655 case Z_DATA_ERROR: // can only happen on decompression
657 return invalidCompressedData();
658
659 default:
660 return unexpectedZlibError(op, res, zs.msg);
661 }
662}
663
664QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel)
665{
666 constexpr qsizetype HeaderSize = sizeof(CompressSizeHint_t);
667 if (nbytes == 0) {
668 return QByteArray(HeaderSize, '\0');
669 }
670 if (!data)
672
673 if (nbytes < 0)
675
676 if (compressionLevel < -1 || compressionLevel > 9)
677 compressionLevel = -1;
678
679 QArrayDataPointer out = [&] {
680 constexpr qsizetype SingleAllocLimit = 256 * 1024; // the maximum size for which we use
681 // zlib's compressBound() to guarantee
682 // the output buffer size is sufficient
683 // to hold result
685 if (nbytes < SingleAllocLimit) {
686 // use maximum size
687 capacity += compressBound(uLong(nbytes)); // cannot overflow (both times)!
689 }
690
691 // for larger buffers, assume it compresses optimally, and
692 // grow geometrically from there:
693 constexpr qsizetype MaxCompressionFactor = 1024; // max theoretical factor is 1032
694 // cf. http://www.zlib.org/zlib_tech.html,
695 // but use a nearby power-of-two (faster)
696 capacity += std::max(qsizetype(compressBound(uLong(SingleAllocLimit))),
697 nbytes / MaxCompressionFactor);
699 }();
700
701 if (out.data() == nullptr) // allocation failed
703
704 qToBigEndian(qt_saturate<CompressSizeHint_t>(nbytes), out.data());
705 out.size = HeaderSize;
706
707 return xxflate(ZLibOp::Compression, std::move(out), {data, nbytes},
708 [=] (z_stream *zs) { return deflateInit(zs, compressionLevel); },
709 [] (z_stream *zs, size_t inputLeft) {
710 return deflate(zs, inputLeft ? Z_NO_FLUSH : Z_FINISH);
711 },
712 [] (z_stream *zs) { deflateEnd(zs); });
713}
714#endif
715
748#ifndef QT_NO_COMPRESS
757{
758 if (!data)
760
761 if (nbytes < 0)
763
764 constexpr qsizetype HeaderSize = sizeof(CompressSizeHint_t);
765 if (nbytes < HeaderSize)
766 return invalidCompressedData();
767
768 const auto expectedSize = qFromBigEndian<CompressSizeHint_t>(data);
769 if (nbytes == HeaderSize) {
770 if (expectedSize != 0)
771 return invalidCompressedData();
772 return QByteArray();
773 }
774
775 constexpr auto MaxDecompressedSize = size_t(MaxByteArraySize);
776 if constexpr (MaxDecompressedSize < std::numeric_limits<CompressSizeHint_t>::max()) {
777 if (expectedSize > MaxDecompressedSize)
779 }
780
781 // expectedSize may be truncated, so always use at least nbytes
782 // (larger by at most 1%, according to zlib docs)
783 qsizetype capacity = std::max(qsizetype(expectedSize), // cannot overflow!
784 nbytes);
785
787 return xxflate(ZLibOp::Decompression, std::move(d), {data + HeaderSize, nbytes - HeaderSize},
788 [] (z_stream *zs) { return inflateInit(zs); },
789 [] (z_stream *zs, size_t) { return inflate(zs, Z_NO_FLUSH); },
790 [] (z_stream *zs) { inflateEnd(zs); });
791}
792#endif
793
1075
1078
1267{
1268 const auto start = std::distance(cbegin(), first);
1269 const auto len = std::distance(first, last);
1270 remove(start, len);
1271 return begin() + start;
1272}
1273
1326{
1327 d = other.d;
1328 return *this;
1329}
1330
1331
1339{
1340 if (!str) {
1341 d.clear();
1342 } else if (!*str) {
1343 d = DataPointer::fromRawData(&_empty, 0);
1344 } else {
1345 const qsizetype len = qsizetype(strlen(str));
1346 const auto capacityAtEnd = d->allocatedCapacity() - d.freeSpaceAtBegin();
1347 if (d->needsDetach() || len > capacityAtEnd
1348 || (len < size() && len < (capacityAtEnd >> 1)))
1349 // ### inefficient! reallocData() does copy the old data and we then overwrite it in the next line
1350 reallocData(len, QArrayData::KeepSize);
1351 memcpy(d.data(), str, len + 1); // include null terminator
1352 d.size = len;
1353 }
1354 return *this;
1355}
1356
1468
1471
1687{
1688 if (pos < size())
1689 resize(pos);
1690}
1691
1706{
1707 if (n > 0)
1708 resize(size() - n);
1709}
1710
1711
1794{
1795 if (!data) {
1796 d = DataPointer();
1797 } else {
1798 if (size < 0)
1799 size = qstrlen(data);
1800 if (!size) {
1801 d = DataPointer::fromRawData(&_empty, 0);
1802 } else {
1804 Q_CHECK_PTR(d.data());
1805 memcpy(d.data(), data, size);
1806 d.data()[size] = '\0';
1807 }
1808 }
1809}
1810
1818{
1819 if (size <= 0) {
1820 d = DataPointer::fromRawData(&_empty, 0);
1821 } else {
1823 Q_CHECK_PTR(d.data());
1824 memset(d.data(), ch, size);
1825 d.data()[size] = '\0';
1826 }
1827}
1828
1834{
1835 if (size <= 0) {
1836 d = DataPointer::fromRawData(&_empty, 0);
1837 } else {
1839 Q_CHECK_PTR(d.data());
1840 d.data()[size] = '\0';
1841 }
1842}
1843
1860{
1861 if (size < 0)
1862 size = 0;
1863
1864 const auto capacityAtEnd = capacity() - d.freeSpaceAtBegin();
1865 if (d->needsDetach() || size > capacityAtEnd)
1866 reallocData(size, QArrayData::Grow);
1867 d.size = size;
1868 if (d->allocatedCapacity())
1869 d.data()[size] = 0;
1870}
1871
1889void QByteArray::resize(qsizetype newSize, char c)
1890{
1891 const auto old = d.size;
1892 resize(newSize);
1893 if (old < d.size)
1894 memset(d.data() + old, c, d.size - old);
1895}
1896
1908{
1909 resize(size < 0 ? this->size() : size);
1910 if (this->size())
1911 memset(d.data(), ch, this->size());
1912 return *this;
1913}
1914
1915void QByteArray::reallocData(qsizetype alloc, QArrayData::AllocationOption option)
1916{
1917 if (!alloc) {
1918 d = DataPointer::fromRawData(&_empty, 0);
1919 return;
1920 }
1921
1922 // don't use reallocate path when reducing capacity and there's free space
1923 // at the beginning: might shift data pointer outside of allocated space
1924 const bool cannotUseReallocate = d.freeSpaceAtBegin() > 0;
1925
1926 if (d->needsDetach() || cannotUseReallocate) {
1927 DataPointer dd(Data::allocate(alloc, option), qMin(alloc, d.size));
1928 Q_CHECK_PTR(dd.data());
1929 if (dd.size > 0)
1930 ::memcpy(dd.data(), d.data(), dd.size);
1931 dd.data()[dd.size] = 0;
1932 d = dd;
1933 } else {
1934 d->reallocate(alloc, option);
1935 }
1936}
1937
1938void QByteArray::reallocGrowData(qsizetype n)
1939{
1940 if (!n) // expected to always allocate
1941 n = 1;
1942
1943 if (d->needsDetach()) {
1945 Q_CHECK_PTR(dd.data());
1946 dd->copyAppend(d.data(), d.data() + d.size);
1947 dd.data()[dd.size] = 0;
1948 d = dd;
1949 } else {
1950 d->reallocate(d.constAllocatedCapacity() + n, QArrayData::Grow);
1951 }
1952}
1953
1954void QByteArray::expand(qsizetype i)
1955{
1956 resize(qMax(i + 1, size()));
1957}
1958
1984{
1985 if (size() == 0 && ba.size() > d.constAllocatedCapacity() && ba.d.isMutable())
1986 return (*this = ba);
1987 return prepend(QByteArrayView(ba));
1988}
1989
2046{
2047 if (size() == 0 && ba.size() > d->freeSpaceAtEnd() && ba.d.isMutable())
2048 return (*this = ba);
2049 return append(QByteArrayView(ba));
2050}
2051
2100{
2101 d.detachAndGrow(QArrayData::GrowsAtEnd, 1, nullptr, nullptr);
2102 d->copyAppend(1, ch);
2103 d.data()[d.size] = '\0';
2104 return *this;
2105}
2106
2158{
2159 const auto len = v.size();
2160
2161 if (len <= capacity() && isDetached()) {
2162 const auto offset = d.freeSpaceAtBegin();
2163 if (offset)
2164 d.setBegin(d.begin() - offset);
2165 std::memcpy(d.begin(), v.data(), len);
2166 d.size = len;
2167 d.data()[d.size] = '\0';
2168 } else {
2169 *this = v.toByteArray();
2170 }
2171 return *this;
2172}
2173
2187
2191
2195{
2196 const char *str = data.data();
2197 qsizetype size = data.size();
2198 if (i < 0 || size <= 0)
2199 return *this;
2200
2201 // handle this specially, as QArrayDataOps::insert() doesn't handle out of
2202 // bounds positions
2203 if (i >= d->size) {
2204 // In case when data points into the range or is == *this, we need to
2205 // defer a call to free() so that it comes after we copied the data from
2206 // the old memory:
2207 DataPointer detached{}; // construction is free
2208 d.detachAndGrow(Data::GrowsAtEnd, (i - d.size) + size, &str, &detached);
2209 Q_CHECK_PTR(d.data());
2210 d->copyAppend(i - d->size, ' ');
2211 d->copyAppend(str, str + size);
2212 d.data()[d.size] = '\0';
2213 return *this;
2214 }
2215
2218 return insert(i, a);
2219 }
2220
2221 d->insert(i, str, size);
2222 d.data()[d.size] = '\0';
2223 return *this;
2224}
2225
2280{
2281 if (i < 0 || count <= 0)
2282 return *this;
2283
2284 if (i >= d->size) {
2285 // handle this specially, as QArrayDataOps::insert() doesn't handle out of bounds positions
2286 d.detachAndGrow(Data::GrowsAtEnd, (i - d.size) + count, nullptr, nullptr);
2287 Q_CHECK_PTR(d.data());
2288 d->copyAppend(i - d->size, ' ');
2289 d->copyAppend(count, ch);
2290 d.data()[d.size] = '\0';
2291 return *this;
2292 }
2293
2294 d->insert(i, count, ch);
2295 d.data()[d.size] = '\0';
2296 return *this;
2297}
2298
2318{
2319 if (len <= 0 || pos < 0 || size_t(pos) >= size_t(size()))
2320 return *this;
2321 if (pos + len > d->size)
2322 len = d->size - pos;
2323
2324 auto begin = d.begin();
2325 if (!d->isShared()) {
2326 d->erase(begin + pos, len);
2327 d.data()[d.size] = '\0';
2328 } else {
2330 const auto toRemove_start = d.begin() + pos;
2331 copy.d->copyRanges({{d.begin(), toRemove_start},
2332 {toRemove_start + len, d.end()}});
2333 swap(copy);
2334 }
2335 return *this;
2336}
2337
2391{
2392 if (QtPrivate::q_points_into_range(after.data(), d)) {
2393 QVarLengthArray copy(after.data(), after.data() + after.size());
2394 return replace(pos, len, QByteArrayView{copy});
2395 }
2396 if (len == after.size() && (pos + len <= size())) {
2397 // same size: in-place replacement possible
2398 if (len > 0) {
2399 detach();
2400 memcpy(d.data() + pos, after.data(), len*sizeof(char));
2401 }
2402 return *this;
2403 } else {
2404 // ### optimize me
2405 remove(pos, len);
2406 return insert(pos, after);
2407 }
2408}
2409
2442{
2443 const char *b = before.data();
2444 qsizetype bsize = before.size();
2445 const char *a = after.data();
2446 qsizetype asize = after.size();
2447
2448 if (isNull() || (b == a && bsize == asize))
2449 return *this;
2450
2451 // protect against before or after being part of this
2453 QVarLengthArray copy(a, a + asize);
2454 return replace(before, QByteArrayView{copy});
2455 }
2457 QVarLengthArray copy(b, b + bsize);
2458 return replace(QByteArrayView{copy}, after);
2459 }
2460
2461 QByteArrayMatcher matcher(b, bsize);
2462 qsizetype index = 0;
2463 qsizetype len = size();
2464 char *d = data(); // detaches
2465
2466 if (bsize == asize) {
2467 if (bsize) {
2468 while ((index = matcher.indexIn(*this, index)) != -1) {
2469 memcpy(d + index, a, asize);
2470 index += bsize;
2471 }
2472 }
2473 } else if (asize < bsize) {
2474 size_t to = 0;
2475 size_t movestart = 0;
2476 size_t num = 0;
2477 while ((index = matcher.indexIn(*this, index)) != -1) {
2478 if (num) {
2479 qsizetype msize = index - movestart;
2480 if (msize > 0) {
2481 memmove(d + to, d + movestart, msize);
2482 to += msize;
2483 }
2484 } else {
2485 to = index;
2486 }
2487 if (asize) {
2488 memcpy(d + to, a, asize);
2489 to += asize;
2490 }
2491 index += bsize;
2492 movestart = index;
2493 num++;
2494 }
2495 if (num) {
2496 qsizetype msize = len - movestart;
2497 if (msize > 0)
2498 memmove(d + to, d + movestart, msize);
2499 resize(len - num*(bsize-asize));
2500 }
2501 } else {
2502 // the most complex case. We don't want to lose performance by doing repeated
2503 // copies and reallocs of the data.
2504 while (index != -1) {
2505 size_t indices[4096];
2506 size_t pos = 0;
2507 while(pos < 4095) {
2508 index = matcher.indexIn(*this, index);
2509 if (index == -1)
2510 break;
2511 indices[pos++] = index;
2512 index += bsize;
2513 // avoid infinite loop
2514 if (!bsize)
2515 index++;
2516 }
2517 if (!pos)
2518 break;
2519
2520 // we have a table of replacement positions, use them for fast replacing
2521 qsizetype adjust = pos*(asize-bsize);
2522 // index has to be adjusted in case we get back into the loop above.
2523 if (index != -1)
2524 index += adjust;
2525 qsizetype newlen = len + adjust;
2526 qsizetype moveend = len;
2527 if (newlen > len) {
2528 resize(newlen);
2529 len = newlen;
2530 }
2531 d = this->d.data(); // data(), without the detach() check
2532
2533 while(pos) {
2534 pos--;
2535 qsizetype movestart = indices[pos] + bsize;
2536 qsizetype insertstart = indices[pos] + pos*(asize-bsize);
2537 qsizetype moveto = insertstart + asize;
2538 memmove(d + moveto, d + movestart, (moveend - movestart));
2539 if (asize)
2540 memcpy(d + insertstart, a, asize);
2541 moveend = movestart - bsize;
2542 }
2543 }
2544 }
2545 return *this;
2546}
2547
2562QByteArray &QByteArray::replace(char before, char after)
2563{
2564 if (!isEmpty()) {
2565 char *i = data();
2566 char *e = i + size();
2567 for (; i != e; ++i)
2568 if (*i == before)
2569 * i = after;
2570 }
2571 return *this;
2572}
2573
2582{
2584 qsizetype start = 0;
2585 qsizetype end;
2586 while ((end = indexOf(sep, start)) != -1) {
2588 start = end + 1;
2589 }
2590 list.append(mid(start));
2591 return list;
2592}
2593
2606{
2607 if (isEmpty())
2608 return *this;
2609
2610 if (times <= 1) {
2611 if (times == 1)
2612 return *this;
2613 return QByteArray();
2614 }
2615
2616 const qsizetype resultSize = times * size();
2617
2619 result.reserve(resultSize);
2620 if (result.capacity() != resultSize)
2621 return QByteArray(); // not enough memory
2622
2623 memcpy(result.d.data(), data(), size());
2624
2625 qsizetype sizeSoFar = size();
2626 char *end = result.d.data() + sizeSoFar;
2627
2628 const qsizetype halfResultSize = resultSize >> 1;
2629 while (sizeSoFar <= halfResultSize) {
2630 memcpy(end, result.d.data(), sizeSoFar);
2631 end += sizeSoFar;
2632 sizeSoFar <<= 1;
2633 }
2634 memcpy(end, result.d.data(), resultSize - sizeSoFar);
2635 result.d.data()[resultSize] = '\0';
2636 result.d.size = resultSize;
2637 return result;
2638}
2639
2640#define REHASH(a) \
2641 if (ol_minus_1 < sizeof(std::size_t) * CHAR_BIT) \
2642 hashHaystack -= std::size_t(a) << ol_minus_1; \
2643 hashHaystack <<= 1
2644
2645static inline qsizetype findCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept
2646{
2647 if (from < 0)
2648 from = qMax(from + haystack.size(), qsizetype(0));
2649 if (from < haystack.size()) {
2650 const char *const b = haystack.data();
2651 if (const auto n = static_cast<const char *>(
2652 memchr(b + from, needle, static_cast<size_t>(haystack.size() - from)))) {
2653 return n - b;
2654 }
2655 }
2656 return -1;
2657}
2658
2660{
2661 const auto ol = needle.size();
2662 const auto l = haystack.size();
2663 if (ol == 0) {
2664 if (from < 0)
2665 return qMax(from + l, 0);
2666 else
2667 return from > l ? -1 : from;
2668 }
2669
2670 if (ol == 1)
2671 return findCharHelper(haystack, from, needle.front());
2672
2673 if (from > l || ol + from > l)
2674 return -1;
2675
2676 return qFindByteArray(haystack.data(), haystack.size(), from, needle.data(), ol);
2677}
2678
2706{
2707 return qToByteArrayViewIgnoringNull(*this).indexOf(ch, from);
2708}
2709
2710static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char *needle,
2711 qsizetype ol, qsizetype from)
2712{
2713 auto delta = l - ol;
2714 if (from < 0)
2715 from = delta;
2716 if (from < 0 || from > l)
2717 return -1;
2718 if (from > delta)
2719 from = delta;
2720
2721 const char *end = haystack;
2722 haystack += from;
2723 const auto ol_minus_1 = std::size_t(ol - 1);
2724 const char *n = needle + ol_minus_1;
2725 const char *h = haystack + ol_minus_1;
2726 std::size_t hashNeedle = 0, hashHaystack = 0;
2727 qsizetype idx;
2728 for (idx = 0; idx < ol; ++idx) {
2729 hashNeedle = ((hashNeedle<<1) + *(n-idx));
2730 hashHaystack = ((hashHaystack<<1) + *(h-idx));
2731 }
2732 hashHaystack -= *haystack;
2733 while (haystack >= end) {
2734 hashHaystack += *haystack;
2735 if (hashHaystack == hashNeedle && memcmp(needle, haystack, ol) == 0)
2736 return haystack - end;
2737 --haystack;
2738 REHASH(*(haystack + ol));
2739 }
2740 return -1;
2741
2742}
2743
2744static inline qsizetype lastIndexOfCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept
2745{
2746 if (haystack.size() == 0)
2747 return -1;
2748 if (from < 0)
2749 from += haystack.size();
2750 else if (from > haystack.size())
2751 from = haystack.size() - 1;
2752 if (from >= 0) {
2753 const char *b = haystack.data();
2754 const char *n = b + from + 1;
2755 while (n-- != b) {
2756 if (*n == needle)
2757 return n - b;
2758 }
2759 }
2760 return -1;
2761}
2762
2764{
2765 if (haystack.isEmpty()) {
2766 if (needle.isEmpty() && from == 0)
2767 return 0;
2768 return -1;
2769 }
2770 const auto ol = needle.size();
2771 if (ol == 1)
2772 return lastIndexOfCharHelper(haystack, from, needle.front());
2773
2774 return lastIndexOfHelper(haystack.data(), haystack.size(), needle.data(), ol, from);
2775}
2776
2830{
2831 return qToByteArrayViewIgnoringNull(*this).lastIndexOf(ch, from);
2832}
2833
2834static inline qsizetype countCharHelper(QByteArrayView haystack, char needle) noexcept
2835{
2836 qsizetype num = 0;
2837 for (char ch : haystack) {
2838 if (ch == needle)
2839 ++num;
2840 }
2841 return num;
2842}
2843
2845{
2846 if (needle.size() == 0)
2847 return haystack.size() + 1;
2848
2849 if (needle.size() == 1)
2850 return countCharHelper(haystack, needle[0]);
2851
2852 qsizetype num = 0;
2853 qsizetype i = -1;
2854 if (haystack.size() > 500 && needle.size() > 5) {
2855 QByteArrayMatcher matcher(needle);
2856 while ((i = matcher.indexIn(haystack, i + 1)) != -1)
2857 ++num;
2858 } else {
2859 while ((i = haystack.indexOf(needle, i + 1)) != -1)
2860 ++num;
2861 }
2862 return num;
2863}
2864
2883{
2884 return countCharHelper(*this, ch);
2885}
2886
2887#if QT_DEPRECATED_SINCE(6, 4)
2894#endif
2895
2909{
2910 if (haystack.size() < needle.size())
2911 return false;
2912 if (haystack.data() == needle.data() || needle.size() == 0)
2913 return true;
2914 return memcmp(haystack.data(), needle.data(), needle.size()) == 0;
2915}
2916
2938{
2939 if (haystack.size() < needle.size())
2940 return false;
2941 if (haystack.end() == needle.end() || needle.size() == 0)
2942 return true;
2943 return memcmp(haystack.end() - needle.size(), needle.data(), needle.size()) == 0;
2944}
2945
2967/*
2968 Returns true if \a c is an uppercase ASCII letter.
2969 */
2970static constexpr inline bool isUpperCaseAscii(char c)
2971{
2972 return c >= 'A' && c <= 'Z';
2973}
2974
2975/*
2976 Returns true if \a c is an lowercase ASCII letter.
2977 */
2978static constexpr inline bool isLowerCaseAscii(char c)
2979{
2980 return c >= 'a' && c <= 'z';
2981}
2982
2995{
2996 return std::none_of(begin(), end(), isLowerCaseAscii);
2997}
2998
3011{
3012 return std::none_of(begin(), end(), isUpperCaseAscii);
3013}
3014
3040{
3041 if (len >= size())
3042 return *this;
3043 if (len < 0)
3044 len = 0;
3045 return QByteArray(data(), len);
3046}
3047
3062{
3063 if (len >= size())
3064 return *this;
3065 if (len < 0)
3066 len = 0;
3067 return QByteArray(end() - len, len);
3068}
3069
3085{
3086 qsizetype p = pos;
3087 qsizetype l = len;
3088 using namespace QtPrivate;
3089 switch (QContainerImplHelper::mid(size(), &p, &l)) {
3090 case QContainerImplHelper::Null:
3091 return QByteArray();
3092 case QContainerImplHelper::Empty:
3093 {
3094 return QByteArray(DataPointer::fromRawData(&_empty, 0));
3095 }
3096 case QContainerImplHelper::Full:
3097 return *this;
3098 case QContainerImplHelper::Subset:
3099 return QByteArray(d.data() + p, l);
3100 }
3101 Q_UNREACHABLE_RETURN(QByteArray());
3102}
3103
3185template <typename T>
3187{
3188 // find the first bad character in input
3189 const char *orig_begin = input.constBegin();
3190 const char *firstBad = orig_begin;
3191 const char *e = input.constEnd();
3192 for ( ; firstBad != e ; ++firstBad) {
3193 uchar ch = uchar(*firstBad);
3194 uchar converted = lookup(ch);
3195 if (ch != converted)
3196 break;
3197 }
3198
3199 if (firstBad == e)
3200 return std::move(input);
3201
3202 // transform the rest
3203 QByteArray s = std::move(input); // will copy if T is const QByteArray
3204 char *b = s.begin(); // will detach if necessary
3205 char *p = b + (firstBad - orig_begin);
3206 e = b + s.size();
3207 for ( ; p != e; ++p)
3208 *p = char(lookup(uchar(*p)));
3209 return s;
3210}
3211
3212QByteArray QByteArray::toLower_helper(const QByteArray &a)
3213{
3214 return toCase_template(a, asciiLower);
3215}
3216
3217QByteArray QByteArray::toLower_helper(QByteArray &a)
3218{
3219 return toCase_template(a, asciiLower);
3220}
3221
3234QByteArray QByteArray::toUpper_helper(const QByteArray &a)
3235{
3236 return toCase_template(a, asciiUpper);
3237}
3238
3239QByteArray QByteArray::toUpper_helper(QByteArray &a)
3240{
3241 return toCase_template(a, asciiUpper);
3242}
3243
3252{
3253 d.clear();
3254}
3255
3256#if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
3257
3267{
3268 if (ba.isNull() && out.version() >= 6) {
3269 out << (quint32)0xffffffff;
3270 return out;
3271 }
3272 return out.writeBytes(ba.constData(), ba.size());
3273}
3274
3284{
3285 ba.clear();
3286 quint32 len;
3287 in >> len;
3288 if (len == 0xffffffff) { // null byte-array
3289 ba = QByteArray();
3290 return in;
3291 }
3292
3293 const quint32 Step = 1024 * 1024;
3294 quint32 allocated = 0;
3295
3296 do {
3297 qsizetype blockSize = qMin(Step, len - allocated);
3298 ba.resize(allocated + blockSize);
3299 if (in.readRawData(ba.data() + allocated, blockSize) != blockSize) {
3300 ba.clear();
3301 in.setStatus(QDataStream::ReadPastEnd);
3302 return in;
3303 }
3304 allocated += blockSize;
3305 } while (allocated < len);
3306
3307 return in;
3308}
3309#endif // QT_NO_DATASTREAM
3310
3619QByteArray QByteArray::simplified_helper(const QByteArray &a)
3620{
3622}
3623
3624QByteArray QByteArray::simplified_helper(QByteArray &a)
3625{
3627}
3628
3648QByteArray QByteArray::trimmed_helper(const QByteArray &a)
3649{
3651}
3652
3653QByteArray QByteArray::trimmed_helper(QByteArray &a)
3654{
3656}
3657
3659{
3660 auto start = view.begin();
3661 auto stop = view.end();
3663 return QByteArrayView(start, stop);
3664}
3665
3685{
3687 qsizetype len = size();
3688 qsizetype padlen = width - len;
3689 if (padlen > 0) {
3690 result.resize(len+padlen);
3691 if (len)
3692 memcpy(result.d.data(), data(), len);
3693 memset(result.d.data()+len, fill, padlen);
3694 } else {
3695 if (truncate)
3696 result = left(width);
3697 else
3698 result = *this;
3699 }
3700 return result;
3701}
3702
3722{
3724 qsizetype len = size();
3725 qsizetype padlen = width - len;
3726 if (padlen > 0) {
3727 result.resize(len+padlen);
3728 if (len)
3729 memcpy(result.d.data()+padlen, data(), len);
3730 memset(result.d.data(), fill, padlen);
3731 } else {
3732 if (truncate)
3733 result = left(width);
3734 else
3735 result = *this;
3736 }
3737 return result;
3738}
3739
3741{
3742#if defined(QT_CHECK_RANGE)
3743 if (base != 0 && (base < 2 || base > 36)) {
3744 qWarning("QByteArray::toIntegral: Invalid base %d", base);
3745 base = 10;
3746 }
3747#endif
3748 if (data.isEmpty())
3749 return {};
3750
3751 bool ok = false;
3753 if (ok)
3754 return ParsedNumber(i);
3755 return {};
3756}
3757
3759{
3760#if defined(QT_CHECK_RANGE)
3761 if (base != 0 && (base < 2 || base > 36)) {
3762 qWarning("QByteArray::toIntegral: Invalid base %d", base);
3763 base = 10;
3764 }
3765#endif
3766 if (data.isEmpty())
3767 return {};
3768
3769 bool ok = false;
3771 if (ok)
3772 return ParsedNumber(u);
3773 return {};
3774}
3775
3802{
3803 return QtPrivate::toIntegral<qlonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3804}
3805
3832{
3833 return QtPrivate::toIntegral<qulonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3834}
3835
3863int QByteArray::toInt(bool *ok, int base) const
3864{
3865 return QtPrivate::toIntegral<int>(qToByteArrayViewIgnoringNull(*this), ok, base);
3866}
3867
3894{
3895 return QtPrivate::toIntegral<uint>(qToByteArrayViewIgnoringNull(*this), ok, base);
3896}
3897
3926long QByteArray::toLong(bool *ok, int base) const
3927{
3928 return QtPrivate::toIntegral<long>(qToByteArrayViewIgnoringNull(*this), ok, base);
3929}
3930
3958{
3959 return QtPrivate::toIntegral<ulong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3960}
3961
3987short QByteArray::toShort(bool *ok, int base) const
3988{
3989 return QtPrivate::toIntegral<short>(qToByteArrayViewIgnoringNull(*this), ok, base);
3990}
3991
4018{
4019 return QtPrivate::toIntegral<ushort>(qToByteArrayViewIgnoringNull(*this), ok, base);
4020}
4021
4047double QByteArray::toDouble(bool *ok) const
4048{
4049 return QByteArrayView(*this).toDouble(ok);
4050}
4051
4053{
4054 auto r = qt_asciiToDouble(a.data(), a.size(), WhitespacesAllowed);
4055 if (r.ok())
4056 return ParsedNumber{r.result};
4057 else
4058 return {};
4059}
4060
4086float QByteArray::toFloat(bool *ok) const
4087{
4089}
4090
4092{
4093 if (const auto r = toDouble(a)) {
4094 bool ok = true;
4095 const auto f = QLocaleData::convertDoubleToFloat(*r, &ok);
4096 if (ok)
4097 return ParsedNumber(f);
4098 }
4099 return {};
4100}
4101
4113QByteArray QByteArray::toBase64(Base64Options options) const
4114{
4115 const char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
4116 "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
4117 const char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
4118 "ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
4119 const char *const alphabet = options & Base64UrlEncoding ? alphabet_base64url : alphabet_base64;
4120 const char padchar = '=';
4121 qsizetype padlen = 0;
4122
4123 const qsizetype sz = size();
4124
4125 QByteArray tmp((sz + 2) / 3 * 4, Qt::Uninitialized);
4126
4127 qsizetype i = 0;
4128 char *out = tmp.data();
4129 while (i < sz) {
4130 // encode 3 bytes at a time
4131 int chunk = 0;
4132 chunk |= int(uchar(data()[i++])) << 16;
4133 if (i == sz) {
4134 padlen = 2;
4135 } else {
4136 chunk |= int(uchar(data()[i++])) << 8;
4137 if (i == sz)
4138 padlen = 1;
4139 else
4140 chunk |= int(uchar(data()[i++]));
4141 }
4142
4143 int j = (chunk & 0x00fc0000) >> 18;
4144 int k = (chunk & 0x0003f000) >> 12;
4145 int l = (chunk & 0x00000fc0) >> 6;
4146 int m = (chunk & 0x0000003f);
4147 *out++ = alphabet[j];
4148 *out++ = alphabet[k];
4149
4150 if (padlen > 1) {
4151 if ((options & OmitTrailingEquals) == 0)
4152 *out++ = padchar;
4153 } else {
4154 *out++ = alphabet[l];
4155 }
4156 if (padlen > 0) {
4157 if ((options & OmitTrailingEquals) == 0)
4158 *out++ = padchar;
4159 } else {
4160 *out++ = alphabet[m];
4161 }
4162 }
4163 Q_ASSERT((options & OmitTrailingEquals) || (out == tmp.size() + tmp.data()));
4164 if (options & OmitTrailingEquals)
4165 tmp.truncate(out - tmp.data());
4166 return tmp;
4167}
4168
4224static char *qulltoa2(char *p, qulonglong n, int base)
4225{
4226#if defined(QT_CHECK_RANGE)
4227 if (base < 2 || base > 36) {
4228 qWarning("QByteArray::setNum: Invalid base %d", base);
4229 base = 10;
4230 }
4231#endif
4232 const char b = 'a' - 10;
4233 do {
4234 const int c = n % base;
4235 n /= base;
4236 *--p = c + (c < 10 ? '0' : b);
4237 } while (n);
4238
4239 return p;
4240}
4241
4248{
4249 const int buffsize = 66; // big enough for MAX_ULLONG in base 2
4250 char buff[buffsize];
4251 char *p;
4252
4253 if (n < 0) {
4254 // Take care to avoid overflow on negating min value:
4255 p = qulltoa2(buff + buffsize, qulonglong(-(1 + n)) + 1, base);
4256 *--p = '-';
4257 } else {
4258 p = qulltoa2(buff + buffsize, qulonglong(n), base);
4259 }
4260
4261 clear();
4262 append(p, buffsize - (p - buff));
4263 return *this;
4264}
4265
4273{
4274 const int buffsize = 66; // big enough for MAX_ULLONG in base 2
4275 char buff[buffsize];
4276 char *p = qulltoa2(buff + buffsize, n, base);
4277
4278 clear();
4279 append(p, buffsize - (p - buff));
4280 return *this;
4281}
4282
4296{
4297 return *this = QByteArray::number(n, format, precision);
4298}
4299
4330{
4331 QByteArray s;
4332 s.setNum(n, base);
4333 return s;
4334}
4335
4342{
4343 QByteArray s;
4344 s.setNum(n, base);
4345 return s;
4346}
4347
4354{
4355 QByteArray s;
4356 s.setNum(n, base);
4357 return s;
4358}
4359
4366{
4367 QByteArray s;
4368 s.setNum(n, base);
4369 return s;
4370}
4371
4378{
4379 QByteArray s;
4380 s.setNum(n, base);
4381 return s;
4382}
4383
4390{
4391 QByteArray s;
4392 s.setNum(n, base);
4393 return s;
4394}
4395
4409{
4411
4413 case 'f':
4415 break;
4416 case 'e':
4418 break;
4419 case 'g':
4421 break;
4422 default:
4423#if defined(QT_CHECK_RANGE)
4424 qWarning("QByteArray::setNum: Invalid format char '%c'", format);
4425#endif
4426 break;
4427 }
4428
4430}
4431
4483{
4484 if (!data || !size)
4485 clear();
4486 else
4487 *this = fromRawData(data, size);
4488 return *this;
4489}
4490
4491namespace {
4492struct fromBase64_helper_result {
4493 qsizetype decodedLength;
4495};
4496
4497fromBase64_helper_result fromBase64_helper(const char *input, qsizetype inputSize,
4498 char *output /* may alias input */,
4499 QByteArray::Base64Options options)
4500{
4501 fromBase64_helper_result result{ 0, QByteArray::Base64DecodingStatus::Ok };
4502
4503 unsigned int buf = 0;
4504 int nbits = 0;
4505
4506 qsizetype offset = 0;
4507 for (qsizetype i = 0; i < inputSize; ++i) {
4508 int ch = input[i];
4509 int d;
4510
4511 if (ch >= 'A' && ch <= 'Z') {
4512 d = ch - 'A';
4513 } else if (ch >= 'a' && ch <= 'z') {
4514 d = ch - 'a' + 26;
4515 } else if (ch >= '0' && ch <= '9') {
4516 d = ch - '0' + 52;
4517 } else if (ch == '+' && (options & QByteArray::Base64UrlEncoding) == 0) {
4518 d = 62;
4519 } else if (ch == '-' && (options & QByteArray::Base64UrlEncoding) != 0) {
4520 d = 62;
4521 } else if (ch == '/' && (options & QByteArray::Base64UrlEncoding) == 0) {
4522 d = 63;
4523 } else if (ch == '_' && (options & QByteArray::Base64UrlEncoding) != 0) {
4524 d = 63;
4525 } else {
4527 if (ch == '=') {
4528 // can have 1 or 2 '=' signs, in both cases padding base64Size to
4529 // a multiple of 4. Any other case is illegal.
4530 if ((inputSize % 4) != 0) {
4532 return result;
4533 } else if ((i == inputSize - 1) ||
4534 (i == inputSize - 2 && input[++i] == '=')) {
4535 d = -1; // ... and exit the loop, normally
4536 } else {
4538 return result;
4539 }
4540 } else {
4542 return result;
4543 }
4544 } else {
4545 d = -1;
4546 }
4547 }
4548
4549 if (d != -1) {
4550 buf = (buf << 6) | d;
4551 nbits += 6;
4552 if (nbits >= 8) {
4553 nbits -= 8;
4554 Q_ASSERT(offset < i);
4555 output[offset++] = buf >> nbits;
4556 buf &= (1 << nbits) - 1;
4557 }
4558 }
4559 }
4560
4561 result.decodedLength = offset;
4562 return result;
4563}
4564} // anonymous namespace
4565
4594{
4595 // try to avoid a detach when calling data(), as it would over-allocate
4596 // (we need less space when decoding than the one required by the full copy)
4597 if (base64.isDetached()) {
4598 const auto base64result = fromBase64_helper(base64.data(),
4599 base64.size(),
4600 base64.data(), // in-place
4601 options);
4602 base64.truncate(base64result.decodedLength);
4603 return { std::move(base64), base64result.status };
4604 }
4605
4606 return fromBase64Encoding(base64, options);
4607}
4608
4609
4611{
4612 const auto base64Size = base64.size();
4613 QByteArray result((base64Size * 3) / 4, Qt::Uninitialized);
4614 const auto base64result = fromBase64_helper(base64.data(),
4615 base64Size,
4616 const_cast<char *>(result.constData()),
4617 options);
4618 result.truncate(base64result.decodedLength);
4619 return { std::move(result), base64result.status };
4620}
4621
4646QByteArray QByteArray::fromBase64(const QByteArray &base64, Base64Options options)
4647{
4648 if (auto result = fromBase64Encoding(base64, options))
4649 return std::move(result.decoded);
4650 return QByteArray();
4651}
4652
4665{
4666 QByteArray res((hexEncoded.size() + 1)/ 2, Qt::Uninitialized);
4667 uchar *result = (uchar *)res.data() + res.size();
4668
4669 bool odd_digit = true;
4670 for (qsizetype i = hexEncoded.size() - 1; i >= 0; --i) {
4671 uchar ch = uchar(hexEncoded.at(i));
4672 int tmp = QtMiscUtils::fromHex(ch);
4673 if (tmp == -1)
4674 continue;
4675 if (odd_digit) {
4676 --result;
4677 *result = tmp;
4678 odd_digit = false;
4679 } else {
4680 *result |= tmp << 4;
4681 odd_digit = true;
4682 }
4683 }
4684
4685 res.remove(0, result - (const uchar *)res.constData());
4686 return res;
4687}
4688
4703QByteArray QByteArray::toHex(char separator) const
4704{
4705 if (isEmpty())
4706 return QByteArray();
4707
4708 const qsizetype length = separator ? (size() * 3 - 1) : (size() * 2);
4710 char *hexData = hex.data();
4711 const uchar *data = (const uchar *)this->data();
4712 for (qsizetype i = 0, o = 0; i < size(); ++i) {
4713 hexData[o++] = QtMiscUtils::toHexLower(data[i] >> 4);
4714 hexData[o++] = QtMiscUtils::toHexLower(data[i] & 0xf);
4715
4716 if ((separator) && (o < length))
4717 hexData[o++] = separator;
4718 }
4719 return hex;
4720}
4721
4722static void q_fromPercentEncoding(QByteArray *ba, char percent)
4723{
4724 if (ba->isEmpty())
4725 return;
4726
4727 char *data = ba->data();
4728 const char *inputPtr = data;
4729
4730 qsizetype i = 0;
4731 qsizetype len = ba->size();
4732 qsizetype outlen = 0;
4733 int a, b;
4734 char c;
4735 while (i < len) {
4736 c = inputPtr[i];
4737 if (c == percent && i + 2 < len) {
4738 a = inputPtr[++i];
4739 b = inputPtr[++i];
4740
4741 if (a >= '0' && a <= '9') a -= '0';
4742 else if (a >= 'a' && a <= 'f') a = a - 'a' + 10;
4743 else if (a >= 'A' && a <= 'F') a = a - 'A' + 10;
4744
4745 if (b >= '0' && b <= '9') b -= '0';
4746 else if (b >= 'a' && b <= 'f') b = b - 'a' + 10;
4747 else if (b >= 'A' && b <= 'F') b = b - 'A' + 10;
4748
4749 *data++ = (char)((a << 4) | b);
4750 } else {
4751 *data++ = c;
4752 }
4753
4754 ++i;
4755 ++outlen;
4756 }
4757
4758 if (outlen != len)
4759 ba->truncate(outlen);
4760}
4761
4781{
4782 if (isEmpty())
4783 return *this; // Preserves isNull().
4784
4785 QByteArray tmp = *this;
4786 q_fromPercentEncoding(&tmp, percent);
4787 return tmp;
4788}
4789
4805{
4806 return input.percentDecoded(percent);
4807}
4808
4817{
4818 return QByteArray(s.data(), qsizetype(s.size()));
4819}
4820
4833std::string QByteArray::toStdString() const
4834{
4835 return std::string(data(), size_t(size()));
4836}
4837
4863 char percent) const
4864{
4865 if (isNull())
4866 return QByteArray(); // preserve null
4867 if (isEmpty())
4868 return QByteArray(data(), 0);
4869
4870 const auto contains = [](const QByteArray &view, char c) {
4871 // As view.contains(c), but optimised to bypass a lot of overhead:
4872 return view.size() > 0 && memchr(view.data(), c, view.size()) != nullptr;
4873 };
4874
4875 QByteArray result = *this;
4876 char *output = nullptr;
4877 qsizetype length = 0;
4878
4879 for (unsigned char c : *this) {
4880 if (char(c) != percent
4881 && ((c >= 0x61 && c <= 0x7A) // ALPHA
4882 || (c >= 0x41 && c <= 0x5A) // ALPHA
4883 || (c >= 0x30 && c <= 0x39) // DIGIT
4884 || c == 0x2D // -
4885 || c == 0x2E // .
4886 || c == 0x5F // _
4887 || c == 0x7E // ~
4888 || contains(exclude, c))
4889 && !contains(include, c)) {
4890 if (output)
4891 output[length] = c;
4892 ++length;
4893 } else {
4894 if (!output) {
4895 // detach now
4896 result.resize(size() * 3); // worst case
4897 output = result.data();
4898 }
4899 output[length++] = percent;
4900 output[length++] = QtMiscUtils::toHexUpper((c & 0xf0) >> 4);
4902 }
4903 }
4904 if (output)
4905 result.truncate(length);
4906
4907 return result;
4908}
4909
4910#if defined(Q_OS_WASM) || defined(Q_QDOC)
4911
4935QByteArray QByteArray::fromEcmaUint8Array(emscripten::val uint8array)
4936{
4937 return qstdweb::Uint8Array(uint8array).copyToQByteArray();
4938}
4939
4957emscripten::val QByteArray::toEcmaUint8Array()
4958{
4959 return qstdweb::Uint8Array::copyFrom(*this).val();
4960}
4961
4962#endif
4963
5060#if QT_DEPRECATED_SINCE(6, 8)
5084#endif // QT_DEPRECATED_SINCE(6, 8)
5085
5185size_t qHash(const QByteArray::FromBase64Result &key, size_t seed) noexcept
5186{
5187 return qHashMulti(seed, key.decoded, static_cast<int>(key.decodingStatus));
5188}
5189
5212
5213#undef REHASH
\inmodule QtCore
constexpr bool isNull() const noexcept
constexpr qsizetype size() const noexcept
qsizetype lastIndexOf(QByteArrayView a) const noexcept
constexpr const_pointer data() const noexcept
qsizetype indexOf(QByteArrayView a, qsizetype from=0) 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:534
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:422
char * qstrncpy(char *dst, const char *src, size_t len)
A safe strncpy() function.
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first byte in the byte-ar...
Definition qbytearray.h:431
QByteArray & prepend(char c)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qbytearray.h:216
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:474
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
QByteArray last(qsizetype n) const
Definition qbytearray.h:161
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
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:611
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:695
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:479
bool isDetached() const
Definition qbytearray.h:550
bool isUpper() const
Returns true if this byte array is uppercase, that is, if it's identical to its toUpper() folding.
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:432
const char * const_iterator
This typedef provides an STL-style const iterator for QByteArray.
Definition qbytearray.h:423
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 right(qsizetype len) const
Returns a byte array that contains the last len bytes of this byte array.
char at(qsizetype i) const
Returns the byte at index position i in the byte array.
Definition qbytearray.h:523
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:103
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:583
bool isEmpty() const noexcept
Returns true if the byte array has size 0; otherwise returns false.
Definition qbytearray.h:106
constexpr QByteArray() noexcept
Constructs an empty byte array.
Definition qbytearray.h:520
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:548
const_iterator cbegin() const noexcept
Definition qbytearray.h:430
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 left(qsizetype len) const
Returns a byte array that contains the first len bytes of this byte array.
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.
qsizetype lastIndexOf(char c, qsizetype from=-1) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
iterator begin()
Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first byte in the byte-array.
Definition qbytearray.h:428
qsizetype capacity() const
Returns the maximum number of bytes that can be stored in the byte array without forcing a reallocati...
Definition qbytearray.h:555
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...
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.
QByteArray mid(qsizetype index, qsizetype len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos.
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:394
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:275
\inmodule QtCore\reentrant
Definition qdatastream.h:30
Definition qlist.h:74
void append(parameter_type t)
Definition qlist.h:441
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1095
QByteArray copyToQByteArray() const
Definition qstdweb.cpp:712
static Uint8Array copyFrom(const char *buffer, uint32_t size)
Definition qstdweb.cpp:730
emscripten::val val()
Definition qstdweb.cpp:743
QString str
[2]
double e
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_NAMESPACE
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)
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 lastIndexOf(QByteArrayView haystack, qsizetype from, 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 qsizetype findByteArray(QByteArrayView haystack, qsizetype from, QByteArrayView needle) 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 qsizetype findCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept
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)
QT_BEGIN_NAMESPACE constexpr qsizetype MaxByteArraySize
Q_CORE_EXPORT char * qstrcpy(char *dst, const char *src)
QByteArrayView qToByteArrayViewIgnoringNull(const QByteArrayLike &b) noexcept
#define Q_DECL_COLD_FUNCTION
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:162
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
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
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
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
GLfixed GLfixed u2
GLuint res
const GLubyte * c
GLenum GLsizei len
GLuint in
GLuint64EXT * result
[6]
GLdouble s
[6]
Definition qopenglext.h:235
GLfloat GLfloat p
[1]
GLuint GLenum option
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:45
unsigned char uchar
Definition qtypes.h:27
unsigned short quint16
Definition qtypes.h:43
size_t quintptr
Definition qtypes.h:72
unsigned long ulong
Definition qtypes.h:30
ptrdiff_t qptrdiff
Definition qtypes.h:69
quint64 qulonglong
Definition qtypes.h:59
ptrdiff_t qsizetype
Definition qtypes.h:70
unsigned int uint
Definition qtypes.h:29
unsigned short ushort
Definition qtypes.h:28
qint64 qlonglong
Definition qtypes.h:58
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)
bool isShared() const noexcept
qsizetype freeSpaceAtBegin() const noexcept
bool needsDetach() const noexcept
qsizetype allocatedCapacity() noexcept
void setBegin(T *begin) noexcept
qsizetype freeSpaceAtEnd() const 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)
bool isMutable() const noexcept
static Q_NODISCARD_CTOR QArrayDataPointer fromRawData(const T *rawData, qsizetype length) noexcept
static quint64 bytearrayToUnsLongLong(QByteArrayView num, int base, bool *ok)
Definition qlocale.cpp:4361
static float convertDoubleToFloat(double d, bool *ok)
Definition qlocale_p.h:283
@ DFSignificantDigits
Definition qlocale_p.h:228
static Q_CORE_EXPORT qint64 bytearrayToLongLong(QByteArrayView num, int base, bool *ok)
Definition qlocale.cpp:4352
static StringType trimmed_helper(StringType &str)
static void trimmed_helper_positions(const Char *&begin, const Char *&end)
static StringType simplified_helper(StringType &str)
static QPair< QTypedArrayData *, T * > allocate(qsizetype capacity, AllocationOption option=QArrayData::KeepSize)
Definition qarraydata.h:101
static ValidUtf8Result isValidUtf8(QByteArrayView in)
void copyAppend(const T *b, const T *e)
void erase(T *b, qsizetype n)
void insert(qsizetype i, const T *data, qsizetype n)