QtBase  v6.3.1
qbytearray.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Copyright (C) 2019 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
6 ** Contact: https://www.qt.io/licensing/
7 **
8 ** This file is part of the QtCore module of the Qt Toolkit.
9 **
10 ** $QT_BEGIN_LICENSE:LGPL$
11 ** Commercial License Usage
12 ** Licensees holding valid commercial Qt licenses may use this file in
13 ** accordance with the commercial license agreement provided with the
14 ** Software or, alternatively, in accordance with the terms contained in
15 ** a written agreement between you and The Qt Company. For licensing terms
16 ** and conditions see https://www.qt.io/terms-conditions. For further
17 ** information use the contact form at https://www.qt.io/contact-us.
18 **
19 ** GNU Lesser General Public License Usage
20 ** Alternatively, this file may be used under the terms of the GNU Lesser
21 ** General Public License version 3 as published by the Free Software
22 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
23 ** packaging of this file. Please review the following information to
24 ** ensure the GNU Lesser General Public License version 3 requirements
25 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
26 **
27 ** GNU General Public License Usage
28 ** Alternatively, this file may be used under the terms of the GNU
29 ** General Public License version 2.0 or (at your option) the GNU General
30 ** Public license version 3 or any later version approved by the KDE Free
31 ** Qt Foundation. The licenses are as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
33 ** included in the packaging of this file. Please review the following
34 ** information to ensure the GNU General Public License requirements will
35 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
36 ** https://www.gnu.org/licenses/gpl-3.0.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qbytearray.h"
43 #include "qbytearraymatcher.h"
44 #include "private/qtools_p.h"
45 #include "qhashfunctions.h"
46 #include "qlist.h"
47 #include "qlocale_p.h"
48 #include "qlocale_tools_p.h"
49 #include "private/qnumeric_p.h"
50 #include "private/qsimd_p.h"
51 #include "qstringalgorithms_p.h"
52 #include "qscopedpointer.h"
53 #include "qbytearray_p.h"
54 #include "qstringconverter_p.h"
55 #include <qdatastream.h>
56 #include <qmath.h>
57 
58 #ifndef QT_NO_COMPRESS
59 #include <zconf.h>
60 #include <zlib.h>
61 #endif
62 #include <ctype.h>
63 #include <limits.h>
64 #include <string.h>
65 #include <stdlib.h>
66 
67 #include <algorithm>
68 
69 #define IS_RAW_DATA(d) ((d)->flags() & QArrayData::RawDataType)
70 
72 
73 const char QByteArray::_empty = '\0';
74 
75 // ASCII case system, used by QByteArray::to{Upper,Lower}() and qstr(n)icmp():
76 static constexpr inline uchar asciiUpper(uchar c)
77 {
78  return c >= 'a' && c <= 'z' ? c & ~0x20 : c;
79 }
80 
81 static constexpr inline uchar asciiLower(uchar c)
82 {
83  return c >= 'A' && c <= 'Z' ? c | 0x20 : c;
84 }
85 
87  const char *haystack0, qsizetype haystackLen, qsizetype from,
88  const char *needle0, qsizetype needleLen);
89 
90 /*****************************************************************************
91  Safe and portable C string functions; extensions to standard string.h
92  *****************************************************************************/
93 
106 char *qstrdup(const char *src)
107 {
108  if (!src)
109  return nullptr;
110  char *dst = new char[strlen(src) + 1];
111  return qstrcpy(dst, src);
112 }
113 
128 char *qstrcpy(char *dst, const char *src)
129 {
130  if (!src)
131  return nullptr;
132 #ifdef Q_CC_MSVC
133  const size_t len = strlen(src);
134  // This is actually not secure!!! It will be fixed
135  // properly in a later release!
136  if (len >= 0 && strcpy_s(dst, len+1, src) == 0)
137  return dst;
138  return nullptr;
139 #else
140  return strcpy(dst, src);
141 #endif
142 }
143 
161 char *qstrncpy(char *dst, const char *src, size_t len)
162 {
163  if (!src || !dst)
164  return nullptr;
165  if (len > 0) {
166 #ifdef Q_CC_MSVC
167  strncpy_s(dst, len, src, len - 1);
168 #else
169  strncpy(dst, src, len);
170 #endif
171  dst[len-1] = '\0';
172  }
173  return dst;
174 }
175 
215 int qstrcmp(const char *str1, const char *str2)
216 {
217  return (str1 && str2) ? strcmp(str1, str2)
218  : (str1 ? 1 : (str2 ? -1 : 0));
219 }
220 
260 int qstricmp(const char *str1, const char *str2)
261 {
262  const uchar *s1 = reinterpret_cast<const uchar *>(str1);
263  const uchar *s2 = reinterpret_cast<const uchar *>(str2);
264  if (!s1)
265  return s2 ? -1 : 0;
266  if (!s2)
267  return 1;
268 
269  enum { Incomplete = 256 };
270  qptrdiff offset = 0;
271  auto innerCompare = [=, &offset](qptrdiff max, bool unlimited) {
272  max += offset;
273  do {
274  uchar c = s1[offset];
275  if (int res = asciiLower(c) - asciiLower(s2[offset]))
276  return res;
277  if (!c)
278  return 0;
279  ++offset;
280  } while (unlimited || offset < max);
281  return int(Incomplete);
282  };
283 
284 #if defined(__SSE4_1__) && !(defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer))
285  enum { PageSize = 4096, PageMask = PageSize - 1 };
286  const __m128i zero = _mm_setzero_si128();
287  forever {
288  // Calculate how many bytes we can load until we cross a page boundary
289  // for either source. This isn't an exact calculation, just something
290  // very quick.
293  size_t n = PageSize - ((u1 | u2) & PageMask);
294 
295  qptrdiff maxoffset = offset + n;
296  for ( ; offset + 16 <= maxoffset; offset += sizeof(__m128i)) {
297  // load 16 bytes from either source
298  __m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s1 + offset));
299  __m128i b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s2 + offset));
300 
301  // compare the two against each other
302  __m128i cmp = _mm_cmpeq_epi8(a, b);
303 
304  // find NUL terminators too
305  cmp = _mm_min_epu8(cmp, a);
306  cmp = _mm_cmpeq_epi8(cmp, zero);
307 
308  // was there any difference or a NUL?
309  uint mask = _mm_movemask_epi8(cmp);
310  if (mask) {
311  // yes, find out where
313  uint end = sizeof(mask) * 8 - qCountLeadingZeroBits(mask);
314  Q_ASSUME(end >= start);
315  offset += start;
316  n = end - start;
317  break;
318  }
319  }
320 
321  // using SIMD could cause a page fault, so iterate byte by byte
322  int res = innerCompare(n, false);
323  if (res != Incomplete)
324  return res;
325  }
326 #endif
327 
328  return innerCompare(-1, true);
329 }
330 
350 int qstrnicmp(const char *str1, const char *str2, size_t len)
351 {
352  const uchar *s1 = reinterpret_cast<const uchar *>(str1);
353  const uchar *s2 = reinterpret_cast<const uchar *>(str2);
354  if (!s1 || !s2)
355  return s1 ? 1 : (s2 ? -1 : 0);
356  for (; len--; ++s1, ++s2) {
357  const uchar c = *s1;
358  if (int res = asciiLower(c) - asciiLower(*s2))
359  return res;
360  if (!c) // strings are equal
361  break;
362  }
363  return 0;
364 }
365 
374 int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
375 {
376  Q_ASSERT(len1 >= 0);
377  Q_ASSERT(len2 >= -1);
378  const uchar *s1 = reinterpret_cast<const uchar *>(str1);
379  const uchar *s2 = reinterpret_cast<const uchar *>(str2);
380  if (!s1 || !len1) {
381  if (len2 == 0)
382  return 0;
383  if (len2 == -1)
384  return (!s2 || !*s2) ? 0 : -1;
385  Q_ASSERT(s2);
386  return -1;
387  }
388  if (!s2)
389  return len1 == 0 ? 0 : 1;
390 
391  if (len2 == -1) {
392  // null-terminated str2
393  qsizetype i;
394  for (i = 0; i < len1; ++i) {
395  const uchar c = s2[i];
396  if (!c)
397  return 1;
398 
399  if (int res = asciiLower(s1[i]) - asciiLower(c))
400  return res;
401  }
402  return s2[i] ? -1 : 0;
403  } else {
404  // not null-terminated
405  const qsizetype len = qMin(len1, len2);
406  for (qsizetype i = 0; i < len; ++i) {
407  if (int res = asciiLower(s1[i]) - asciiLower(s2[i]))
408  return res;
409  }
410  if (len1 == len2)
411  return 0;
412  return len1 < len2 ? -1 : 1;
413  }
414 }
415 
420 {
421  if (!lhs.isNull() && !rhs.isNull()) {
422  int ret = memcmp(lhs.data(), rhs.data(), qMin(lhs.size(), rhs.size()));
423  if (ret != 0)
424  return ret;
425  }
426 
427  // they matched qMin(l1, l2) bytes
428  // so the longer one is lexically after the shorter one
429  return lhs.size() == rhs.size() ? 0 : lhs.size() > rhs.size() ? 1 : -1;
430 }
431 
436 {
438 }
439 
440 // the CRC table below is created by the following piece of code
441 #if 0
442 static void createCRC16Table() // build CRC16 lookup table
443 {
444  unsigned int i;
445  unsigned int j;
446  unsigned short crc_tbl[16];
447  unsigned int v0, v1, v2, v3;
448  for (i = 0; i < 16; i++) {
449  v0 = i & 1;
450  v1 = (i >> 1) & 1;
451  v2 = (i >> 2) & 1;
452  v3 = (i >> 3) & 1;
453  j = 0;
454 #undef SET_BIT
455 #define SET_BIT(x, b, v) (x) |= (v) << (b)
456  SET_BIT(j, 0, v0);
457  SET_BIT(j, 7, v0);
458  SET_BIT(j, 12, v0);
459  SET_BIT(j, 1, v1);
460  SET_BIT(j, 8, v1);
461  SET_BIT(j, 13, v1);
462  SET_BIT(j, 2, v2);
463  SET_BIT(j, 9, v2);
464  SET_BIT(j, 14, v2);
465  SET_BIT(j, 3, v3);
466  SET_BIT(j, 10, v3);
467  SET_BIT(j, 15, v3);
468  crc_tbl[i] = j;
469  }
470  printf("static const quint16 crc_tbl[16] = {\n");
471  for (int i = 0; i < 16; i +=4)
472  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]);
473  printf("};\n");
474 }
475 #endif
476 
477 static const quint16 crc_tbl[16] = {
478  0x0000, 0x1081, 0x2102, 0x3183,
479  0x4204, 0x5285, 0x6306, 0x7387,
480  0x8408, 0x9489, 0xa50a, 0xb58b,
481  0xc60c, 0xd68d, 0xe70e, 0xf78f
482 };
483 
498 {
499  quint16 crc = 0x0000;
500  switch (standard) {
501  case Qt::ChecksumIso3309:
502  crc = 0xffff;
503  break;
504  case Qt::ChecksumItuV41:
505  crc = 0x6363;
506  break;
507  }
508  uchar c;
509  const uchar *p = reinterpret_cast<const uchar *>(data.data());
510  qsizetype len = data.size();
511  while (len--) {
512  c = *p++;
513  crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
514  c >>= 4;
515  crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
516  }
517  switch (standard) {
518  case Qt::ChecksumIso3309:
519  crc = ~crc;
520  break;
521  case Qt::ChecksumItuV41:
522  break;
523  }
524  return crc & 0xffff;
525 }
526 
555 #ifndef QT_NO_COMPRESS
556 QByteArray qCompress(const uchar* data, qsizetype nbytes, int compressionLevel)
557 {
558  if (nbytes == 0) {
559  return QByteArray(4, '\0');
560  }
561  if (!data) {
562  qWarning("qCompress: Data is null");
563  return QByteArray();
564  }
565  if (compressionLevel < -1 || compressionLevel > 9)
566  compressionLevel = -1;
567 
568  ulong len = nbytes + nbytes / 100 + 13;
569  QByteArray bazip;
570  int res;
571  do {
572  bazip.resize(len + 4);
573  res = ::compress2((uchar*)bazip.data()+4, &len, data, nbytes, compressionLevel);
574 
575  switch (res) {
576  case Z_OK:
577  bazip.resize(len + 4);
578  bazip[0] = (nbytes & 0xff000000) >> 24;
579  bazip[1] = (nbytes & 0x00ff0000) >> 16;
580  bazip[2] = (nbytes & 0x0000ff00) >> 8;
581  bazip[3] = (nbytes & 0x000000ff);
582  break;
583  case Z_MEM_ERROR:
584  qWarning("qCompress: Z_MEM_ERROR: Not enough memory");
585  bazip.resize(0);
586  break;
587  case Z_BUF_ERROR:
588  len *= 2;
589  break;
590  }
591  } while (res == Z_BUF_ERROR);
592 
593  return bazip;
594 }
595 #endif
596 
620 #ifndef QT_NO_COMPRESS
621 static QByteArray invalidCompressedData()
622 {
623  qWarning("qUncompress: Input data is corrupted");
624  return QByteArray();
625 }
626 
635 {
636  if (!data) {
637  qWarning("qUncompress: Data is null");
638  return QByteArray();
639  }
640  if (nbytes <= 4) {
641  if (nbytes < 4 || (data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0))
642  qWarning("qUncompress: Input data is corrupted");
643  return QByteArray();
644  }
645  size_t expectedSize = size_t((data[0] << 24) | (data[1] << 16) |
646  (data[2] << 8) | (data[3] ));
647  size_t len = qMax(expectedSize, 1ul);
648  const size_t maxPossibleSize = MaxAllocSize - sizeof(QByteArray::Data);
649  if (Q_UNLIKELY(len >= maxPossibleSize)) {
650  // QByteArray does not support that huge size anyway.
651  return invalidCompressedData();
652  }
653 
655  if (Q_UNLIKELY(d.data() == nullptr))
656  return invalidCompressedData();
657 
658  forever {
659  const auto alloc = len;
660  int res = ::uncompress((uchar*)d.data(), reinterpret_cast<uLongf*>(&len),
661  data+4, nbytes-4);
662 
663  switch (res) {
664  case Z_OK: {
665  Q_ASSERT(len <= alloc);
666  Q_UNUSED(alloc);
667  d.data()[len] = '\0';
668  d.size = len;
669  return QByteArray(d);
670  }
671 
672  case Z_MEM_ERROR:
673  qWarning("qUncompress: Z_MEM_ERROR: Not enough memory");
674  return QByteArray();
675 
676  case Z_BUF_ERROR:
677  len *= 2;
678  if (Q_UNLIKELY(len >= maxPossibleSize)) {
679  // QByteArray does not support that huge size anyway.
680  return invalidCompressedData();
681  } else {
682  // grow the block
683  d->reallocate(d->allocatedCapacity()*2, QArrayData::Grow);
684  if (Q_UNLIKELY(d.data() == nullptr))
685  return invalidCompressedData();
686  }
687  continue;
688 
689  case Z_DATA_ERROR:
690  qWarning("qUncompress: Z_DATA_ERROR: Input data is corrupted");
691  return QByteArray();
692  }
693  }
694 }
695 #endif
696 
978 
981 
1170 {
1171  const auto start = std::distance(cbegin(), first);
1172  const auto len = std::distance(first, last);
1173  remove(start, len);
1174  return begin() + start;
1175 }
1176 
1214 {
1215  d = other.d;
1216  return *this;
1217 }
1218 
1219 
1227 {
1228  if (!str) {
1229  d.clear();
1230  } else if (!*str) {
1231  d = DataPointer::fromRawData(&_empty, 0);
1232  } else {
1233  const qsizetype len = qsizetype(strlen(str));
1234  const auto capacityAtEnd = d->allocatedCapacity() - d.freeSpaceAtBegin();
1235  if (d->needsDetach() || len > capacityAtEnd
1236  || (len < size() && len < (capacityAtEnd >> 1)))
1237  // ### inefficient! reallocData() does copy the old data and we then overwrite it in the next line
1238  reallocData(len, QArrayData::KeepSize);
1239  memcpy(d.data(), str, len + 1); // include null terminator
1240  d.size = len;
1241  }
1242  return *this;
1243 }
1244 
1356 
1359 
1575 {
1576  if (pos < size())
1577  resize(pos);
1578 }
1579 
1594 {
1595  if (n > 0)
1596  resize(size() - n);
1597 }
1598 
1599 
1682 {
1683  if (!data) {
1684  d = DataPointer();
1685  } else {
1686  if (size < 0)
1687  size = qstrlen(data);
1688  if (!size) {
1689  d = DataPointer::fromRawData(&_empty, 0);
1690  } else {
1692  Q_CHECK_PTR(d.data());
1693  memcpy(d.data(), data, size);
1694  d.data()[size] = '\0';
1695  }
1696  }
1697 }
1698 
1706 {
1707  if (size <= 0) {
1708  d = DataPointer::fromRawData(&_empty, 0);
1709  } else {
1711  Q_CHECK_PTR(d.data());
1712  memset(d.data(), ch, size);
1713  d.data()[size] = '\0';
1714  }
1715 }
1716 
1724 {
1725  if (size <= 0) {
1726  d = DataPointer::fromRawData(&_empty, 0);
1727  } else {
1729  Q_CHECK_PTR(d.data());
1730  d.data()[size] = '\0';
1731  }
1732 }
1733 
1750 {
1751  if (size < 0)
1752  size = 0;
1753 
1754  const auto capacityAtEnd = capacity() - d.freeSpaceAtBegin();
1755  if (d->needsDetach() || size > capacityAtEnd)
1756  reallocData(size, QArrayData::Grow);
1757  d.size = size;
1758  if (d->allocatedCapacity())
1759  d.data()[size] = 0;
1760 }
1761 
1773 {
1775  if (this->size())
1776  memset(d.data(), ch, this->size());
1777  return *this;
1778 }
1779 
1780 void QByteArray::reallocData(qsizetype alloc, QArrayData::AllocationOption option)
1781 {
1782  if (!alloc) {
1783  d = DataPointer::fromRawData(&_empty, 0);
1784  return;
1785  }
1786 
1787  // don't use reallocate path when reducing capacity and there's free space
1788  // at the beginning: might shift data pointer outside of allocated space
1789  const bool cannotUseReallocate = d.freeSpaceAtBegin() > 0;
1790 
1791  if (d->needsDetach() || cannotUseReallocate) {
1792  DataPointer dd(Data::allocate(alloc, option), qMin(alloc, d.size));
1793  Q_CHECK_PTR(dd.data());
1794  if (dd.size > 0)
1795  ::memcpy(dd.data(), d.data(), dd.size);
1796  dd.data()[dd.size] = 0;
1797  d = dd;
1798  } else {
1799  d->reallocate(alloc, option);
1800  }
1801 }
1802 
1803 void QByteArray::reallocGrowData(qsizetype n)
1804 {
1805  if (!n) // expected to always allocate
1806  n = 1;
1807 
1808  if (d->needsDetach()) {
1810  Q_CHECK_PTR(dd.data());
1811  dd->copyAppend(d.data(), d.data() + d.size);
1812  dd.data()[dd.size] = 0;
1813  d = dd;
1814  } else {
1815  d->reallocate(d.constAllocatedCapacity() + n, QArrayData::Grow);
1816  }
1817 }
1818 
1819 void QByteArray::expand(qsizetype i)
1820 {
1821  resize(qMax(i + 1, size()));
1822 }
1823 
1833 QByteArray QByteArray::nulTerminated() const
1834 {
1835  // is this fromRawData?
1836  if (d.isMutable())
1837  return *this; // no, then we're sure we're zero terminated
1838 
1839  QByteArray copy(*this);
1840  copy.detach();
1841  return copy;
1842 }
1843 
1869 {
1870  if (size() == 0 && ba.size() > d.constAllocatedCapacity() && ba.d.isMutable())
1871  return (*this = ba);
1872  return prepend(QByteArrayView(ba));
1873 }
1874 
1931 {
1932  if (size() == 0 && ba.size() > d->freeSpaceAtEnd() && ba.d.isMutable())
1933  return (*this = ba);
1934  return append(QByteArrayView(ba));
1935 }
1936 
1985 {
1986  d.detachAndGrow(QArrayData::GrowsAtEnd, 1, nullptr, nullptr);
1987  d->copyAppend(1, ch);
1988  d.data()[d.size] = '\0';
1989  return *this;
1990 }
1991 
2005 
2009 
2013 {
2014  const char *str = data.data();
2015  qsizetype size = data.size();
2016  if (i < 0 || size <= 0)
2017  return *this;
2018 
2019  // handle this specially, as QArrayDataOps::insert() doesn't handle out of
2020  // bounds positions
2021  if (i >= d->size) {
2022  // In case when data points into the range or is == *this, we need to
2023  // defer a call to free() so that it comes after we copied the data from
2024  // the old memory:
2025  DataPointer detached{}; // construction is free
2027  Q_CHECK_PTR(d.data());
2028  d->copyAppend(i - d->size, ' ');
2029  d->copyAppend(str, str + size);
2030  d.data()[d.size] = '\0';
2031  return *this;
2032  }
2033 
2034  if (!d->needsDetach() && QtPrivate::q_points_into_range(str, d.data(), d.data() + d.size)) {
2036  return insert(i, a);
2037  }
2038 
2039  d->insert(i, str, size);
2040  d.data()[d.size] = '\0';
2041  return *this;
2042 }
2043 
2098 {
2099  if (i < 0 || count <= 0)
2100  return *this;
2101 
2102  if (i >= d->size) {
2103  // handle this specially, as QArrayDataOps::insert() doesn't handle out of bounds positions
2104  d.detachAndGrow(Data::GrowsAtEnd, (i - d.size) + count, nullptr, nullptr);
2105  Q_CHECK_PTR(d.data());
2106  d->copyAppend(i - d->size, ' ');
2107  d->copyAppend(count, ch);
2108  d.data()[d.size] = '\0';
2109  return *this;
2110  }
2111 
2112  d->insert(i, count, ch);
2113  d.data()[d.size] = '\0';
2114  return *this;
2115 }
2116 
2136 {
2137  if (len <= 0 || pos < 0 || size_t(pos) >= size_t(size()))
2138  return *this;
2139  detach();
2140  if (pos + len > d->size)
2141  len = d->size - pos;
2142  d->erase(d.begin() + pos, len);
2143  d.data()[d.size] = '\0';
2144  return *this;
2145 }
2146 
2168 {
2169  if (QtPrivate::q_points_into_range(after.data(), d.data(), d.data() + d.size)) {
2170  QVarLengthArray copy(after.data(), after.data() + after.size());
2171  return replace(pos, len, QByteArrayView{copy});
2172  }
2173  if (len == after.size() && (pos + len <= size())) {
2174  // same size: in-place replacement possible
2175  if (len > 0) {
2176  detach();
2177  memcpy(d.data() + pos, after.data(), len*sizeof(char));
2178  }
2179  return *this;
2180  } else {
2181  // ### optimize me
2182  remove(pos, len);
2183  return insert(pos, after);
2184  }
2185 }
2186 
2219 {
2220  const char *b = before.data();
2221  qsizetype bsize = before.size();
2222  const char *a = after.data();
2223  qsizetype asize = after.size();
2224 
2225  if (isNull() || (b == a && bsize == asize))
2226  return *this;
2227 
2228  // protect against before or after being part of this
2229  if (QtPrivate::q_points_into_range(a, d.data(), d.data() + d.size)) {
2230  QVarLengthArray copy(a, a + asize);
2231  return replace(before, QByteArrayView{copy});
2232  }
2233  if (QtPrivate::q_points_into_range(b, d.data(), d.data() + d.size)) {
2234  QVarLengthArray copy(b, b + bsize);
2235  return replace(QByteArrayView{copy}, after);
2236  }
2237 
2238  QByteArrayMatcher matcher(b, bsize);
2239  qsizetype index = 0;
2240  qsizetype len = size();
2241  char *d = data(); // detaches
2242 
2243  if (bsize == asize) {
2244  if (bsize) {
2245  while ((index = matcher.indexIn(*this, index)) != -1) {
2246  memcpy(d + index, a, asize);
2247  index += bsize;
2248  }
2249  }
2250  } else if (asize < bsize) {
2251  size_t to = 0;
2252  size_t movestart = 0;
2253  size_t num = 0;
2254  while ((index = matcher.indexIn(*this, index)) != -1) {
2255  if (num) {
2256  qsizetype msize = index - movestart;
2257  if (msize > 0) {
2258  memmove(d + to, d + movestart, msize);
2259  to += msize;
2260  }
2261  } else {
2262  to = index;
2263  }
2264  if (asize) {
2265  memcpy(d + to, a, asize);
2266  to += asize;
2267  }
2268  index += bsize;
2269  movestart = index;
2270  num++;
2271  }
2272  if (num) {
2273  qsizetype msize = len - movestart;
2274  if (msize > 0)
2275  memmove(d + to, d + movestart, msize);
2276  resize(len - num*(bsize-asize));
2277  }
2278  } else {
2279  // the most complex case. We don't want to lose performance by doing repeated
2280  // copies and reallocs of the data.
2281  while (index != -1) {
2282  size_t indices[4096];
2283  size_t pos = 0;
2284  while(pos < 4095) {
2285  index = matcher.indexIn(*this, index);
2286  if (index == -1)
2287  break;
2288  indices[pos++] = index;
2289  index += bsize;
2290  // avoid infinite loop
2291  if (!bsize)
2292  index++;
2293  }
2294  if (!pos)
2295  break;
2296 
2297  // we have a table of replacement positions, use them for fast replacing
2298  qsizetype adjust = pos*(asize-bsize);
2299  // index has to be adjusted in case we get back into the loop above.
2300  if (index != -1)
2301  index += adjust;
2302  qsizetype newlen = len + adjust;
2303  qsizetype moveend = len;
2304  if (newlen > len) {
2305  resize(newlen);
2306  len = newlen;
2307  }
2308  d = this->d.data(); // data(), without the detach() check
2309 
2310  while(pos) {
2311  pos--;
2312  qsizetype movestart = indices[pos] + bsize;
2313  qsizetype insertstart = indices[pos] + pos*(asize-bsize);
2314  qsizetype moveto = insertstart + asize;
2315  memmove(d + moveto, d + movestart, (moveend - movestart));
2316  if (asize)
2317  memcpy(d + insertstart, a, asize);
2318  moveend = movestart - bsize;
2319  }
2320  }
2321  }
2322  return *this;
2323 }
2324 
2339 QByteArray &QByteArray::replace(char before, char after)
2340 {
2341  if (!isEmpty()) {
2342  char *i = data();
2343  char *e = i + size();
2344  for (; i != e; ++i)
2345  if (*i == before)
2346  * i = after;
2347  }
2348  return *this;
2349 }
2350 
2359 {
2361  qsizetype start = 0;
2362  qsizetype end;
2363  while ((end = indexOf(sep, start)) != -1) {
2364  list.append(mid(start, end - start));
2365  start = end + 1;
2366  }
2367  list.append(mid(start));
2368  return list;
2369 }
2370 
2383 {
2384  if (isEmpty())
2385  return *this;
2386 
2387  if (times <= 1) {
2388  if (times == 1)
2389  return *this;
2390  return QByteArray();
2391  }
2392 
2393  const qsizetype resultSize = times * size();
2394 
2396  result.reserve(resultSize);
2397  if (result.capacity() != resultSize)
2398  return QByteArray(); // not enough memory
2399 
2400  memcpy(result.d.data(), data(), size());
2401 
2402  qsizetype sizeSoFar = size();
2403  char *end = result.d.data() + sizeSoFar;
2404 
2405  const qsizetype halfResultSize = resultSize >> 1;
2406  while (sizeSoFar <= halfResultSize) {
2407  memcpy(end, result.d.data(), sizeSoFar);
2408  end += sizeSoFar;
2409  sizeSoFar <<= 1;
2410  }
2411  memcpy(end, result.d.data(), resultSize - sizeSoFar);
2412  result.d.data()[resultSize] = '\0';
2413  result.d.size = resultSize;
2414  return result;
2415 }
2416 
2417 #define REHASH(a) \
2418  if (ol_minus_1 < sizeof(std::size_t) * CHAR_BIT) \
2419  hashHaystack -= std::size_t(a) << ol_minus_1; \
2420  hashHaystack <<= 1
2421 
2422 static inline qsizetype findCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept
2423 {
2424  if (from < 0)
2425  from = qMax(from + haystack.size(), qsizetype(0));
2426  if (from < haystack.size()) {
2427  const char *const b = haystack.data();
2428  if (const auto n = static_cast<const char *>(
2429  memchr(b + from, needle, static_cast<size_t>(haystack.size() - from)))) {
2430  return n - b;
2431  }
2432  }
2433  return -1;
2434 }
2435 
2437 {
2438  const auto ol = needle.size();
2439  const auto l = haystack.size();
2440  if (ol == 0) {
2441  if (from < 0)
2442  return qMax(from + l, 0);
2443  else
2444  return from > l ? -1 : from;
2445  }
2446 
2447  if (ol == 1)
2448  return findCharHelper(haystack, from, needle.front());
2449 
2450  if (from > l || ol + from > l)
2451  return -1;
2452 
2453  return qFindByteArray(haystack.data(), haystack.size(), from, needle.data(), ol);
2454 }
2455 
2483 {
2484  return qToByteArrayViewIgnoringNull(*this).indexOf(ch, from);
2485 }
2486 
2487 static qsizetype lastIndexOfHelper(const char *haystack, qsizetype l, const char *needle,
2488  qsizetype ol, qsizetype from)
2489 {
2490  auto delta = l - ol;
2491  if (from < 0)
2492  from = delta;
2493  if (from < 0 || from > l)
2494  return -1;
2495  if (from > delta)
2496  from = delta;
2497 
2498  const char *end = haystack;
2499  haystack += from;
2500  const auto ol_minus_1 = std::size_t(ol - 1);
2501  const char *n = needle + ol_minus_1;
2502  const char *h = haystack + ol_minus_1;
2503  std::size_t hashNeedle = 0, hashHaystack = 0;
2504  qsizetype idx;
2505  for (idx = 0; idx < ol; ++idx) {
2506  hashNeedle = ((hashNeedle<<1) + *(n-idx));
2507  hashHaystack = ((hashHaystack<<1) + *(h-idx));
2508  }
2509  hashHaystack -= *haystack;
2510  while (haystack >= end) {
2511  hashHaystack += *haystack;
2512  if (hashHaystack == hashNeedle && memcmp(needle, haystack, ol) == 0)
2513  return haystack - end;
2514  --haystack;
2515  REHASH(*(haystack + ol));
2516  }
2517  return -1;
2518 
2519 }
2520 
2521 static inline qsizetype lastIndexOfCharHelper(QByteArrayView haystack, qsizetype from, char needle) noexcept
2522 {
2523  if (haystack.size() == 0)
2524  return -1;
2525  if (from < 0)
2526  from += haystack.size();
2527  else if (from > haystack.size())
2528  from = haystack.size() - 1;
2529  if (from >= 0) {
2530  const char *b = haystack.data();
2531  const char *n = b + from + 1;
2532  while (n-- != b) {
2533  if (*n == needle)
2534  return n - b;
2535  }
2536  }
2537  return -1;
2538 }
2539 
2541 {
2542  if (haystack.isEmpty()) {
2543  if (needle.isEmpty() && from == 0)
2544  return 0;
2545  return -1;
2546  }
2547  const auto ol = needle.size();
2548  if (ol == 1)
2549  return lastIndexOfCharHelper(haystack, from, needle.front());
2550 
2551  return lastIndexOfHelper(haystack.data(), haystack.size(), needle.data(), ol, from);
2552 }
2553 
2605 {
2606  return qToByteArrayViewIgnoringNull(*this).lastIndexOf(ch, from);
2607 }
2608 
2609 static inline qsizetype countCharHelper(QByteArrayView haystack, char needle) noexcept
2610 {
2611  qsizetype num = 0;
2612  for (char ch : haystack) {
2613  if (ch == needle)
2614  ++num;
2615  }
2616  return num;
2617 }
2618 
2620 {
2621  if (needle.size() == 0)
2622  return haystack.size() + 1;
2623 
2624  if (needle.size() == 1)
2625  return countCharHelper(haystack, needle[0]);
2626 
2627  qsizetype num = 0;
2628  qsizetype i = -1;
2629  if (haystack.size() > 500 && needle.size() > 5) {
2630  QByteArrayMatcher matcher(needle);
2631  while ((i = matcher.indexIn(haystack, i + 1)) != -1)
2632  ++num;
2633  } else {
2634  while ((i = haystack.indexOf(needle, i + 1)) != -1)
2635  ++num;
2636  }
2637  return num;
2638 }
2639 
2658 {
2659  return static_cast<int>(countCharHelper(*this, ch));
2660 }
2661 
2681 bool QtPrivate::startsWith(QByteArrayView haystack, QByteArrayView needle) noexcept
2682 {
2683  if (haystack.size() < needle.size())
2684  return false;
2685  if (haystack.data() == needle.data() || needle.size() == 0)
2686  return true;
2687  return memcmp(haystack.data(), needle.data(), needle.size()) == 0;
2688 }
2689 
2710 bool QtPrivate::endsWith(QByteArrayView haystack, QByteArrayView needle) noexcept
2711 {
2712  if (haystack.size() < needle.size())
2713  return false;
2714  if (haystack.end() == needle.end() || needle.size() == 0)
2715  return true;
2716  return memcmp(haystack.end() - needle.size(), needle.data(), needle.size()) == 0;
2717 }
2718 
2740 /*
2741  Returns true if \a c is an uppercase ASCII letter.
2742  */
2743 static constexpr inline bool isUpperCaseAscii(char c)
2744 {
2745  return c >= 'A' && c <= 'Z';
2746 }
2747 
2748 /*
2749  Returns true if \a c is an lowercase ASCII letter.
2750  */
2751 static constexpr inline bool isLowerCaseAscii(char c)
2752 {
2753  return c >= 'a' && c <= 'z';
2754 }
2755 
2768 {
2769  return std::none_of(begin(), end(), isLowerCaseAscii);
2770 }
2771 
2784 {
2785  return std::none_of(begin(), end(), isUpperCaseAscii);
2786 }
2787 
2813 {
2814  if (len >= size())
2815  return *this;
2816  if (len < 0)
2817  len = 0;
2818  return QByteArray(data(), len);
2819 }
2820 
2835 {
2836  if (len >= size())
2837  return *this;
2838  if (len < 0)
2839  len = 0;
2840  return QByteArray(end() - len, len);
2841 }
2842 
2858 {
2859  qsizetype p = pos;
2860  qsizetype l = len;
2861  using namespace QtPrivate;
2862  switch (QContainerImplHelper::mid(size(), &p, &l)) {
2864  return QByteArray();
2865  case QContainerImplHelper::Empty:
2866  {
2867  return QByteArray(DataPointer::fromRawData(&_empty, 0));
2868  }
2869  case QContainerImplHelper::Full:
2870  return *this;
2871  case QContainerImplHelper::Subset:
2872  return QByteArray(d.data() + p, l);
2873  }
2874  Q_UNREACHABLE();
2875  return QByteArray();
2876 }
2877 
2959 // prevent the compiler from inlining the function in each of
2960 // toLower and toUpper when the only difference is the table being used
2961 // (even with constant propagation, there's no gain in performance).
2962 template <typename T>
2963 Q_NEVER_INLINE
2964 static QByteArray toCase_template(T &input, uchar (*lookup)(uchar))
2965 {
2966  // find the first bad character in input
2967  const char *orig_begin = input.constBegin();
2968  const char *firstBad = orig_begin;
2969  const char *e = input.constEnd();
2970  for ( ; firstBad != e ; ++firstBad) {
2971  uchar ch = uchar(*firstBad);
2972  uchar converted = lookup(ch);
2973  if (ch != converted)
2974  break;
2975  }
2976 
2977  if (firstBad == e)
2978  return std::move(input);
2979 
2980  // transform the rest
2981  QByteArray s = std::move(input); // will copy if T is const QByteArray
2982  char *b = s.begin(); // will detach if necessary
2983  char *p = b + (firstBad - orig_begin);
2984  e = b + s.size();
2985  for ( ; p != e; ++p)
2986  *p = char(lookup(uchar(*p)));
2987  return s;
2988 }
2989 
2990 QByteArray QByteArray::toLower_helper(const QByteArray &a)
2991 {
2992  return toCase_template(a, asciiLower);
2993 }
2994 
2995 QByteArray QByteArray::toLower_helper(QByteArray &a)
2996 {
2997  return toCase_template(a, asciiLower);
2998 }
2999 
3012 QByteArray QByteArray::toUpper_helper(const QByteArray &a)
3013 {
3014  return toCase_template(a, asciiUpper);
3015 }
3016 
3017 QByteArray QByteArray::toUpper_helper(QByteArray &a)
3018 {
3019  return toCase_template(a, asciiUpper);
3020 }
3021 
3030 {
3031  d.clear();
3032 }
3033 
3034 #if !defined(QT_NO_DATASTREAM) || defined(QT_BOOTSTRAPPED)
3035 
3045 {
3046  if (ba.isNull() && out.version() >= 6) {
3047  out << (quint32)0xffffffff;
3048  return out;
3049  }
3050  return out.writeBytes(ba.constData(), ba.size());
3051 }
3052 
3062 {
3063  ba.clear();
3064  quint32 len;
3065  in >> len;
3066  if (len == 0xffffffff)
3067  return in;
3068 
3069  const quint32 Step = 1024 * 1024;
3070  quint32 allocated = 0;
3071 
3072  do {
3073  qsizetype blockSize = qMin(Step, len - allocated);
3074  ba.resize(allocated + blockSize);
3075  if (in.readRawData(ba.data() + allocated, blockSize) != blockSize) {
3076  ba.clear();
3077  in.setStatus(QDataStream::ReadPastEnd);
3078  return in;
3079  }
3080  allocated += blockSize;
3081  } while (allocated < len);
3082 
3083  return in;
3084 }
3085 #endif // QT_NO_DATASTREAM
3086 
3395 QByteArray QByteArray::simplified_helper(const QByteArray &a)
3396 {
3398 }
3399 
3400 QByteArray QByteArray::simplified_helper(QByteArray &a)
3401 {
3403 }
3404 
3424 QByteArray QByteArray::trimmed_helper(const QByteArray &a)
3425 {
3427 }
3428 
3429 QByteArray QByteArray::trimmed_helper(QByteArray &a)
3430 {
3432 }
3433 
3435 {
3436  auto start = view.begin();
3437  auto stop = view.end();
3439  return QByteArrayView(start, stop);
3440 }
3441 
3461 {
3463  qsizetype len = size();
3464  qsizetype padlen = width - len;
3465  if (padlen > 0) {
3466  result.resize(len+padlen);
3467  if (len)
3468  memcpy(result.d.data(), data(), len);
3469  memset(result.d.data()+len, fill, padlen);
3470  } else {
3471  if (truncate)
3472  result = left(width);
3473  else
3474  result = *this;
3475  }
3476  return result;
3477 }
3478 
3498 {
3500  qsizetype len = size();
3501  qsizetype padlen = width - len;
3502  if (padlen > 0) {
3503  result.resize(len+padlen);
3504  if (len)
3505  memcpy(result.d.data()+padlen, data(), len);
3506  memset(result.d.data(), fill, padlen);
3507  } else {
3508  if (truncate)
3509  result = left(width);
3510  else
3511  result = *this;
3512  }
3513  return result;
3514 }
3515 
3516 bool QByteArray::isNull() const noexcept
3517 {
3518  return d->isNull();
3519 }
3520 
3522 {
3523 #if defined(QT_CHECK_RANGE)
3524  if (base != 0 && (base < 2 || base > 36)) {
3525  qWarning("QByteArray::toIntegral: Invalid base %d", base);
3526  base = 10;
3527  }
3528 #endif
3529  if (data.isEmpty())
3530  return {};
3531 
3532  bool ok = false;
3533  const auto i = QLocaleData::bytearrayToLongLong(data, base, &ok);
3534  if (ok)
3535  return ParsedNumber(i);
3536  return {};
3537 }
3538 
3540 {
3541 #if defined(QT_CHECK_RANGE)
3542  if (base != 0 && (base < 2 || base > 36)) {
3543  qWarning("QByteArray::toIntegral: Invalid base %d", base);
3544  base = 10;
3545  }
3546 #endif
3547  if (data.isEmpty())
3548  return {};
3549 
3550  bool ok = false;
3552  if (ok)
3553  return ParsedNumber(u);
3554  return {};
3555 }
3556 
3580 {
3581  return QtPrivate::toIntegral<qlonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3582 }
3583 
3607 {
3608  return QtPrivate::toIntegral<qulonglong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3609 }
3610 
3635 int QByteArray::toInt(bool *ok, int base) const
3636 {
3637  return QtPrivate::toIntegral<int>(qToByteArrayViewIgnoringNull(*this), ok, base);
3638 }
3639 
3662 uint QByteArray::toUInt(bool *ok, int base) const
3663 {
3664  return QtPrivate::toIntegral<uint>(qToByteArrayViewIgnoringNull(*this), ok, base);
3665 }
3666 
3692 long QByteArray::toLong(bool *ok, int base) const
3693 {
3694  return QtPrivate::toIntegral<long>(qToByteArrayViewIgnoringNull(*this), ok, base);
3695 }
3696 
3721 {
3722  return QtPrivate::toIntegral<ulong>(qToByteArrayViewIgnoringNull(*this), ok, base);
3723 }
3724 
3747 short QByteArray::toShort(bool *ok, int base) const
3748 {
3749  return QtPrivate::toIntegral<short>(qToByteArrayViewIgnoringNull(*this), ok, base);
3750 }
3751 
3775 {
3776  return QtPrivate::toIntegral<ushort>(qToByteArrayViewIgnoringNull(*this), ok, base);
3777 }
3778 
3804 double QByteArray::toDouble(bool *ok) const
3805 {
3806  return QByteArrayView(*this).toDouble(ok);
3807 }
3808 
3810 {
3811  bool nonNullOk = false;
3812  int processed = 0;
3813  double d = qt_asciiToDouble(a.data(), a.size(), nonNullOk, processed, WhitespacesAllowed);
3814  if (nonNullOk)
3815  return ParsedNumber{d};
3816  else
3817  return {};
3818 }
3819 
3845 float QByteArray::toFloat(bool *ok) const
3846 {
3848 }
3849 
3851 {
3852  if (const auto r = toDouble(a)) {
3853  bool ok = true;
3854  const auto f = QLocaleData::convertDoubleToFloat(*r, &ok);
3855  if (ok)
3856  return ParsedNumber(f);
3857  }
3858  return {};
3859 }
3860 
3872 QByteArray QByteArray::toBase64(Base64Options options) const
3873 {
3874  const char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
3875  "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
3876  const char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
3877  "ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
3878  const char *const alphabet = options & Base64UrlEncoding ? alphabet_base64url : alphabet_base64;
3879  const char padchar = '=';
3880  qsizetype padlen = 0;
3881 
3882  QByteArray tmp((size() + 2) / 3 * 4, Qt::Uninitialized);
3883 
3884  qsizetype i = 0;
3885  char *out = tmp.data();
3886  while (i < size()) {
3887  // encode 3 bytes at a time
3888  int chunk = 0;
3889  chunk |= int(uchar(data()[i++])) << 16;
3890  if (i == size()) {
3891  padlen = 2;
3892  } else {
3893  chunk |= int(uchar(data()[i++])) << 8;
3894  if (i == size())
3895  padlen = 1;
3896  else
3897  chunk |= int(uchar(data()[i++]));
3898  }
3899 
3900  int j = (chunk & 0x00fc0000) >> 18;
3901  int k = (chunk & 0x0003f000) >> 12;
3902  int l = (chunk & 0x00000fc0) >> 6;
3903  int m = (chunk & 0x0000003f);
3904  *out++ = alphabet[j];
3905  *out++ = alphabet[k];
3906 
3907  if (padlen > 1) {
3908  if ((options & OmitTrailingEquals) == 0)
3909  *out++ = padchar;
3910  } else {
3911  *out++ = alphabet[l];
3912  }
3913  if (padlen > 0) {
3914  if ((options & OmitTrailingEquals) == 0)
3915  *out++ = padchar;
3916  } else {
3917  *out++ = alphabet[m];
3918  }
3919  }
3920  Q_ASSERT((options & OmitTrailingEquals) || (out == tmp.size() + tmp.data()));
3921  if (options & OmitTrailingEquals)
3922  tmp.truncate(out - tmp.data());
3923  return tmp;
3924 }
3925 
3981 static char *qulltoa2(char *p, qulonglong n, int base)
3982 {
3983 #if defined(QT_CHECK_RANGE)
3984  if (base < 2 || base > 36) {
3985  qWarning("QByteArray::setNum: Invalid base %d", base);
3986  base = 10;
3987  }
3988 #endif
3989  const char b = 'a' - 10;
3990  do {
3991  const int c = n % base;
3992  n /= base;
3993  *--p = c + (c < 10 ? '0' : b);
3994  } while (n);
3995 
3996  return p;
3997 }
3998 
4005 {
4006  const int buffsize = 66; // big enough for MAX_ULLONG in base 2
4007  char buff[buffsize];
4008  char *p;
4009 
4010  if (n < 0) {
4011  // Take care to avoid overflow on negating min value:
4012  p = qulltoa2(buff + buffsize, qulonglong(-(1 + n)) + 1, base);
4013  *--p = '-';
4014  } else {
4015  p = qulltoa2(buff + buffsize, qulonglong(n), base);
4016  }
4017 
4018  clear();
4019  append(p, buffsize - (p - buff));
4020  return *this;
4021 }
4022 
4030 {
4031  const int buffsize = 66; // big enough for MAX_ULLONG in base 2
4032  char buff[buffsize];
4033  char *p = qulltoa2(buff + buffsize, n, base);
4034 
4035  clear();
4036  append(p, buffsize - (p - buff));
4037  return *this;
4038 }
4039 
4053 {
4054  return *this = QByteArray::number(n, format, precision);
4055 }
4056 
4087 {
4088  QByteArray s;
4089  s.setNum(n, base);
4090  return s;
4091 }
4092 
4099 {
4100  QByteArray s;
4101  s.setNum(n, base);
4102  return s;
4103 }
4104 
4111 {
4112  QByteArray s;
4113  s.setNum(n, base);
4114  return s;
4115 }
4116 
4123 {
4124  QByteArray s;
4125  s.setNum(n, base);
4126  return s;
4127 }
4128 
4135 {
4136  QByteArray s;
4137  s.setNum(n, base);
4138  return s;
4139 }
4140 
4147 {
4148  QByteArray s;
4149  s.setNum(n, base);
4150  return s;
4151 }
4152 
4166 {
4168 
4169  switch (asciiLower(format)) {
4170  case 'f':
4172  break;
4173  case 'e':
4175  break;
4176  case 'g':
4178  break;
4179  default:
4180 #if defined(QT_CHECK_RANGE)
4181  qWarning("QByteArray::setNum: Invalid format char '%c'", format);
4182 #endif
4183  break;
4184  }
4185 
4186  return qdtoAscii(n, form, precision, isUpperCaseAscii(format));
4187 }
4188 
4240 {
4241  if (!data || !size)
4242  clear();
4243  else
4244  *this = fromRawData(data, size);
4245  return *this;
4246 }
4247 
4248 namespace {
4249 struct fromBase64_helper_result {
4250  qsizetype decodedLength;
4252 };
4253 
4254 fromBase64_helper_result fromBase64_helper(const char *input, qsizetype inputSize,
4255  char *output /* may alias input */,
4256  QByteArray::Base64Options options)
4257 {
4258  fromBase64_helper_result result{ 0, QByteArray::Base64DecodingStatus::Ok };
4259 
4260  unsigned int buf = 0;
4261  int nbits = 0;
4262 
4263  qsizetype offset = 0;
4264  for (qsizetype i = 0; i < inputSize; ++i) {
4265  int ch = input[i];
4266  int d;
4267 
4268  if (ch >= 'A' && ch <= 'Z') {
4269  d = ch - 'A';
4270  } else if (ch >= 'a' && ch <= 'z') {
4271  d = ch - 'a' + 26;
4272  } else if (ch >= '0' && ch <= '9') {
4273  d = ch - '0' + 52;
4274  } else if (ch == '+' && (options & QByteArray::Base64UrlEncoding) == 0) {
4275  d = 62;
4276  } else if (ch == '-' && (options & QByteArray::Base64UrlEncoding) != 0) {
4277  d = 62;
4278  } else if (ch == '/' && (options & QByteArray::Base64UrlEncoding) == 0) {
4279  d = 63;
4280  } else if (ch == '_' && (options & QByteArray::Base64UrlEncoding) != 0) {
4281  d = 63;
4282  } else {
4284  if (ch == '=') {
4285  // can have 1 or 2 '=' signs, in both cases padding base64Size to
4286  // a multiple of 4. Any other case is illegal.
4287  if ((inputSize % 4) != 0) {
4289  return result;
4290  } else if ((i == inputSize - 1) ||
4291  (i == inputSize - 2 && input[++i] == '=')) {
4292  d = -1; // ... and exit the loop, normally
4293  } else {
4295  return result;
4296  }
4297  } else {
4299  return result;
4300  }
4301  } else {
4302  d = -1;
4303  }
4304  }
4305 
4306  if (d != -1) {
4307  buf = (buf << 6) | d;
4308  nbits += 6;
4309  if (nbits >= 8) {
4310  nbits -= 8;
4311  Q_ASSERT(offset < i);
4312  output[offset++] = buf >> nbits;
4313  buf &= (1 << nbits) - 1;
4314  }
4315  }
4316  }
4317 
4318  result.decodedLength = offset;
4319  return result;
4320 }
4321 } // anonymous namespace
4322 
4351 {
4352  // try to avoid a detach when calling data(), as it would over-allocate
4353  // (we need less space when decoding than the one required by the full copy)
4354  if (base64.isDetached()) {
4355  const auto base64result = fromBase64_helper(base64.data(),
4356  base64.size(),
4357  base64.data(), // in-place
4358  options);
4359  base64.truncate(int(base64result.decodedLength));
4360  return { std::move(base64), base64result.status };
4361  }
4362 
4363  return fromBase64Encoding(base64, options);
4364 }
4365 
4366 
4368 {
4369  const auto base64Size = base64.size();
4370  QByteArray result((base64Size * 3) / 4, Qt::Uninitialized);
4371  const auto base64result = fromBase64_helper(base64.data(),
4372  base64Size,
4373  const_cast<char *>(result.constData()),
4374  options);
4375  result.truncate(int(base64result.decodedLength));
4376  return { std::move(result), base64result.status };
4377 }
4378 
4403 QByteArray QByteArray::fromBase64(const QByteArray &base64, Base64Options options)
4404 {
4405  if (auto result = fromBase64Encoding(base64, options))
4406  return std::move(result.decoded);
4407  return QByteArray();
4408 }
4409 
4422 {
4423  QByteArray res((hexEncoded.size() + 1)/ 2, Qt::Uninitialized);
4424  uchar *result = (uchar *)res.data() + res.size();
4425 
4426  bool odd_digit = true;
4427  for (qsizetype i = hexEncoded.size() - 1; i >= 0; --i) {
4428  uchar ch = uchar(hexEncoded.at(i));
4429  int tmp = QtMiscUtils::fromHex(ch);
4430  if (tmp == -1)
4431  continue;
4432  if (odd_digit) {
4433  --result;
4434  *result = tmp;
4435  odd_digit = false;
4436  } else {
4437  *result |= tmp << 4;
4438  odd_digit = true;
4439  }
4440  }
4441 
4442  res.remove(0, result - (const uchar *)res.constData());
4443  return res;
4444 }
4445 
4460 QByteArray QByteArray::toHex(char separator) const
4461 {
4462  if (isEmpty())
4463  return QByteArray();
4464 
4465  const qsizetype length = separator ? (size() * 3 - 1) : (size() * 2);
4467  char *hexData = hex.data();
4468  const uchar *data = (const uchar *)this->data();
4469  for (qsizetype i = 0, o = 0; i < size(); ++i) {
4470  hexData[o++] = QtMiscUtils::toHexLower(data[i] >> 4);
4471  hexData[o++] = QtMiscUtils::toHexLower(data[i] & 0xf);
4472 
4473  if ((separator) && (o < length))
4474  hexData[o++] = separator;
4475  }
4476  return hex;
4477 }
4478 
4479 static void q_fromPercentEncoding(QByteArray *ba, char percent)
4480 {
4481  if (ba->isEmpty())
4482  return;
4483 
4484  char *data = ba->data();
4485  const char *inputPtr = data;
4486 
4487  qsizetype i = 0;
4488  qsizetype len = ba->count();
4489  qsizetype outlen = 0;
4490  int a, b;
4491  char c;
4492  while (i < len) {
4493  c = inputPtr[i];
4494  if (c == percent && i + 2 < len) {
4495  a = inputPtr[++i];
4496  b = inputPtr[++i];
4497 
4498  if (a >= '0' && a <= '9') a -= '0';
4499  else if (a >= 'a' && a <= 'f') a = a - 'a' + 10;
4500  else if (a >= 'A' && a <= 'F') a = a - 'A' + 10;
4501 
4502  if (b >= '0' && b <= '9') b -= '0';
4503  else if (b >= 'a' && b <= 'f') b = b - 'a' + 10;
4504  else if (b >= 'A' && b <= 'F') b = b - 'A' + 10;
4505 
4506  *data++ = (char)((a << 4) | b);
4507  } else {
4508  *data++ = c;
4509  }
4510 
4511  ++i;
4512  ++outlen;
4513  }
4514 
4515  if (outlen != len)
4516  ba->truncate(outlen);
4517 }
4518 
4520 {
4521  q_fromPercentEncoding(ba, '%');
4522 }
4523 
4541 {
4542  if (input.isNull())
4543  return QByteArray(); // preserve null
4544  if (input.isEmpty())
4545  return QByteArray(input.data(), 0);
4546 
4547  QByteArray tmp = input;
4548  q_fromPercentEncoding(&tmp, percent);
4549  return tmp;
4550 }
4551 
4573 static inline bool q_strchr(const char str[], char chr)
4574 {
4575  if (!str) return false;
4576 
4577  const char *ptr = str;
4578  char c;
4579  while ((c = *ptr++))
4580  if (c == chr)
4581  return true;
4582  return false;
4583 }
4584 
4585 static void q_toPercentEncoding(QByteArray *ba, const char *dontEncode, const char *alsoEncode, char percent)
4586 {
4587  if (ba->isEmpty())
4588  return;
4589 
4590  QByteArray input = *ba;
4591  qsizetype len = input.count();
4592  const char *inputData = input.constData();
4593  char *output = nullptr;
4594  qsizetype length = 0;
4595 
4596  for (qsizetype i = 0; i < len; ++i) {
4597  unsigned char c = *inputData++;
4598  if (((c >= 0x61 && c <= 0x7A) // ALPHA
4599  || (c >= 0x41 && c <= 0x5A) // ALPHA
4600  || (c >= 0x30 && c <= 0x39) // DIGIT
4601  || c == 0x2D // -
4602  || c == 0x2E // .
4603  || c == 0x5F // _
4604  || c == 0x7E // ~
4605  || q_strchr(dontEncode, c))
4606  && !q_strchr(alsoEncode, c)) {
4607  if (output)
4608  output[length] = c;
4609  ++length;
4610  } else {
4611  if (!output) {
4612  // detach now
4613  ba->resize(len*3); // worst case
4614  output = ba->data();
4615  }
4616  output[length++] = percent;
4617  output[length++] = QtMiscUtils::toHexUpper((c & 0xf0) >> 4);
4618  output[length++] = QtMiscUtils::toHexUpper(c & 0xf);
4619  }
4620  }
4621  if (output)
4622  ba->truncate(length);
4623 }
4624 
4625 void q_toPercentEncoding(QByteArray *ba, const char *exclude, const char *include)
4626 {
4627  q_toPercentEncoding(ba, exclude, include, '%');
4628 }
4629 
4630 void q_normalizePercentEncoding(QByteArray *ba, const char *exclude)
4631 {
4632  q_fromPercentEncoding(ba, '%');
4633  q_toPercentEncoding(ba, exclude, nullptr, '%');
4634 }
4635 
4661  char percent) const
4662 {
4663  if (isNull())
4664  return QByteArray(); // preserve null
4665  if (isEmpty())
4666  return QByteArray(data(), 0);
4667 
4668  QByteArray include2 = include;
4669  if (percent != '%') // the default
4670  if ((percent >= 0x61 && percent <= 0x7A) // ALPHA
4671  || (percent >= 0x41 && percent <= 0x5A) // ALPHA
4672  || (percent >= 0x30 && percent <= 0x39) // DIGIT
4673  || percent == 0x2D // -
4674  || percent == 0x2E // .
4675  || percent == 0x5F // _
4676  || percent == 0x7E) // ~
4677  include2 += percent;
4678 
4679  QByteArray result = *this;
4680  q_toPercentEncoding(&result, exclude.nulTerminated().constData(), include2.nulTerminated().constData(), percent);
4681 
4682  return result;
4683 }
4684 
4878 size_t qHash(const QByteArray::FromBase64Result &key, size_t seed) noexcept
4879 {
4880  return qHashMulti(seed, key.decoded, static_cast<int>(key.decodingStatus));
4881 }
4882 
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
FT_UInt idx
Definition: cffcmap.c:135
The QByteArray::FromBase64Result class holds the result of a call to QByteArray::fromBase64Encoding.
Definition: qbytearray.h:625
size_t qHash(const QByteArray::FromBase64Result &key, size_t seed) noexcept
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:85
char * data()
Definition: qbytearray.h:516
qulonglong toULongLong(bool *ok=nullptr, int base=10) const
qlonglong toLongLong(bool *ok=nullptr, int base=10) const
char * iterator
Definition: qbytearray.h:419
char * qstrncpy(char *dst, const char *src, size_t len)
Definition: qbytearray.cpp:161
const_iterator constBegin() const noexcept
Definition: qbytearray.h:428
QByteArray & prepend(char c)
Definition: qbytearray.h:238
size_t qstrlen(const char *str)
QByteArray repeated(qsizetype times) const
QDataStream & operator<<(QDataStream &out, const QByteArray &ba)
QDataStream & operator>>(QDataStream &in, QByteArray &ba)
QByteArray & operator=(const QByteArray &) noexcept
uint toUInt(bool *ok=nullptr, int base=10) const
QByteArray & fill(char c, qsizetype size=-1)
QByteArray qCompress(const uchar *data, qsizetype nbytes, int compressionLevel)
Definition: qbytearray.cpp:556
qsizetype size() const noexcept
Definition: qbytearray.h:470
quint16 qChecksum(QByteArrayView data, Qt::ChecksumType standard)
Definition: qbytearray.cpp:497
static QByteArray fromHex(const QByteArray &hexEncoded)
QByteArray qUncompress(const QByteArray &data)
Definition: qbytearray.h:618
QByteArray last(qsizetype n) const
Definition: qbytearray.h:183
const char * constData() const noexcept
Definition: qbytearray.h:144
QByteArray & setNum(short, int base=10)
Definition: qbytearray.h:587
int toInt(bool *ok=nullptr, int base=10) const
bool isLower() const
QList< QByteArray > split(char sep) const
int qstricmp(const char *str1, const char *str2)
Definition: qbytearray.cpp:260
static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent='%')
qsizetype indexOf(char c, qsizetype from=0) const
iterator erase(const_iterator first, const_iterator last)
void chop(qsizetype n)
qsizetype length() const noexcept
Definition: qbytearray.h:472
bool isUpper() const
ushort toUShort(bool *ok=nullptr, int base=10) const
iterator end()
Definition: qbytearray.h:429
const char * const_iterator
Definition: qbytearray.h:420
long toLong(bool *ok=nullptr, int base=10) const
void truncate(qsizetype pos)
double toDouble(bool *ok=nullptr) const
static QByteArray fromBase64(const QByteArray &base64, Base64Options options=Base64Encoding)
@ Base64UrlEncoding
Definition: qbytearray.h:97
@ AbortOnBase64DecodingErrors
Definition: qbytearray.h:103
@ OmitTrailingEquals
Definition: qbytearray.h:100
QByteArray right(qsizetype len) const
char at(qsizetype i) const
Definition: qbytearray.h:505
QByteArray toPercentEncoding(const QByteArray &exclude=QByteArray(), const QByteArray &include=QByteArray(), char percent='%') const
int qstrnicmp(const char *str1, const char *str2, size_t len)
Definition: qbytearray.cpp:350
QByteArray & insert(qsizetype i, QByteArrayView data)
bool isEmpty() const noexcept
Definition: qbytearray.h:129
constexpr QByteArray() noexcept
Definition: qbytearray.h:502
short toShort(bool *ok=nullptr, int base=10) const
void detach()
Definition: qbytearray.h:530
const_iterator cbegin() const noexcept
Definition: qbytearray.h:427
ulong toULong(bool *ok=nullptr, int base=10) const
static QByteArray number(int, int base=10)
qsizetype count() const noexcept
Definition: qbytearray.h:471
Base64DecodingStatus
Definition: qbytearray.h:107
float toFloat(bool *ok=nullptr) const
char * qstrcpy(char *dst, const char *src)
Definition: qbytearray.cpp:128
QByteArray leftJustified(qsizetype width, char fill=' ', bool truncate=false) const
QByteArrayData DataPointer
Definition: qbytearray.h:87
void clear()
int qstrcmp(const char *str1, const char *str2)
Definition: qbytearray.cpp:215
QByteArray left(qsizetype len) const
QByteArray rightJustified(qsizetype width, char fill=' ', bool truncate=false) const
qsizetype lastIndexOf(char c, qsizetype from=-1) const
iterator begin()
Definition: qbytearray.h:425
qsizetype capacity() const
Definition: qbytearray.h:537
void resize(qsizetype size)
QByteArray & remove(qsizetype index, qsizetype len)
QByteArray & append(char c)
QByteArray toBase64(Base64Options options=Base64Encoding) const
char * qstrdup(const char *src)
Definition: qbytearray.cpp:106
qsizetype count(char c) const
QByteArray & setRawData(const char *a, qsizetype n)
QByteArray toHex(char separator='\0') const
bool isNull() const noexcept
QByteArray mid(qsizetype index, qsizetype len=-1) const
static FromBase64Result fromBase64Encoding(QByteArray &&base64, Base64Options options=Base64Encoding)
static QByteArray fromRawData(const char *data, qsizetype size)
Definition: qbytearray.h:396
QByteArray & replace(qsizetype index, qsizetype len, const char *s, qsizetype alen)
Definition: qbytearray.h:278
The QByteArrayMatcher class holds a sequence of bytes that can be quickly matched in a byte array.
Q_WEAK_OVERLOAD qsizetype indexIn(const QByteArray &ba, qsizetype from=0) const
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
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:66
QChar * data()
Definition: qstring.h:1228
Definition: base.h:37
int ZEXPORT compress2(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level)
Definition: compress.c:22
#define this
Definition: dialogs.cpp:56
QString str
[2]
double e
#define Z_BUF_ERROR
Definition: zlib.h:139
#define Z_OK
Definition: zlib.h:132
#define Z_DATA_ERROR
Definition: zlib.h:137
#define Z_MEM_ERROR
Definition: zlib.h:138
#define forever
Definition: ftrandom.c:53
uLong FAR uLongf
Definition: ftzconf.h:233
auto it unsigned count const
Definition: hb-iter.hh:848
#define Null(Type)
Definition: hb-null.hh:106
register bit_buf_type register int int nbits
Definition: jdhuff.h:177
GeneratorWrapper< std::vector< T > > chunk(size_t size, GeneratorWrapper< T > &&generator)
Definition: catch_p_p.h:4333
ChecksumType
Definition: qnamespace.h:1718
@ ChecksumIso3309
Definition: qnamespace.h:1719
@ ChecksumItuV41
Definition: qnamespace.h:1720
constexpr Initialization Uninitialized
Definition: qnamespace.h:1613
Initialization
Definition: qnamespace.h:1610
constexpr char toHexUpper(uint value) noexcept
Definition: qtools_p.h:60
constexpr char toHexLower(uint value) noexcept
Definition: qtools_p.h:65
constexpr int fromHex(uint c) noexcept
Definition: qtools_p.h:70
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)
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)
Definition: qbytearray.cpp:419
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
Definition: qbytearray.cpp:435
constexpr struct q20::ranges::@311 none_of
int distance(TestIterator &a, TestIterator &b)
void *PRIV() memmove(void *d, const void *s, size_t n)
int PRIV() strcmp(PCRE2_SPTR str1, PCRE2_SPTR str2)
PCRE2_SIZE PRIV() strlen(PCRE2_SPTR str)
#define SET_BIT(c)
Definition: pcre2_study.c:57
png_uint_32 crc
Definition: png.c:2247
QT_POPCOUNT_RELAXED_CONSTEXPR uint qCountLeadingZeroBits(quint32 v) noexcept
Definition: qalgorithms.h:411
constexpr uint qCountTrailingZeroBits(quint32 v) noexcept
Definition: qalgorithms.h:362
const int blockSize
#define REHASH(a)
void q_normalizePercentEncoding(QByteArray *ba, const char *exclude)
void q_fromPercentEncoding(QByteArray *ba)
qsizetype qFindByteArray(const char *haystack0, qsizetype haystackLen, qsizetype from, const char *needle0, qsizetype needleLen)
void q_toPercentEncoding(QByteArray *ba, const char *exclude, const char *include)
QByteArrayView qToByteArrayViewIgnoringNull(const QByteArrayLike &b) noexcept
#define Q_UNLIKELY(x)
#define Q_ASSUME(Expr)
#define Q_UNREACHABLE()
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
unsigned int quint32
Definition: qglobal.h:288
QT_BEGIN_INCLUDE_NAMESPACE typedef unsigned char uchar
Definition: qglobal.h:332
unsigned short quint16
Definition: qglobal.h:286
size_t quintptr
Definition: qglobal.h:310
unsigned long ulong
Definition: qglobal.h:335
ptrdiff_t qptrdiff
Definition: qglobal.h:307
quint64 qulonglong
Definition: qglobal.h:302
ptrdiff_t qsizetype
Definition: qglobal.h:308
unsigned int uint
Definition: qglobal.h:334
unsigned short ushort
Definition: qglobal.h:333
qint64 qlonglong
Definition: qglobal.h:301
constexpr QtPrivate::QHashMultiReturnType< T... > qHashMulti(size_t seed, const T &... args) noexcept(std::conjunction_v< QtPrivate::QNothrowHashable< T >... >)
QByteArray qdtoAscii(double d, QLocaleData::DoubleForm form, int precision, bool uppercase)
double qt_asciiToDouble(const char *num, qsizetype numLen, bool &ok, int &processed, StrayCharacterMode strayCharMode)
@ WhitespacesAllowed
#define qWarning
Definition: qlogging.h:179
GLenum GLuint GLenum GLsizei length
Definition: qopengl.h:270
GLint GLfloat GLfloat GLfloat v2
GLboolean GLboolean GLboolean b
const GLfloat * m
GLuint64 key
GLboolean r
[2]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLenum GLenum GLsizei count
GLfloat GLfloat f
GLenum src
GLint GLsizei width
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
Definition: qopenglext.h:5206
GLuint res
Definition: qopenglext.h:8867
const GLubyte * c
Definition: qopenglext.h:12701
GLenum GLsizei len
Definition: qopenglext.h:3292
GLuint in
Definition: qopenglext.h:8870
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLuint GLenum option
Definition: qopenglext.h:5929
GLfixed u1
Definition: qopenglext.h:5206
GLuint num
Definition: qopenglext.h:5654
GLenum GLenum GLenum input
Definition: qopenglext.h:10816
GLenum GLint GLint * precision
Definition: qopenglext.h:1890
#define Q_ASSERT(cond)
Definition: qrandom.cpp:84
#define zero
#define s2
#define v1
#define s1
#define v0
constexpr qsizetype MaxAllocSize
Definition: qtools_p.h:95
Q_UNUSED(salary)
[21]
Q_CHECK_PTR(a=new int[80])
QByteArray ba
[0]
QString base
QTextStream out(stdout)
[7]
QSharedPointer< T > other(t)
[5]
QGraphicsWidget * form
QQuickView * view
[0]
QStringList list
[0]
void detachAndGrow(QArrayData::GrowthPosition where, qsizetype n, const T **data, QArrayDataPointer *old)
bool isNull() const noexcept
qsizetype freeSpaceAtBegin() const noexcept
T * data() noexcept
bool needsDetach() const noexcept
qsizetype allocatedCapacity() noexcept
qsizetype freeSpaceAtEnd() const noexcept
qsizetype constAllocatedCapacity() const noexcept
void clear() noexcept(std::is_nothrow_destructible< T >::value)
T * begin() noexcept
static QArrayDataPointer fromRawData(const T *rawData, qsizetype length) noexcept
static QArrayDataPointer allocateGrow(const QArrayDataPointer &from, qsizetype n, QArrayData::GrowthPosition position)
bool isMutable() const noexcept
static quint64 bytearrayToUnsLongLong(QByteArrayView num, int base, bool *ok)
Definition: qlocale.cpp:4185
static float convertDoubleToFloat(double d, bool *ok)
Definition: qlocale_p.h:262
@ DFSignificantDigits
Definition: qlocale_p.h:205
static Q_CORE_EXPORT qint64 bytearrayToLongLong(QByteArrayView num, int base, bool *ok)
Definition: qlocale.cpp:4149
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:137
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)
Definition: main.cpp:38
ByteArray detached(ByteArray b)
#define rhs
const char alphabet[]
int ZEXPORT uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: uncompr.c:86