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
59/*****************************************************************************
60 Safe and portable C string functions; extensions to standard string.h
61 *****************************************************************************/
62
75char *qstrdup(const char *src)
76{
77 if (!src)
78 return nullptr;
79 char *dst = new char[strlen(src) + 1];
80 return qstrcpy(dst, src);
81}
82
97char *qstrcpy(char *dst, const char *src)
98{
99 if (!src)
100 return nullptr;
101#ifdef Q_CC_MSVC
102 const size_t len = strlen(src);
103 // This is actually not secure!!! It will be fixed
104 // properly in a later release!
105 if (len >= 0 && strcpy_s(dst, len+1, src) == 0)
106 return dst;
107 return nullptr;
108#else
109 return strcpy(dst, src);
110#endif
111}
112
134char *qstrncpy(char *dst, const char *src, size_t len)
135{
136 if (dst && len > 0) {
137 *dst = '\0';
138 if (src)
139 std::strncat(dst, src, len - 1);
140 }
141 return src ? dst : nullptr;
142}
143
183int qstrcmp(const char *str1, const char *str2)
184{
185 return (str1 && str2) ? strcmp(str1, str2)
186 : (str1 ? 1 : (str2 ? -1 : 0));
187}
188
228int qstricmp(const char *str1, const char *str2)
229{
230 const uchar *s1 = reinterpret_cast<const uchar *>(str1);
231 const uchar *s2 = reinterpret_cast<const uchar *>(str2);
232 if (!s1)
233 return s2 ? -1 : 0;
234 if (!s2)
235 return 1;
236
237 enum { Incomplete = 256 };
238 qptrdiff offset = 0;
239 auto innerCompare = [=, &offset](qptrdiff max, bool unlimited) {
240 max += offset;
241 do {
242 uchar c = s1[offset];
244 return res;
245 if (!c)
246 return 0;
247 ++offset;
248 } while (unlimited || offset < max);
249 return int(Incomplete);
250 };
251
252#if defined(__SSE4_1__) && !(defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer))
253 enum { PageSize = 4096, PageMask = PageSize - 1 };
254 const __m128i zero = _mm_setzero_si128();
255 forever {
256 // Calculate how many bytes we can load until we cross a page boundary
257 // for either source. This isn't an exact calculation, just something
258 // very quick.
261 size_t n = PageSize - ((u1 | u2) & PageMask);
262
263 qptrdiff maxoffset = offset + n;
264 for ( ; offset + 16 <= maxoffset; offset += sizeof(__m128i)) {
265 // load 16 bytes from either source
266 __m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s1 + offset));
267 __m128i b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s2 + offset));
268
269 // compare the two against each other
270 __m128i cmp = _mm_cmpeq_epi8(a, b);
271
272 // find NUL terminators too
273 cmp = _mm_min_epu8(cmp, a);
274 cmp = _mm_cmpeq_epi8(cmp, zero);
275
276 // was there any difference or a NUL?
277 uint mask = _mm_movemask_epi8(cmp);
278 if (mask) {
279 // yes, find out where
281 uint end = sizeof(mask) * 8 - qCountLeadingZeroBits(mask);
282 Q_ASSERT(end >= start);
283 offset += start;
284 n = end - start;
285 break;
286 }
287 }
288
289 // using SIMD could cause a page fault, so iterate byte by byte
290 int res = innerCompare(n, false);
291 if (res != Incomplete)
292 return res;
293 }
294#endif
295
296 return innerCompare(-1, true);
297}
298
318int qstrnicmp(const char *str1, const char *str2, size_t len)
319{
320 const uchar *s1 = reinterpret_cast<const uchar *>(str1);
321 const uchar *s2 = reinterpret_cast<const uchar *>(str2);
322 if (!s1 || !s2)
323 return s1 ? 1 : (s2 ? -1 : 0);
324 for (; len--; ++s1, ++s2) {
325 const uchar c = *s1;
327 return res;
328 if (!c) // strings are equal
329 break;
330 }
331 return 0;
332}
333
342int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
343{
344 Q_ASSERT(len1 >= 0);
345 Q_ASSERT(len2 >= -1);
346 const uchar *s1 = reinterpret_cast<const uchar *>(str1);
347 const uchar *s2 = reinterpret_cast<const uchar *>(str2);
348 if (!s1 || !len1) {
349 if (len2 == 0)
350 return 0;
351 if (len2 == -1)
352 return (!s2 || !*s2) ? 0 : -1;
353 Q_ASSERT(s2);
354 return -1;
355 }
356 if (!s2)
357 return len1 == 0 ? 0 : 1;
358
359 if (len2 == -1) {
360 // null-terminated str2
361 qsizetype i;
362 for (i = 0; i < len1; ++i) {
363 const uchar c = s2[i];
364 if (!c)
365 return 1;
366
368 return res;
369 }
370 return s2[i] ? -1 : 0;
371 } else {
372 // not null-terminated
373 const qsizetype len = qMin(len1, len2);
374 for (qsizetype i = 0; i < len; ++i) {
376 return res;
377 }
378 if (len1 == len2)
379 return 0;
380 return len1 < len2 ? -1 : 1;
381 }
382}
383
388{
389 if (!lhs.isNull() && !rhs.isNull()) {
390 int ret = memcmp(lhs.data(), rhs.data(), qMin(lhs.size(), rhs.size()));
391 if (ret != 0)
392 return ret;
393 }
394
395 // they matched qMin(l1, l2) bytes
396 // so the longer one is lexically after the shorter one
397 return lhs.size() == rhs.size() ? 0 : lhs.size() > rhs.size() ? 1 : -1;
398}
399
404{
405 return QUtf8::isValidUtf8(s).isValidUtf8;
406}
407
408// the CRC table below is created by the following piece of code
409#if 0
410static void createCRC16Table() // build CRC16 lookup table
411{
412 unsigned int i;
413 unsigned int j;
414 unsigned short crc_tbl[16];
415 unsigned int v0, v1, v2, v3;
416 for (i = 0; i < 16; i++) {
417 v0 = i & 1;
418 v1 = (i >> 1) & 1;
419 v2 = (i >> 2) & 1;
420 v3 = (i >> 3) & 1;
421 j = 0;
422#undef SET_BIT
423#define SET_BIT(x, b, v) (x) |= (v) << (b)
424 SET_BIT(j, 0, v0);
425 SET_BIT(j, 7, v0);
426 SET_BIT(j, 12, v0);
427 SET_BIT(j, 1, v1);
428 SET_BIT(j, 8, v1);
429 SET_BIT(j, 13, v1);
430 SET_BIT(j, 2, v2);
431 SET_BIT(j, 9, v2);
432 SET_BIT(j, 14, v2);
433 SET_BIT(j, 3, v3);
434 SET_BIT(j, 10, v3);
435 SET_BIT(j, 15, v3);
436 crc_tbl[i] = j;
437 }
438 printf("static const quint16 crc_tbl[16] = {\n");
439 for (int i = 0; i < 16; i +=4)
440 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]);
441 printf("};\n");
442}
443#endif
444
445static const quint16 crc_tbl[16] = {
446 0x0000, 0x1081, 0x2102, 0x3183,
447 0x4204, 0x5285, 0x6306, 0x7387,
448 0x8408, 0x9489, 0xa50a, 0xb58b,
449 0xc60c, 0xd68d, 0xe70e, 0xf78f
450};
451
466{
467 quint16 crc = 0x0000;
468 switch (standard) {
470 crc = 0xffff;
471 break;
473 crc = 0x6363;
474 break;
475 }
476 uchar c;
477 const uchar *p = reinterpret_cast<const uchar *>(data.data());
478 qsizetype len = data.size();
479 while (len--) {
480 c = *p++;
481 crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
482 c >>= 4;
483 crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
484 }
485 switch (standard) {
487 crc = ~crc;
488 break;
490 break;
491 }
492 return crc & 0xffff;
493}
494
525#ifndef QT_NO_COMPRESS
526using CompressSizeHint_t = quint32; // 32-bit BE, historically
527
528enum class ZLibOp : bool { Compression, Decompression };
529
531static const char *zlibOpAsString(ZLibOp op)
532{
533 switch (op) {
534 case ZLibOp::Compression: return "qCompress";
535 case ZLibOp::Decompression: return "qUncompress";
536 }
537 Q_UNREACHABLE_RETURN(nullptr);
538}
539
541static QByteArray zlibError(ZLibOp op, const char *what)
542{
543 qWarning("%s: %s", zlibOpAsString(op), what);
544 return QByteArray();
545}
546
549{
550 return zlibError(op, "Data is null");
551}
552
555{
556 return zlibError(op, "Input length is negative");
557}
558
561{
562 return zlibError(op, "Not enough memory");
563}
564
567{
568 return zlibError(ZLibOp::Decompression, "Input data is corrupted");
569}
570
572static QByteArray unexpectedZlibError(ZLibOp op, int err, const char *msg)
573{
574 qWarning("%s unexpected zlib error: %s (%d)",
575 zlibOpAsString(op),
576 msg ? msg : "",
577 err);
578 return QByteArray();
579}
580
581static QByteArray xxflate(ZLibOp op, QArrayDataPointer<char> out, QByteArrayView input,
582 qxp::function_ref<int(z_stream *) const> init,
583 qxp::function_ref<int(z_stream *, size_t) const> processChunk,
584 qxp::function_ref<void(z_stream *) const> deinit)
585{
586 if (out.data() == nullptr) // allocation failed
587 return tooMuchData(op);
588 qsizetype capacity = out.allocatedCapacity();
589
590 const auto initalSize = out.size;
591
592 z_stream zs = {};
593 zs.next_in = reinterpret_cast<uchar *>(const_cast<char *>(input.data())); // 1980s C API...
594 if (const int err = init(&zs); err != Z_OK)
595 return unexpectedZlibError(op, err, zs.msg);
596 const auto sg = qScopeGuard([&] { deinit(&zs); });
597
598 using ZlibChunkSize_t = decltype(zs.avail_in);
599 static_assert(!std::is_signed_v<ZlibChunkSize_t>);
600 static_assert(std::is_same_v<ZlibChunkSize_t, decltype(zs.avail_out)>);
601 constexpr auto MaxChunkSize = std::numeric_limits<ZlibChunkSize_t>::max();
602 [[maybe_unused]]
603 constexpr auto MaxStatisticsSize = std::numeric_limits<decltype(zs.total_out)>::max();
604
605 size_t inputLeft = size_t(input.size());
606
607 int res;
608 do {
609 Q_ASSERT(out.freeSpaceAtBegin() == 0); // ensure prepend optimization stays out of the way
610 Q_ASSERT(capacity == out.allocatedCapacity());
611
612 if (zs.avail_out == 0) {
613 Q_ASSERT(size_t(out.size) - initalSize > MaxStatisticsSize || // total_out overflow
614 size_t(out.size) - initalSize == zs.total_out);
615 Q_ASSERT(out.size <= capacity);
616
617 qsizetype avail_out = capacity - out.size;
618 if (avail_out == 0) {
619 out->reallocateAndGrow(QArrayData::GrowsAtEnd, 1); // grow to next natural capacity
620 if (out.data() == nullptr) // reallocation failed
621 return tooMuchData(op);
622 capacity = out.allocatedCapacity();
623 avail_out = capacity - out.size;
624 }
625 zs.next_out = reinterpret_cast<uchar *>(out.data()) + out.size;
626 zs.avail_out = size_t(avail_out) > size_t(MaxChunkSize) ? MaxChunkSize
627 : ZlibChunkSize_t(avail_out);
628 out.size += zs.avail_out;
629
630 Q_ASSERT(zs.avail_out > 0);
631 }
632
633 if (zs.avail_in == 0) {
634 // zs.next_in is kept up-to-date by processChunk(), so nothing to do
635 zs.avail_in = inputLeft > MaxChunkSize ? MaxChunkSize : ZlibChunkSize_t(inputLeft);
636 inputLeft -= zs.avail_in;
637 }
638
639 res = processChunk(&zs, inputLeft);
640 } while (res == Z_OK);
641
642 switch (res) {
643 case Z_STREAM_END:
644 out.size -= zs.avail_out;
645 Q_ASSERT(size_t(out.size) - initalSize > MaxStatisticsSize || // total_out overflow
646 size_t(out.size) - initalSize == zs.total_out);
647 Q_ASSERT(out.size <= out.allocatedCapacity());
648 out.data()[out.size] = '\0';
649 return QByteArray(std::move(out));
650
651 case Z_MEM_ERROR:
652 return tooMuchData(op);
653
654 case Z_BUF_ERROR:
655 Q_UNREACHABLE(); // cannot happen - we supply a buffer that can hold the result,
656 // or else error out early
657
658 case Z_DATA_ERROR: // can only happen on decompression
660 return invalidCompressedData();
661
662 default:
663 return unexpectedZlibError(op, res, zs.msg);
664 }
665}
666
667QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel)
668{
669 constexpr qsizetype HeaderSize = sizeof(CompressSizeHint_t);
670 if (nbytes == 0) {
671 return QByteArray(HeaderSize, '\0');
672 }
673 if (!data)
675
676 if (nbytes < 0)
678
679 if (compressionLevel < -1 || compressionLevel > 9)
680 compressionLevel = -1;
681
682 QArrayDataPointer out = [&] {
683 constexpr qsizetype SingleAllocLimit = 256 * 1024; // the maximum size for which we use
684 // zlib's compressBound() to guarantee
685 // the output buffer size is sufficient
686 // to hold result
688 if (nbytes < SingleAllocLimit) {
689 // use maximum size
690 capacity += compressBound(uLong(nbytes)); // cannot overflow (both times)!
691 return QArrayDataPointer<char>(capacity);
692 }
693
694 // for larger buffers, assume it compresses optimally, and
695 // grow geometrically from there:
696 constexpr qsizetype MaxCompressionFactor = 1024; // max theoretical factor is 1032
697 // cf. http://www.zlib.org/zlib_tech.html,
698 // but use a nearby power-of-two (faster)
699 capacity += std::max(qsizetype(compressBound(uLong(SingleAllocLimit))),
700 nbytes / MaxCompressionFactor);
701 return QArrayDataPointer<char>(capacity, 0, QArrayData::Grow);
702 }();
703
704 if (out.data() == nullptr) // allocation failed
706
707 qToBigEndian(qt_saturate<CompressSizeHint_t>(nbytes), out.data());
708 out.size = HeaderSize;
709
710 return xxflate(ZLibOp::Compression, std::move(out), {data, nbytes},
711 [=] (z_stream *zs) { return deflateInit(zs, compressionLevel); },
712 [] (z_stream *zs, size_t inputLeft) {
713 return deflate(zs, inputLeft ? Z_NO_FLUSH : Z_FINISH);
714 },
715 [] (z_stream *zs) { deflateEnd(zs); });
716}
717#endif
718
751#ifndef QT_NO_COMPRESS
760{
761 if (!data)
763
764 if (nbytes < 0)
766
767 constexpr qsizetype HeaderSize = sizeof(CompressSizeHint_t);
768 if (nbytes < HeaderSize)
769 return invalidCompressedData();
770
771 const auto expectedSize = qFromBigEndian<CompressSizeHint_t>(data);
772 if (nbytes == HeaderSize) {
773 if (expectedSize != 0)
774 return invalidCompressedData();
775 return QByteArray();
776 }
777
778 constexpr auto MaxDecompressedSize = size_t(QByteArray::max_size());
779 if constexpr (MaxDecompressedSize < std::numeric_limits<CompressSizeHint_t>::max()) {
780 if (expectedSize > MaxDecompressedSize)
782 }
783
784 // expectedSize may be truncated, so always use at least nbytes
785 // (larger by at most 1%, according to zlib docs)
786 qsizetype capacity = std::max(qsizetype(expectedSize), // cannot overflow!
787 nbytes);
788
789 QArrayDataPointer<char> d(capacity);
790 return xxflate(ZLibOp::Decompression, std::move(d), {data + HeaderSize, nbytes - HeaderSize},
791 [] (z_stream *zs) { return inflateInit(zs); },
792 [] (z_stream *zs, size_t) { return inflate(zs, Z_NO_FLUSH); },
793 [] (z_stream *zs) { inflateEnd(zs); });
794}
795#endif
796
1086
1089
1278{
1279 const auto start = std::distance(cbegin(), first);
1280 const auto len = std::distance(first, last);
1281 remove(start, len);
1282 return begin() + start;
1283}
1284
1338{
1339 d = other.d;
1340 return *this;
1341}
1342
1343
1354{
1355 if (!str) {
1356 d.clear();
1357 } else if (!*str) {
1358 d = DataPointer::fromRawData(&_empty, 0);
1359 } else {
1360 assign(str);
1361 }
1362 return *this;
1363}
1364
1485
1488
1704{
1705 if (pos < size())
1706 resize(pos);
1707}
1708
1723{
1724 if (n > 0)
1725 resize(size() - n);
1726}
1727
1728
1811{
1812 if (!data) {
1813 d = DataPointer();
1814 } else {
1815 if (size < 0)
1816 size = qstrlen(data);
1817 if (!size) {
1818 d = DataPointer::fromRawData(&_empty, 0);
1819 } else {
1820 d = DataPointer(size, size);
1821 Q_CHECK_PTR(d.data());
1822 memcpy(d.data(), data, size);
1823 d.data()[size] = '\0';
1824 }
1825 }
1826}
1827
1835{
1836 if (size <= 0) {
1837 d = DataPointer::fromRawData(&_empty, 0);
1838 } else {
1839 d = DataPointer(size, size);
1840 Q_CHECK_PTR(d.data());
1841 memset(d.data(), ch, size);
1842 d.data()[size] = '\0';
1843 }
1844}
1845
1851{
1852 if (size <= 0) {
1853 d = DataPointer::fromRawData(&_empty, 0);
1854 } else {
1855 d = DataPointer(size, size);
1856 Q_CHECK_PTR(d.data());
1857 d.data()[size] = '\0';
1858 }
1859}
1860
1877{
1878 if (size < 0)
1879 size = 0;
1880
1881 const auto capacityAtEnd = capacity() - d.freeSpaceAtBegin();
1882 if (d->needsDetach() || size > capacityAtEnd)
1883 reallocData(size, QArrayData::Grow);
1884 d.size = size;
1885 if (d->allocatedCapacity())
1886 d.data()[size] = 0;
1887}
1888
1906void QByteArray::resize(qsizetype newSize, char c)
1907{
1908 const auto old = d.size;
1909 resize(newSize);
1910 if (old < d.size)
1911 memset(d.data() + old, c, d.size - old);
1912}
1913
1928
1940{
1941 resize(size < 0 ? this->size() : size);
1942 if (this->size())
1943 memset(d.data(), ch, this->size());
1944 return *this;
1945}
1946
1947void QByteArray::reallocData(qsizetype alloc, QArrayData::AllocationOption option)
1948{
1949 if (!alloc) {
1950 d = DataPointer::fromRawData(&_empty, 0);
1951 return;
1952 }
1953
1954 // don't use reallocate path when reducing capacity and there's free space
1955 // at the beginning: might shift data pointer outside of allocated space
1956 const bool cannotUseReallocate = d.freeSpaceAtBegin() > 0;
1957
1958 if (d->needsDetach() || cannotUseReallocate) {
1959 DataPointer dd(alloc, qMin(alloc, d.size), option);
1960 Q_CHECK_PTR(dd.data());
1961 if (dd.size > 0)
1962 ::memcpy(dd.data(), d.data(), dd.size);
1963 dd.data()[dd.size] = 0;
1964 d = dd;
1965 } else {
1966 d->reallocate(alloc, option);
1967 }
1968}
1969
1970void QByteArray::reallocGrowData(qsizetype n)
1971{
1972 if (!n) // expected to always allocate
1973 n = 1;
1974
1975 if (d->needsDetach()) {
1977 Q_CHECK_PTR(dd.data());
1978 dd->copyAppend(d.data(), d.data() + d.size);
1979 dd.data()[dd.size] = 0;
1980 d = dd;
1981 } else {
1982 d->reallocate(d.constAllocatedCapacity() + n, QArrayData::Grow);
1983 }
1984}
1985
1986void QByteArray::expand(qsizetype i)
1987{
1988 resize(qMax(i + 1, size()));
1989}
1990
2016{
2017 if (size() == 0 && ba.size() > d.constAllocatedCapacity() && ba.d.isMutable())
2018 return (*this = ba);
2019 return prepend(QByteArrayView(ba));
2020}
2021
2078{
2079 if (!ba.isNull()) {
2080 if (isNull()) {
2081 if (Q_UNLIKELY(!ba.d.isMutable()))
2082 assign(ba); // fromRawData, so we do a deep copy
2083 else
2084 operator=(ba);
2085 } else if (ba.size()) {
2087 }
2088 }
2089 return *this;
2090}
2091
2140{
2141 d.detachAndGrow(QArrayData::GrowsAtEnd, 1, nullptr, nullptr);
2142 d->copyAppend(1, ch);
2143 d.data()[d.size] = '\0';
2144 return *this;
2145}
2146
2198{
2199 const auto len = v.size();
2200
2201 if (len <= capacity() && isDetached()) {
2202 const auto offset = d.freeSpaceAtBegin();
2203 if (offset)
2204 d.setBegin(d.begin() - offset);
2205 std::memcpy(d.begin(), v.data(), len);
2206 d.size = len;
2207 d.data()[d.size] = '\0';
2208 } else {
2209 *this = v.toByteArray();
2210 }
2211 return *this;
2212}
2213
2227
2231
2235{
2236 const char *str = data.data();
2237 qsizetype size = data.size();
2238 if (i < 0 || size <= 0)
2239 return *this;
2240
2241 // handle this specially, as QArrayDataOps::insert() doesn't handle out of
2242 // bounds positions
2243 if (i >= d->size) {
2244 // In case when data points into the range or is == *this, we need to
2245 // defer a call to free() so that it comes after we copied the data from
2246 // the old memory:
2247 DataPointer detached{}; // construction is free
2248 d.detachAndGrow(Data::GrowsAtEnd, (i - d.size) + size, &str, &detached);
2249 Q_CHECK_PTR(d.data());
2250 d->copyAppend(i - d->size, ' ');
2251 d->copyAppend(str, str + size);
2252 d.data()[d.size] = '\0';
2253 return *this;
2254 }
2255
2256 if (!d->needsDetach() && QtPrivate::q_points_into_range(str, d)) {
2258 return insert(i, a);
2259 }
2260
2261 d->insert(i, str, size);
2262 d.data()[d.size] = '\0';
2263 return *this;
2264}
2265
2320{
2321 if (i < 0 || count <= 0)
2322 return *this;
2323
2324 if (i >= d->size) {
2325 // handle this specially, as QArrayDataOps::insert() doesn't handle out of bounds positions
2326 d.detachAndGrow(Data::GrowsAtEnd, (i - d.size) + count, nullptr, nullptr);
2327 Q_CHECK_PTR(d.data());
2328 d->copyAppend(i - d->size, ' ');
2329 d->copyAppend(count, ch);
2330 d.data()[d.size] = '\0';
2331 return *this;
2332 }
2333
2334 d->insert(i, count, ch);
2335 d.data()[d.size] = '\0';
2336 return *this;
2337}
2338
2358{
2359 if (len <= 0 || pos < 0 || size_t(pos) >= size_t(size()))
2360 return *this;
2361 if (pos + len > d->size)
2362 len = d->size - pos;
2363
2364 auto begin = d.begin();
2365 if (!d->isShared()) {
2366 d->erase(begin + pos, len);
2367 d.data()[d.size] = '\0';
2368 } else {
2370 const auto toRemove_start = d.begin() + pos;
2371 copy.d->copyRanges({{d.begin(), toRemove_start},
2372 {toRemove_start + len, d.end()}});
2373 swap(copy);
2374 }
2375 return *this;
2376}
2377
2431{
2432 if (QtPrivate::q_points_into_range(after.data(), d)) {
2433 QVarLengthArray copy(after.data(), after.data() + after.size());
2434 return replace(pos, len, QByteArrayView{copy});
2435 }
2436 if (len == after.size() && (pos + len <= size())) {
2437 // same size: in-place replacement possible
2438 if (len > 0) {
2439 detach();
2440 memcpy(d.data() + pos, after.data(), len*sizeof(char));
2441 }
2442 return *this;
2443 } else {
2444 // ### optimize me
2445 remove(pos, len);
2446 return insert(pos, after);
2447 }
2448}
2449
2482{
2483 const char *b = before.data();
2484 qsizetype bsize = before.size();
2485 const char *a = after.data();
2486 qsizetype asize = after.size();
2487
2488 if (isNull() || (b == a && bsize == asize))
2489 return *this;
2490
2491 // protect against before or after being part of this
2493 QVarLengthArray copy(a, a + asize);
2494 return replace(before, QByteArrayView{copy});
2495 }
2497 QVarLengthArray copy(b, b + bsize);
2498 return replace(QByteArrayView{copy}, after);
2499 }
2500
2501 QByteArrayMatcher matcher(b, bsize);
2502 qsizetype index = 0;
2503 qsizetype len = size();
2504 char *d = data(); // detaches
2505
2506 if (bsize == asize) {
2507 if (bsize) {
2508 while ((index = matcher.indexIn(*this, index)) != -1) {
2509 memcpy(d + index, a, asize);
2510 index += bsize;
2511 }
2512 }
2513 } else if (asize < bsize) {
2514 size_t to = 0;
2515 size_t movestart = 0;
2516 size_t num = 0;
2517 while ((index = matcher.indexIn(*this, index)) != -1) {
2518 if (num) {
2519 qsizetype msize = index - movestart;
2520 if (msize > 0) {
2521 memmove(d + to, d + movestart, msize);
2522 to += msize;
2523 }
2524 } else {
2525 to = index;
2526 }
2527 if (asize) {
2528 memcpy(d + to, a, asize);
2529 to += asize;
2530 }
2531 index += bsize;
2532 movestart = index;
2533 num++;
2534 }
2535 if (num) {
2536 qsizetype msize = len - movestart;
2537 if (msize > 0)
2538 memmove(d + to, d + movestart, msize);
2539 resize(len - num*(bsize-asize));
2540 }
2541 } else {
2542 // the most complex case. We don't want to lose performance by doing repeated
2543 // copies and reallocs of the data.
2544 while (index != -1) {
2545 size_t indices[4096];
2546 size_t pos = 0;
2547 while(pos < 4095) {
2548 index = matcher.indexIn(*this, index);
2549 if (index == -1)
2550 break;
2551 indices[pos++] = index;
2552 index += bsize;
2553 // avoid infinite loop
2554 if (!bsize)
2555 index++;
2556 }
2557 if (!pos)
2558 break;
2559
2560 // we have a table of replacement positions, use them for fast replacing
2561 qsizetype adjust = pos*(asize-bsize);
2562 // index has to be adjusted in case we get back into the loop above.
2563 if (index != -1)
2564 index += adjust;
2565 qsizetype newlen = len + adjust;
2566 qsizetype moveend = len;
2567 if (newlen > len) {
2568 resize(newlen);
2569 len = newlen;
2570 }
2571 d = this->d.data(); // data(), without the detach() check
2572
2573 while(pos) {
2574 pos--;
2575 qsizetype movestart = indices[pos] + bsize;
2576 qsizetype insertstart = indices[pos] + pos*(asize-bsize);
2577 qsizetype moveto = insertstart + asize;
2578 memmove(d + moveto, d + movestart, (moveend - movestart));
2579 if (asize)
2580 memcpy(d + insertstart, a, asize);
2581 moveend = movestart - bsize;
2582 }
2583 }
2584 }
2585 return *this;
2586}
2587
2602QByteArray &QByteArray::replace(char before, char after)
2603{
2604 if (before != after) {
2605 if (const auto pos = indexOf(before); pos >= 0) {
2606 const auto detachedData = data();
2607 std::replace(detachedData + pos, detachedData + size(), before, after);
2608 }
2609 }
2610 return *this;
2611}
2612
2620QList<QByteArray> QByteArray::split(char sep) const
2621{
2622 QList<QByteArray> list;
2623 qsizetype start = 0;
2624 qsizetype end;
2625 while ((end = indexOf(sep, start)) != -1) {
2627 start = end + 1;
2628 }
2629 list.append(mid(start));
2630 return list;
2631}
2632
2645{
2646 if (isEmpty())
2647 return *this;
2648
2649 if (times <= 1) {
2650 if (times == 1)
2651 return *this;
2652 return QByteArray();
2653 }
2654
2655 const qsizetype resultSize = times * size();
2656
2658 result.reserve(resultSize);
2659 if (result.capacity() != resultSize)
2660 return QByteArray(); // not enough memory
2661
2662 memcpy(result.d.data(), data(), size());
2663
2664 qsizetype sizeSoFar = size();
2665 char *end = result.d.data() + sizeSoFar;
2666
2667 const qsizetype halfResultSize = resultSize >> 1;
2668 while (sizeSoFar <= halfResultSize) {
2669 memcpy(end, result.d.data(), sizeSoFar);
2670 end += sizeSoFar;
2671 sizeSoFar <<= 1;
2672 }
2673 memcpy(end, result.d.data(), resultSize - sizeSoFar);
2674 result.d.data()[resultSize] = '\0';
2675 result.d.size = resultSize;
2676 return result;
2677}
2678
2706static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char *needle,
2707 qsizetype ol, qsizetype from)
2708{
2709 auto delta = l - ol;
2710 if (from < 0)
2711 from = delta;
2712 if (from < 0 || from > l)
2713 return -1;
2714 if (from > delta)
2715 from = delta;
2716
2717 const char *end = haystack;
2718 haystack += from;
2719 const qregisteruint ol_minus_1 = ol - 1;
2720 const char *n = needle + ol_minus_1;
2721 const char *h = haystack + ol_minus_1;
2722 qregisteruint hashNeedle = 0, hashHaystack = 0;
2723 qsizetype idx;
2724 for (idx = 0; idx < ol; ++idx) {
2725 hashNeedle = ((hashNeedle<<1) + *(n-idx));
2726 hashHaystack = ((hashHaystack<<1) + *(h-idx));
2727 }
2728 hashHaystack -= *haystack;
2729 while (haystack >= end) {
2730 hashHaystack += *haystack;
2731 if (hashHaystack == hashNeedle && memcmp(needle, haystack, ol) == 0)
2732 return haystack - end;
2733 --haystack;
2734 if (ol_minus_1 < sizeof(ol_minus_1) * CHAR_BIT)
2735 hashHaystack -= qregisteruint(*(haystack + ol)) << ol_minus_1;
2736 hashHaystack <<= 1;
2737 }
2738 return -1;
2739}
2740
2741static inline qsizetype lastIndexOfCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept
2742{
2743 if (haystack.size() == 0)
2744 return -1;
2745 if (from < 0)
2746 from += haystack.size();
2747 else if (from > haystack.size())
2748 from = haystack.size() - 1;
2749 if (from >= 0) {
2750 const char *b = haystack.data();
2751 const char *n = b + from + 1;
2752 while (n-- != b) {
2753 if (*n == needle)
2754 return n - b;
2755 }
2756 }
2757 return -1;
2758}
2759
2760qsizetype QtPrivate::lastIndexOf(QByteArrayView haystack, qsizetype from, char needle) noexcept
2761{
2762 return lastIndexOfCharHelper(haystack, from, needle);
2763}
2764
2766{
2767 if (haystack.isEmpty()) {
2768 if (needle.isEmpty() && from == 0)
2769 return 0;
2770 return -1;
2771 }
2772 const auto ol = needle.size();
2773 if (ol == 1)
2774 return lastIndexOfCharHelper(haystack, from, needle.front());
2775
2776 return lastIndexOfHelper(haystack.data(), haystack.size(), needle.data(), ol, from);
2777}
2778
2832static inline qsizetype countCharHelper(QByteArrayView haystack, char needle) noexcept
2833{
2834 qsizetype num = 0;
2835 for (char ch : haystack) {
2836 if (ch == needle)
2837 ++num;
2838 }
2839 return num;
2840}
2841
2843{
2844 if (needle.size() == 0)
2845 return haystack.size() + 1;
2846
2847 if (needle.size() == 1)
2848 return countCharHelper(haystack, needle[0]);
2849
2850 qsizetype num = 0;
2851 qsizetype i = -1;
2852 if (haystack.size() > 500 && needle.size() > 5) {
2853 QByteArrayMatcher matcher(needle);
2854 while ((i = matcher.indexIn(haystack, i + 1)) != -1)
2855 ++num;
2856 } else {
2857 while ((i = haystack.indexOf(needle, i + 1)) != -1)
2858 ++num;
2859 }
2860 return num;
2861}
2862
2881{
2882 return countCharHelper(*this, ch);
2883}
2884
2885#if QT_DEPRECATED_SINCE(6, 4)
2892#endif
2893
2907{
2908 if (haystack.size() < needle.size())
2909 return false;
2910 if (haystack.data() == needle.data() || needle.size() == 0)
2911 return true;
2912 return memcmp(haystack.data(), needle.data(), needle.size()) == 0;
2913}
2914
2936{
2937 if (haystack.size() < needle.size())
2938 return false;
2939 if (haystack.end() == needle.end() || needle.size() == 0)
2940 return true;
2941 return memcmp(haystack.end() - needle.size(), needle.data(), needle.size()) == 0;
2942}
2943
2965/*
2966 Returns true if \a c is an uppercase ASCII letter.
2967 */
2968static constexpr inline bool isUpperCaseAscii(char c)
2969{
2970 return c >= 'A' && c <= 'Z';
2971}
2972
2973/*
2974 Returns true if \a c is an lowercase ASCII letter.
2975 */
2976static constexpr inline bool isLowerCaseAscii(char c)
2977{
2978 return c >= 'a' && c <= 'z';
2979}
2980
2993{
2994 return std::none_of(begin(), end(), isLowerCaseAscii);
2995}
2996
3009{
3010 return std::none_of(begin(), end(), isUpperCaseAscii);
3011}
3012
3075{
3076 qsizetype p = pos;
3077 qsizetype l = len;
3078 using namespace QtPrivate;
3079 switch (QContainerImplHelper::mid(size(), &p, &l)) {
3080 case QContainerImplHelper::Null:
3081 return QByteArray();
3082 case QContainerImplHelper::Empty:
3083 {
3084 return QByteArray(DataPointer::fromRawData(&_empty, 0));
3085 }
3086 case QContainerImplHelper::Full:
3087 return *this;
3088 case QContainerImplHelper::Subset:
3089 return sliced(p, l);
3090 }
3091 Q_UNREACHABLE_RETURN(QByteArray());
3092}
3093
3095{
3096 qsizetype p = pos;
3097 qsizetype l = len;
3098 using namespace QtPrivate;
3099 switch (QContainerImplHelper::mid(size(), &p, &l)) {
3100 case QContainerImplHelper::Null:
3101 return QByteArray();
3102 case QContainerImplHelper::Empty:
3103 resize(0); // keep capacity if we've reserve()d
3104 [[fallthrough]];
3105 case QContainerImplHelper::Full:
3106 return std::move(*this);
3107 case QContainerImplHelper::Subset:
3108 return std::move(*this).sliced(p, l);
3109 }
3110 Q_UNREACHABLE_RETURN(QByteArray());
3111}
3112
3159QByteArray QByteArray::sliced_helper(QByteArray &a, qsizetype pos, qsizetype n)
3160{
3161 if (n == 0)
3162 return fromRawData(&_empty, 0);
3163 DataPointer d = std::move(a.d).sliced(pos, n);
3164 d.data()[n] = 0;
3165 return QByteArray(std::move(d));
3166}
3167
3236template <typename T>
3238{
3239 // find the first bad character in input
3240 const char *orig_begin = input.constBegin();
3241 const char *firstBad = orig_begin;
3242 const char *e = input.constEnd();
3243 for ( ; firstBad != e ; ++firstBad) {
3244 uchar ch = uchar(*firstBad);
3245 uchar converted = lookup(ch);
3246 if (ch != converted)
3247 break;
3248 }
3249
3250 if (firstBad == e)
3251 return std::move(input);
3252
3253 // transform the rest
3254 QByteArray s = std::move(input); // will copy if T is const QByteArray
3255 char *b = s.begin(); // will detach if necessary
3256 char *p = b + (firstBad - orig_begin);
3257 e = b + s.size();
3258 for ( ; p != e; ++p)
3259 *p = char(lookup(uchar(*p)));
3260 return s;
3261}
3262
3263QByteArray QByteArray::toLower_helper(const QByteArray &a)
3264{
3265 return toCase_template(a, asciiLower);
3266}
3267
3268QByteArray QByteArray::toLower_helper(QByteArray &a)
3269{
3270 return toCase_template(a, asciiLower);
3271}
3272
3285QByteArray QByteArray::toUpper_helper(const QByteArray &a)
3286{
3287 return toCase_template(a, asciiUpper);
3288}
3289
3290QByteArray QByteArray::toUpper_helper(QByteArray &a)
3291{
3292 return toCase_template(a, asciiUpper);
3293}
3294
3303{
3304 d.clear();
3305}
3306
3307#if !defined(QT_NO_DATASTREAM)
3308
3318{
3319 if (ba.isNull() && out.version() >= 6) {
3320 QDataStream::writeQSizeType(out, -1);
3321 return out;
3322 }
3323 return out.writeBytes(ba.constData(), ba.size());
3324}
3325
3335{
3336 ba.clear();
3337
3338 qint64 size = QDataStream::readQSizeType(in);
3339 qsizetype len = size;
3340 if (size != len || size < -1) {
3341 ba.clear();
3342 in.setStatus(QDataStream::SizeLimitExceeded);
3343 return in;
3344 }
3345 if (len == -1) { // null byte-array
3346 ba = QByteArray();
3347 return in;
3348 }
3349
3350 constexpr qsizetype Step = 1024 * 1024;
3351 qsizetype allocated = 0;
3352
3353 do {
3354 qsizetype blockSize = qMin(Step, len - allocated);
3355 ba.resize(allocated + blockSize);
3356 if (in.readRawData(ba.data() + allocated, blockSize) != blockSize) {
3357 ba.clear();
3358 in.setStatus(QDataStream::ReadPastEnd);
3359 return in;
3360 }
3361 allocated += blockSize;
3362 } while (allocated < len);
3363
3364 return in;
3365}
3366#endif // QT_NO_DATASTREAM
3367
3592QByteArray QByteArray::simplified_helper(const QByteArray &a)
3593{
3595}
3596
3597QByteArray QByteArray::simplified_helper(QByteArray &a)
3598{
3600}
3601
3621QByteArray QByteArray::trimmed_helper(const QByteArray &a)
3622{
3624}
3625
3626QByteArray QByteArray::trimmed_helper(QByteArray &a)
3627{
3629}
3630
3636
3656{
3658 qsizetype len = size();
3659 qsizetype padlen = width - len;
3660 if (padlen > 0) {
3661 result.resize(len+padlen);
3662 if (len)
3663 memcpy(result.d.data(), data(), len);
3664 memset(result.d.data()+len, fill, padlen);
3665 } else {
3666 if (truncate)
3667 result = left(width);
3668 else
3669 result = *this;
3670 }
3671 return result;
3672}
3673
3693{
3695 qsizetype len = size();
3696 qsizetype padlen = width - len;
3697 if (padlen > 0) {
3698 result.resize(len+padlen);
3699 if (len)
3700 memcpy(result.d.data()+padlen, data(), len);
3701 memset(result.d.data(), fill, padlen);
3702 } else {
3703 if (truncate)
3704 result = left(width);
3705 else
3706 result = *this;
3707 }
3708 return result;
3709}
3710
3711auto QtPrivate::toSignedInteger(QByteArrayView data, int base) -> ParsedNumber<qlonglong>
3712{
3713#if defined(QT_CHECK_RANGE)
3714 if (base != 0 && (base < 2 || base > 36)) {
3715 qWarning("QByteArray::toIntegral: Invalid base %d", base);
3716 base = 10;
3717 }
3718#endif
3719 if (data.isEmpty())
3720 return {};
3721
3723 if (r.ok())
3724 return ParsedNumber(r.result);
3725 return {};
3726}
3727
3728auto QtPrivate::toUnsignedInteger(QByteArrayView data, int base) -> ParsedNumber<qulonglong>
3729{
3730#if defined(QT_CHECK_RANGE)
3731 if (base != 0 && (base < 2 || base > 36)) {
3732 qWarning("QByteArray::toIntegral: Invalid base %d", base);
3733 base = 10;
3734 }
3735#endif
3736 if (data.isEmpty())
3737 return {};
3738
3740 if (r.ok())
3741 return ParsedNumber(r.result);
3742 return {};
3743}
3744
3771{
3772 return QtPrivate::toIntegral<qlonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3773}
3774
3801{
3802 return QtPrivate::toIntegral<qulonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3803}
3804
3832int QByteArray::toInt(bool *ok, int base) const
3833{
3834 return QtPrivate::toIntegral<int>(qToByteArrayViewIgnoringNull(*this), ok, base);
3835}
3836
3863{
3864 return QtPrivate::toIntegral<uint>(qToByteArrayViewIgnoringNull(*this), ok, base);
3865}
3866
3895long QByteArray::toLong(bool *ok, int base) const
3896{
3897 return QtPrivate::toIntegral<long>(qToByteArrayViewIgnoringNull(*this), ok, base);
3898}
3899
3927{
3928 return QtPrivate::toIntegral<ulong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3929}
3930
3956short QByteArray::toShort(bool *ok, int base) const
3957{
3958 return QtPrivate::toIntegral<short>(qToByteArrayViewIgnoringNull(*this), ok, base);
3959}
3960
3987{
3988 return QtPrivate::toIntegral<ushort>(qToByteArrayViewIgnoringNull(*this), ok, base);
3989}
3990
4016double QByteArray::toDouble(bool *ok) const
4017{
4018 return QByteArrayView(*this).toDouble(ok);
4019}
4020
4021auto QtPrivate::toDouble(QByteArrayView a) noexcept -> ParsedNumber<double>
4022{
4023 auto r = qt_asciiToDouble(a.data(), a.size(), WhitespacesAllowed);
4024 if (r.ok())
4025 return ParsedNumber{r.result};
4026 else
4027 return {};
4028}
4029
4055float QByteArray::toFloat(bool *ok) const
4056{
4058}
4059
4060auto QtPrivate::toFloat(QByteArrayView a) noexcept -> ParsedNumber<float>
4061{
4062 if (const auto r = toDouble(a)) {
4063 bool ok = true;
4064 const auto f = QLocaleData::convertDoubleToFloat(*r, &ok);
4065 if (ok)
4066 return ParsedNumber(f);
4067 }
4068 return {};
4069}
4070
4082QByteArray QByteArray::toBase64(Base64Options options) const
4083{
4084 constexpr char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
4085 "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
4086 constexpr char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
4087 "ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
4088 const char *const alphabet = options & Base64UrlEncoding ? alphabet_base64url : alphabet_base64;
4089 constexpr char padchar = '=';
4090 qsizetype padlen = 0;
4091
4092 const qsizetype sz = size();
4093
4094 QByteArray tmp((sz + 2) / 3 * 4, Qt::Uninitialized);
4095
4096 qsizetype i = 0;
4097 char *out = tmp.data();
4098 while (i < sz) {
4099 // encode 3 bytes at a time
4100 int chunk = 0;
4101 chunk |= int(uchar(data()[i++])) << 16;
4102 if (i == sz) {
4103 padlen = 2;
4104 } else {
4105 chunk |= int(uchar(data()[i++])) << 8;
4106 if (i == sz)
4107 padlen = 1;
4108 else
4109 chunk |= int(uchar(data()[i++]));
4110 }
4111
4112 int j = (chunk & 0x00fc0000) >> 18;
4113 int k = (chunk & 0x0003f000) >> 12;
4114 int l = (chunk & 0x00000fc0) >> 6;
4115 int m = (chunk & 0x0000003f);
4116 *out++ = alphabet[j];
4117 *out++ = alphabet[k];
4118
4119 if (padlen > 1) {
4120 if ((options & OmitTrailingEquals) == 0)
4121 *out++ = padchar;
4122 } else {
4123 *out++ = alphabet[l];
4124 }
4125 if (padlen > 0) {
4126 if ((options & OmitTrailingEquals) == 0)
4127 *out++ = padchar;
4128 } else {
4129 *out++ = alphabet[m];
4130 }
4131 }
4132 Q_ASSERT((options & OmitTrailingEquals) || (out == tmp.size() + tmp.data()));
4133 if (options & OmitTrailingEquals)
4134 tmp.truncate(out - tmp.data());
4135 return tmp;
4136}
4137
4193static char *qulltoa2(char *p, qulonglong n, int base)
4194{
4195#if defined(QT_CHECK_RANGE)
4196 if (base < 2 || base > 36) {
4197 qWarning("QByteArray::setNum: Invalid base %d", base);
4198 base = 10;
4199 }
4200#endif
4201 constexpr char b = 'a' - 10;
4202 do {
4203 const int c = n % base;
4204 n /= base;
4205 *--p = c + (c < 10 ? '0' : b);
4206 } while (n);
4207
4208 return p;
4209}
4210
4217{
4218 constexpr int buffsize = 66; // big enough for MAX_ULLONG in base 2
4219 char buff[buffsize];
4220 char *p;
4221
4222 if (n < 0) {
4223 // Take care to avoid overflow on negating min value:
4224 p = qulltoa2(buff + buffsize, qulonglong(-(1 + n)) + 1, base);
4225 *--p = '-';
4226 } else {
4227 p = qulltoa2(buff + buffsize, qulonglong(n), base);
4228 }
4229
4230 clear();
4231 append(p, buffsize - (p - buff));
4232 return *this;
4233}
4234
4242{
4243 constexpr int buffsize = 66; // big enough for MAX_ULLONG in base 2
4244 char buff[buffsize];
4245 char *p = qulltoa2(buff + buffsize, n, base);
4246
4247 clear();
4248 append(p, buffsize - (p - buff));
4249 return *this;
4250}
4251
4265{
4266 return *this = QByteArray::number(n, format, precision);
4267}
4268
4299{
4300 QByteArray s;
4301 s.setNum(n, base);
4302 return s;
4303}
4304
4311{
4312 QByteArray s;
4313 s.setNum(n, base);
4314 return s;
4315}
4316
4323{
4324 QByteArray s;
4325 s.setNum(n, base);
4326 return s;
4327}
4328
4335{
4336 QByteArray s;
4337 s.setNum(n, base);
4338 return s;
4339}
4340
4347{
4348 QByteArray s;
4349 s.setNum(n, base);
4350 return s;
4351}
4352
4359{
4360 QByteArray s;
4361 s.setNum(n, base);
4362 return s;
4363}
4364
4378{
4380
4382 case 'f':
4384 break;
4385 case 'e':
4387 break;
4388 case 'g':
4390 break;
4391 default:
4392#if defined(QT_CHECK_RANGE)
4393 qWarning("QByteArray::setNum: Invalid format char '%c'", format);
4394#endif
4395 break;
4396 }
4397
4399}
4400
4452{
4453 if (!data || !size)
4454 clear();
4455 else
4456 *this = fromRawData(data, size);
4457 return *this;
4458}
4459
4460namespace {
4461struct fromBase64_helper_result {
4462 qsizetype decodedLength;
4464};
4465
4466fromBase64_helper_result fromBase64_helper(const char *input, qsizetype inputSize,
4467 char *output /* may alias input */,
4468 QByteArray::Base64Options options)
4469{
4470 fromBase64_helper_result result{ 0, QByteArray::Base64DecodingStatus::Ok };
4471
4472 unsigned int buf = 0;
4473 int nbits = 0;
4474
4475 qsizetype offset = 0;
4476 for (qsizetype i = 0; i < inputSize; ++i) {
4477 int ch = input[i];
4478 int d;
4479
4480 if (ch >= 'A' && ch <= 'Z') {
4481 d = ch - 'A';
4482 } else if (ch >= 'a' && ch <= 'z') {
4483 d = ch - 'a' + 26;
4484 } else if (ch >= '0' && ch <= '9') {
4485 d = ch - '0' + 52;
4486 } else if (ch == '+' && (options & QByteArray::Base64UrlEncoding) == 0) {
4487 d = 62;
4488 } else if (ch == '-' && (options & QByteArray::Base64UrlEncoding) != 0) {
4489 d = 62;
4490 } else if (ch == '/' && (options & QByteArray::Base64UrlEncoding) == 0) {
4491 d = 63;
4492 } else if (ch == '_' && (options & QByteArray::Base64UrlEncoding) != 0) {
4493 d = 63;
4494 } else {
4496 if (ch == '=') {
4497 // can have 1 or 2 '=' signs, in both cases padding base64Size to
4498 // a multiple of 4. Any other case is illegal.
4499 if ((inputSize % 4) != 0) {
4501 return result;
4502 } else if ((i == inputSize - 1) ||
4503 (i == inputSize - 2 && input[++i] == '=')) {
4504 d = -1; // ... and exit the loop, normally
4505 } else {
4507 return result;
4508 }
4509 } else {
4511 return result;
4512 }
4513 } else {
4514 d = -1;
4515 }
4516 }
4517
4518 if (d != -1) {
4519 buf = (buf << 6) | d;
4520 nbits += 6;
4521 if (nbits >= 8) {
4522 nbits -= 8;
4523 Q_ASSERT(offset < i);
4524 output[offset++] = buf >> nbits;
4525 buf &= (1 << nbits) - 1;
4526 }
4527 }
4528 }
4529
4530 result.decodedLength = offset;
4531 return result;
4532}
4533} // anonymous namespace
4534
4563{
4564 // try to avoid a detach when calling data(), as it would over-allocate
4565 // (we need less space when decoding than the one required by the full copy)
4566 if (base64.isDetached()) {
4567 const auto base64result = fromBase64_helper(base64.data(),
4568 base64.size(),
4569 base64.data(), // in-place
4570 options);
4571 base64.truncate(base64result.decodedLength);
4572 return { std::move(base64), base64result.status };
4573 }
4574
4575 return fromBase64Encoding(base64, options);
4576}
4577
4578
4580{
4581 const auto base64Size = base64.size();
4582 QByteArray result((base64Size * 3) / 4, Qt::Uninitialized);
4583 const auto base64result = fromBase64_helper(base64.data(),
4584 base64Size,
4585 const_cast<char *>(result.constData()),
4586 options);
4587 result.truncate(base64result.decodedLength);
4588 return { std::move(result), base64result.status };
4589}
4590
4615QByteArray QByteArray::fromBase64(const QByteArray &base64, Base64Options options)
4616{
4617 if (auto result = fromBase64Encoding(base64, options))
4618 return std::move(result.decoded);
4619 return QByteArray();
4620}
4621
4634{
4635 QByteArray res((hexEncoded.size() + 1)/ 2, Qt::Uninitialized);
4636 uchar *result = (uchar *)res.data() + res.size();
4637
4638 bool odd_digit = true;
4639 for (qsizetype i = hexEncoded.size() - 1; i >= 0; --i) {
4640 uchar ch = uchar(hexEncoded.at(i));
4641 int tmp = QtMiscUtils::fromHex(ch);
4642 if (tmp == -1)
4643 continue;
4644 if (odd_digit) {
4645 --result;
4646 *result = tmp;
4647 odd_digit = false;
4648 } else {
4649 *result |= tmp << 4;
4650 odd_digit = true;
4651 }
4652 }
4653
4654 res.remove(0, result - (const uchar *)res.constData());
4655 return res;
4656}
4657
4672QByteArray QByteArray::toHex(char separator) const
4673{
4674 if (isEmpty())
4675 return QByteArray();
4676
4677 const qsizetype length = separator ? (size() * 3 - 1) : (size() * 2);
4679 char *hexData = hex.data();
4680 const uchar *data = (const uchar *)this->data();
4681 for (qsizetype i = 0, o = 0; i < size(); ++i) {
4682 hexData[o++] = QtMiscUtils::toHexLower(data[i] >> 4);
4683 hexData[o++] = QtMiscUtils::toHexLower(data[i] & 0xf);
4684
4685 if ((separator) && (o < length))
4686 hexData[o++] = separator;
4687 }
4688 return hex;
4689}
4690
4691static void q_fromPercentEncoding(QByteArray *ba, char percent)
4692{
4693 if (ba->isEmpty())
4694 return;
4695
4696 char *data = ba->data();
4697 const char *inputPtr = data;
4698
4699 qsizetype i = 0;
4700 qsizetype len = ba->size();
4701 qsizetype outlen = 0;
4702 int a, b;
4703 char c;
4704 while (i < len) {
4705 c = inputPtr[i];
4706 if (c == percent && i + 2 < len) {
4707 a = inputPtr[++i];
4708 b = inputPtr[++i];
4709
4710 if (a >= '0' && a <= '9') a -= '0';
4711 else if (a >= 'a' && a <= 'f') a = a - 'a' + 10;
4712 else if (a >= 'A' && a <= 'F') a = a - 'A' + 10;
4713
4714 if (b >= '0' && b <= '9') b -= '0';
4715 else if (b >= 'a' && b <= 'f') b = b - 'a' + 10;
4716 else if (b >= 'A' && b <= 'F') b = b - 'A' + 10;
4717
4718 *data++ = (char)((a << 4) | b);
4719 } else {
4720 *data++ = c;
4721 }
4722
4723 ++i;
4724 ++outlen;
4725 }
4726
4727 if (outlen != len)
4728 ba->truncate(outlen);
4729}
4730
4750{
4751 if (isEmpty())
4752 return *this; // Preserves isNull().
4753
4754 QByteArray tmp = *this;
4755 q_fromPercentEncoding(&tmp, percent);
4756 return tmp;
4757}
4758
4774{
4775 return input.percentDecoded(percent);
4776}
4777
4786{
4787 return QByteArray(s.data(), qsizetype(s.size()));
4788}
4789
4802std::string QByteArray::toStdString() const
4803{
4804 return std::string(data(), size_t(size()));
4805}
4806
4832 char percent) const
4833{
4834 if (isNull())
4835 return QByteArray(); // preserve null
4836 if (isEmpty())
4837 return QByteArray(data(), 0);
4838
4839 const auto contains = [](const QByteArray &view, char c) {
4840 // As view.contains(c), but optimised to bypass a lot of overhead:
4841 return view.size() > 0 && memchr(view.data(), c, view.size()) != nullptr;
4842 };
4843
4844 QByteArray result = *this;
4845 char *output = nullptr;
4846 qsizetype length = 0;
4847
4848 for (unsigned char c : *this) {
4849 if (char(c) != percent
4850 && ((c >= 0x61 && c <= 0x7A) // ALPHA
4851 || (c >= 0x41 && c <= 0x5A) // ALPHA
4852 || (c >= 0x30 && c <= 0x39) // DIGIT
4853 || c == 0x2D // -
4854 || c == 0x2E // .
4855 || c == 0x5F // _
4856 || c == 0x7E // ~
4857 || contains(exclude, c))
4858 && !contains(include, c)) {
4859 if (output)
4860 output[length] = c;
4861 ++length;
4862 } else {
4863 if (!output) {
4864 // detach now
4865 result.resize(size() * 3); // worst case
4866 output = result.data();
4867 }
4868 output[length++] = percent;
4869 output[length++] = QtMiscUtils::toHexUpper((c & 0xf0) >> 4);
4871 }
4872 }
4873 if (output)
4874 result.truncate(length);
4875
4876 return result;
4877}
4878
4879#if defined(Q_OS_WASM) || defined(Q_QDOC)
4880
4904QByteArray QByteArray::fromEcmaUint8Array(emscripten::val uint8array)
4905{
4906 return qstdweb::Uint8Array(uint8array).copyToQByteArray();
4907}
4908
4926emscripten::val QByteArray::toEcmaUint8Array()
4927{
4928 return qstdweb::Uint8Array::copyFrom(*this).val();
4929}
4930
4931#endif
4932
5029#if QT_DEPRECATED_SINCE(6, 8)
5053#endif // QT_DEPRECATED_SINCE(6, 8)
5054
5154size_t qHash(const QByteArray::FromBase64Result &key, size_t seed) noexcept
5155{
5156 return qHashMulti(seed, key.decoded, static_cast<int>(key.decodingStatus));
5157}
5158
\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)
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)
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)
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)