summaryrefslogtreecommitdiffstats
path: root/src/corelib/text
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2019-05-27 19:13:54 +0200
committerEdward Welbourne <edward.welbourne@qt.io>2019-07-10 17:05:30 +0200
commita9aa206b7b8ac4e69f8c46233b4080e00e845ff5 (patch)
tree0d19cb1f1a3b9d79d322e6e63f6f72160977ca67 /src/corelib/text
parent85d3061c1cd4617ef09cb381320611c27da205a5 (diff)
Move text-related code out of corelib/tools/ to corelib/text/
This includes byte array, string, char, unicode, locale, collation and regular expressions. Change-Id: I8b125fa52c8c513eb57a0f1298b91910e5a0d786 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/corelib/text')
-rw-r--r--src/corelib/text/UNICODE_LICENSE.txt31
-rw-r--r--src/corelib/text/qbytearray.cpp5020
-rw-r--r--src/corelib/text/qbytearray.h754
-rw-r--r--src/corelib/text/qbytearray_p.h66
-rw-r--r--src/corelib/text/qbytearraylist.cpp175
-rw-r--r--src/corelib/text/qbytearraylist.h94
-rw-r--r--src/corelib/text/qbytearraymatcher.cpp435
-rw-r--r--src/corelib/text/qbytearraymatcher.h164
-rw-r--r--src/corelib/text/qbytedata_p.h245
-rw-r--r--src/corelib/text/qchar.cpp2059
-rw-r--r--src/corelib/text/qchar.h644
-rw-r--r--src/corelib/text/qcollator.cpp456
-rw-r--r--src/corelib/text/qcollator.h135
-rw-r--r--src/corelib/text/qcollator_icu.cpp154
-rw-r--r--src/corelib/text/qcollator_macx.cpp152
-rw-r--r--src/corelib/text/qcollator_p.h148
-rw-r--r--src/corelib/text/qcollator_posix.cpp116
-rw-r--r--src/corelib/text/qcollator_win.cpp175
-rw-r--r--src/corelib/text/qdoublescanprint_p.h156
-rw-r--r--src/corelib/text/qharfbuzz.cpp109
-rw-r--r--src/corelib/text/qharfbuzz_p.h357
-rw-r--r--src/corelib/text/qlocale.cpp4223
-rw-r--r--src/corelib/text/qlocale.h1153
-rw-r--r--src/corelib/text/qlocale.qdoc1278
-rw-r--r--src/corelib/text/qlocale_data_p.h8814
-rw-r--r--src/corelib/text/qlocale_icu.cpp111
-rw-r--r--src/corelib/text/qlocale_mac.mm508
-rw-r--r--src/corelib/text/qlocale_p.h471
-rw-r--r--src/corelib/text/qlocale_tools.cpp578
-rw-r--r--src/corelib/text/qlocale_tools_p.h124
-rw-r--r--src/corelib/text/qlocale_unix.cpp300
-rw-r--r--src/corelib/text/qlocale_win.cpp1143
-rw-r--r--src/corelib/text/qregexp.cpp4609
-rw-r--r--src/corelib/text/qregexp.h134
-rw-r--r--src/corelib/text/qregularexpression.cpp2986
-rw-r--r--src/corelib/text/qregularexpression.h279
-rw-r--r--src/corelib/text/qstring.cpp12592
-rw-r--r--src/corelib/text/qstring.h2043
-rw-r--r--src/corelib/text/qstring_compat.cpp112
-rw-r--r--src/corelib/text/qstring_mips_dsp_asm.S447
-rw-r--r--src/corelib/text/qstringalgorithms.h106
-rw-r--r--src/corelib/text/qstringalgorithms_p.h152
-rw-r--r--src/corelib/text/qstringbuilder.cpp137
-rw-r--r--src/corelib/text/qstringbuilder.h494
-rw-r--r--src/corelib/text/qstringiterator.qdoc314
-rw-r--r--src/corelib/text/qstringiterator_p.h255
-rw-r--r--src/corelib/text/qstringlist.cpp923
-rw-r--r--src/corelib/text/qstringlist.h406
-rw-r--r--src/corelib/text/qstringliteral.h112
-rw-r--r--src/corelib/text/qstringmatcher.cpp348
-rw-r--r--src/corelib/text/qstringmatcher.h93
-rw-r--r--src/corelib/text/qstringview.cpp898
-rw-r--r--src/corelib/text/qstringview.h338
-rw-r--r--src/corelib/text/qt_attribution.json39
-rw-r--r--src/corelib/text/qtextboundaryfinder.cpp511
-rw-r--r--src/corelib/text/qtextboundaryfinder.h111
-rw-r--r--src/corelib/text/qunicodetables.cpp13446
-rw-r--r--src/corelib/text/qunicodetables_p.h232
-rw-r--r--src/corelib/text/qunicodetools.cpp847
-rw-r--r--src/corelib/text/qunicodetools_p.h110
-rw-r--r--src/corelib/text/qvsnprintf.cpp129
-rw-r--r--src/corelib/text/text.pri100
62 files changed, 73651 insertions, 0 deletions
diff --git a/src/corelib/text/UNICODE_LICENSE.txt b/src/corelib/text/UNICODE_LICENSE.txt
new file mode 100644
index 0000000000..1c73202b74
--- /dev/null
+++ b/src/corelib/text/UNICODE_LICENSE.txt
@@ -0,0 +1,31 @@
+Copyright © 1991-2018 Unicode, Inc. All rights reserved.
+Distributed under the Terms of Use in http://www.unicode.org/copyright.html.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Unicode data files and any associated documentation
+(the "Data Files") or Unicode software and any associated documentation
+(the "Software") to deal in the Data Files or Software
+without restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, and/or sell copies of
+the Data Files or Software, and to permit persons to whom the Data Files
+or Software are furnished to do so, provided that either
+(a) this copyright and permission notice appear with all copies
+of the Data Files or Software, or
+(b) this copyright and permission notice appear in associated
+Documentation.
+
+THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT OF THIRD PARTY RIGHTS.
+IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS
+NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL
+DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THE DATA FILES OR SOFTWARE.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale,
+use or other dealings in these Data Files or Software without prior
+written authorization of the copyright holder.
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
new file mode 100644
index 0000000000..fcf7b5e709
--- /dev/null
+++ b/src/corelib/text/qbytearray.cpp
@@ -0,0 +1,5020 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Copyright (C) 2016 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbytearray.h"
+#include "qbytearraymatcher.h"
+#include "private/qtools_p.h"
+#include "qstring.h"
+#include "qlist.h"
+#include "qlocale.h"
+#include "qlocale_p.h"
+#include "qlocale_tools_p.h"
+#include "private/qnumeric_p.h"
+#include "private/qsimd_p.h"
+#include "qstringalgorithms_p.h"
+#include "qscopedpointer.h"
+#include "qbytearray_p.h"
+#include <qdatastream.h>
+#include <qmath.h>
+
+#ifndef QT_NO_COMPRESS
+#include <zconf.h>
+#include <zlib.h>
+#endif
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define IS_RAW_DATA(d) ((d)->offset != sizeof(QByteArrayData))
+
+QT_BEGIN_NAMESPACE
+
+// Latin 1 case system, used by QByteArray::to{Upper,Lower}() and qstr(n)icmp():
+/*
+#!/usr/bin/perl -l
+use feature "unicode_strings";
+for (0..255) {
+ $up = uc(chr($_));
+ $up = chr($_) if ord($up) > 0x100 || length $up > 1;
+ printf "0x%02x,", ord($up);
+ print "" if ($_ & 0xf) == 0xf;
+}
+*/
+static const uchar latin1_uppercased[256] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
+ 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x7b,0x7c,0x7d,0x7e,0x7f,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+ 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+ 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
+ 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+ 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xf7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xff
+};
+
+/*
+#!/usr/bin/perl -l
+use feature "unicode_strings";
+for (0..255) {
+ $up = lc(chr($_));
+ $up = chr($_) if ord($up) > 0x100 || length $up > 1;
+ printf "0x%02x,", ord($up);
+ print "" if ($_ & 0xf) == 0xf;
+}
+*/
+static const uchar latin1_lowercased[256] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x5b,0x5c,0x5d,0x5e,0x5f,
+ 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+ 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
+ 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xd7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xdf,
+ 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
+ 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
+};
+
+int qFindByteArray(
+ const char *haystack0, int haystackLen, int from,
+ const char *needle0, int needleLen);
+
+/*****************************************************************************
+ Safe and portable C string functions; extensions to standard string.h
+ *****************************************************************************/
+
+/*! \relates QByteArray
+
+ Returns a duplicate string.
+
+ Allocates space for a copy of \a src, copies it, and returns a
+ pointer to the copy. If \a src is \nullptr, it immediately returns
+ \nullptr.
+
+ Ownership is passed to the caller, so the returned string must be
+ deleted using \c delete[].
+*/
+
+char *qstrdup(const char *src)
+{
+ if (!src)
+ return nullptr;
+ char *dst = new char[strlen(src) + 1];
+ return qstrcpy(dst, src);
+}
+
+/*! \relates QByteArray
+
+ Copies all the characters up to and including the '\\0' from \a
+ src into \a dst and returns a pointer to \a dst. If \a src is
+ \nullptr, it immediately returns \nullptr.
+
+ This function assumes that \a dst is large enough to hold the
+ contents of \a src.
+
+ \note If \a dst and \a src overlap, the behavior is undefined.
+
+ \sa qstrncpy()
+*/
+
+char *qstrcpy(char *dst, const char *src)
+{
+ if (!src)
+ return nullptr;
+#ifdef Q_CC_MSVC
+ const int len = int(strlen(src));
+ // This is actually not secure!!! It will be fixed
+ // properly in a later release!
+ if (len >= 0 && strcpy_s(dst, len+1, src) == 0)
+ return dst;
+ return nullptr;
+#else
+ return strcpy(dst, src);
+#endif
+}
+
+/*! \relates QByteArray
+
+ A safe \c strncpy() function.
+
+ Copies at most \a len bytes from \a src (stopping at \a len or the
+ terminating '\\0' whichever comes first) into \a dst and returns a
+ pointer to \a dst. Guarantees that \a dst is '\\0'-terminated. If
+ \a src or \a dst is \nullptr, returns \nullptr immediately.
+
+ This function assumes that \a dst is at least \a len characters
+ long.
+
+ \note If \a dst and \a src overlap, the behavior is undefined.
+
+ \note When compiling with Visual C++ compiler version 14.00
+ (Visual C++ 2005) or later, internally the function strncpy_s
+ will be used.
+
+ \sa qstrcpy()
+*/
+
+char *qstrncpy(char *dst, const char *src, uint len)
+{
+ if (!src || !dst)
+ return nullptr;
+ if (len > 0) {
+#ifdef Q_CC_MSVC
+ strncpy_s(dst, len, src, len - 1);
+#else
+ strncpy(dst, src, len);
+#endif
+ dst[len-1] = '\0';
+ }
+ return dst;
+}
+
+/*! \fn uint qstrlen(const char *str)
+ \relates QByteArray
+
+ A safe \c strlen() function.
+
+ Returns the number of characters that precede the terminating '\\0',
+ or 0 if \a str is \nullptr.
+
+ \sa qstrnlen()
+*/
+
+/*! \fn uint qstrnlen(const char *str, uint maxlen)
+ \relates QByteArray
+ \since 4.2
+
+ A safe \c strnlen() function.
+
+ Returns the number of characters that precede the terminating '\\0', but
+ at most \a maxlen. If \a str is \nullptr, returns 0.
+
+ \sa qstrlen()
+*/
+
+/*!
+ \relates QByteArray
+
+ A safe \c strcmp() function.
+
+ Compares \a str1 and \a str2. Returns a negative value if \a str1
+ is less than \a str2, 0 if \a str1 is equal to \a str2 or a
+ positive value if \a str1 is greater than \a str2.
+
+ Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr.
+
+ Special case 2: Returns an arbitrary non-zero value if \a str1 is
+ \nullptr or \a str2 is \nullptr (but not both).
+
+ \sa qstrncmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons},
+ QByteArray::compare()
+*/
+int qstrcmp(const char *str1, const char *str2)
+{
+ return (str1 && str2) ? strcmp(str1, str2)
+ : (str1 ? 1 : (str2 ? -1 : 0));
+}
+
+/*! \fn int qstrncmp(const char *str1, const char *str2, uint len);
+
+ \relates QByteArray
+
+ A safe \c strncmp() function.
+
+ Compares at most \a len bytes of \a str1 and \a str2.
+
+ Returns a negative value if \a str1 is less than \a str2, 0 if \a
+ str1 is equal to \a str2 or a positive value if \a str1 is greater
+ than \a str2.
+
+ Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr.
+
+ Special case 2: Returns a random non-zero value if \a str1 is \nullptr
+ or \a str2 is \nullptr (but not both).
+
+ \sa qstrcmp(), qstricmp(), qstrnicmp(), {8-bit Character Comparisons},
+ QByteArray::compare()
+*/
+
+/*! \relates QByteArray
+
+ A safe \c stricmp() function.
+
+ Compares \a str1 and \a str2 ignoring the case of the
+ characters. The encoding of the strings is assumed to be Latin-1.
+
+ Returns a negative value if \a str1 is less than \a str2, 0 if \a
+ str1 is equal to \a str2 or a positive value if \a str1 is greater
+ than \a str2.
+
+ Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr.
+
+ Special case 2: Returns a random non-zero value if \a str1 is \nullptr
+ or \a str2 is \nullptr (but not both).
+
+ \sa qstrcmp(), qstrncmp(), qstrnicmp(), {8-bit Character Comparisons},
+ QByteArray::compare()
+*/
+
+int qstricmp(const char *str1, const char *str2)
+{
+ const uchar *s1 = reinterpret_cast<const uchar *>(str1);
+ const uchar *s2 = reinterpret_cast<const uchar *>(str2);
+ if (!s1)
+ return s2 ? -1 : 0;
+ if (!s2)
+ return 1;
+
+ enum { Incomplete = 256 };
+ qptrdiff offset = 0;
+ auto innerCompare = [=, &offset](qptrdiff max, bool unlimited) {
+ max += offset;
+ do {
+ uchar c = latin1_lowercased[s1[offset]];
+ int res = c - latin1_lowercased[s2[offset]];
+ if (Q_UNLIKELY(res))
+ return res;
+ if (Q_UNLIKELY(!c))
+ return 0;
+ ++offset;
+ } while (unlimited || offset < max);
+ return int(Incomplete);
+ };
+
+#if defined(__SSE4_1__) && !(defined(__SANITIZE_ADDRESS__) || QT_HAS_FEATURE(address_sanitizer))
+ enum { PageSize = 4096, PageMask = PageSize - 1 };
+ const __m128i zero = _mm_setzero_si128();
+ forever {
+ // Calculate how many bytes we can load until we cross a page boundary
+ // for either source. This isn't an exact calculation, just something
+ // very quick.
+ quintptr u1 = quintptr(s1 + offset);
+ quintptr u2 = quintptr(s2 + offset);
+ uint n = PageSize - ((u1 | u2) & PageMask);
+
+ qptrdiff maxoffset = offset + n;
+ for ( ; offset + 16 <= maxoffset; offset += sizeof(__m128i)) {
+ // load 16 bytes from either source
+ __m128i a = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s1 + offset));
+ __m128i b = _mm_loadu_si128(reinterpret_cast<const __m128i *>(s2 + offset));
+
+ // compare the two against each oher
+ __m128i cmp = _mm_cmpeq_epi8(a, b);
+
+ // find NUL terminators too
+ cmp = _mm_min_epu8(cmp, a);
+ cmp = _mm_cmpeq_epi8(cmp, zero);
+
+ // was there any difference or a NUL?
+ uint mask = _mm_movemask_epi8(cmp);
+ if (mask) {
+ // yes, find out where
+ uint start = qCountTrailingZeroBits(mask);
+ uint end = sizeof(mask) * 8 - qCountLeadingZeroBits(mask);
+ Q_ASSUME(end >= start);
+ offset += start;
+ n = end - start;
+ break;
+ }
+ }
+
+ // using SIMD could cause a page fault, so iterate byte by byte
+ int res = innerCompare(n, false);
+ if (res != Incomplete)
+ return res;
+ }
+#endif
+
+ return innerCompare(-1, true);
+}
+
+/*! \relates QByteArray
+
+ A safe \c strnicmp() function.
+
+ Compares at most \a len bytes of \a str1 and \a str2 ignoring the
+ case of the characters. The encoding of the strings is assumed to
+ be Latin-1.
+
+ Returns a negative value if \a str1 is less than \a str2, 0 if \a str1
+ is equal to \a str2 or a positive value if \a str1 is greater than \a
+ str2.
+
+ Special case 1: Returns 0 if \a str1 and \a str2 are both \nullptr.
+
+ Special case 2: Returns a random non-zero value if \a str1 is \nullptr
+ or \a str2 is \nullptr (but not both).
+
+ \sa qstrcmp(), qstrncmp(), qstricmp(), {8-bit Character Comparisons},
+ QByteArray::compare()
+*/
+
+int qstrnicmp(const char *str1, const char *str2, uint len)
+{
+ const uchar *s1 = reinterpret_cast<const uchar *>(str1);
+ const uchar *s2 = reinterpret_cast<const uchar *>(str2);
+ int res;
+ uchar c;
+ if (!s1 || !s2)
+ return s1 ? 1 : (s2 ? -1 : 0);
+ for (; len--; s1++, s2++) {
+ if ((res = (c = latin1_lowercased[*s1]) - latin1_lowercased[*s2]))
+ return res;
+ if (!c) // strings are equal
+ break;
+ }
+ return 0;
+}
+
+/*!
+ \internal
+ \since 5.12
+
+ A helper for QByteArray::compare. Compares \a len1 bytes from \a str1 to \a
+ len2 bytes from \a str2. If \a len2 is -1, then \a str2 is expected to be
+ '\\0'-terminated.
+ */
+int qstrnicmp(const char *str1, qsizetype len1, const char *str2, qsizetype len2)
+{
+ Q_ASSERT(str1);
+ Q_ASSERT(len1 >= 0);
+ Q_ASSERT(len2 >= -1);
+ const uchar *s1 = reinterpret_cast<const uchar *>(str1);
+ const uchar *s2 = reinterpret_cast<const uchar *>(str2);
+ if (!s2)
+ return len1 == 0 ? 0 : 1;
+
+ int res;
+ uchar c;
+ if (len2 == -1) {
+ // null-terminated str2
+ qsizetype i;
+ for (i = 0; i < len1; ++i) {
+ c = latin1_lowercased[s2[i]];
+ if (!c)
+ return 1;
+
+ res = latin1_lowercased[s1[i]] - c;
+ if (res)
+ return res;
+ }
+ c = latin1_lowercased[s2[i]];
+ return c ? -1 : 0;
+ } else {
+ // not null-terminated
+ for (qsizetype i = 0; i < qMin(len1, len2); ++i) {
+ c = latin1_lowercased[s2[i]];
+ res = latin1_lowercased[s1[i]] - c;
+ if (res)
+ return res;
+ }
+ if (len1 == len2)
+ return 0;
+ return len1 < len2 ? -1 : 1;
+ }
+}
+
+/*!
+ \internal
+ ### Qt6: replace the QByteArray parameter with [pointer,len] pair
+ */
+int qstrcmp(const QByteArray &str1, const char *str2)
+{
+ if (!str2)
+ return str1.isEmpty() ? 0 : +1;
+
+ const char *str1data = str1.constData();
+ const char *str1end = str1data + str1.length();
+ for ( ; str1data < str1end && *str2; ++str1data, ++str2) {
+ int diff = int(uchar(*str1data)) - uchar(*str2);
+ if (diff)
+ // found a difference
+ return diff;
+ }
+
+ // Why did we stop?
+ if (*str2 != '\0')
+ // not the null, so we stopped because str1 is shorter
+ return -1;
+ if (str1data < str1end)
+ // we haven't reached the end, so str1 must be longer
+ return +1;
+ return 0;
+}
+
+/*!
+ \internal
+ ### Qt6: replace the QByteArray parameter with [pointer,len] pair
+ */
+int qstrcmp(const QByteArray &str1, const QByteArray &str2)
+{
+ int l1 = str1.length();
+ int l2 = str2.length();
+ int ret = memcmp(str1.constData(), str2.constData(), qMin(l1, l2));
+ if (ret != 0)
+ return ret;
+
+ // they matched qMin(l1, l2) bytes
+ // so the longer one is lexically after the shorter one
+ return l1 - l2;
+}
+
+// the CRC table below is created by the following piece of code
+#if 0
+static void createCRC16Table() // build CRC16 lookup table
+{
+ unsigned int i;
+ unsigned int j;
+ unsigned short crc_tbl[16];
+ unsigned int v0, v1, v2, v3;
+ for (i = 0; i < 16; i++) {
+ v0 = i & 1;
+ v1 = (i >> 1) & 1;
+ v2 = (i >> 2) & 1;
+ v3 = (i >> 3) & 1;
+ j = 0;
+#undef SET_BIT
+#define SET_BIT(x, b, v) (x) |= (v) << (b)
+ SET_BIT(j, 0, v0);
+ SET_BIT(j, 7, v0);
+ SET_BIT(j, 12, v0);
+ SET_BIT(j, 1, v1);
+ SET_BIT(j, 8, v1);
+ SET_BIT(j, 13, v1);
+ SET_BIT(j, 2, v2);
+ SET_BIT(j, 9, v2);
+ SET_BIT(j, 14, v2);
+ SET_BIT(j, 3, v3);
+ SET_BIT(j, 10, v3);
+ SET_BIT(j, 15, v3);
+ crc_tbl[i] = j;
+ }
+ printf("static const quint16 crc_tbl[16] = {\n");
+ for (int i = 0; i < 16; i +=4)
+ 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]);
+ printf("};\n");
+}
+#endif
+
+static const quint16 crc_tbl[16] = {
+ 0x0000, 0x1081, 0x2102, 0x3183,
+ 0x4204, 0x5285, 0x6306, 0x7387,
+ 0x8408, 0x9489, 0xa50a, 0xb58b,
+ 0xc60c, 0xd68d, 0xe70e, 0xf78f
+};
+
+/*!
+ \relates QByteArray
+
+ Returns the CRC-16 checksum of the first \a len bytes of \a data.
+
+ The checksum is independent of the byte order (endianness) and will be
+ calculated accorded to the algorithm published in ISO 3309 (Qt::ChecksumIso3309).
+
+ \note This function is a 16-bit cache conserving (16 entry table)
+ implementation of the CRC-16-CCITT algorithm.
+*/
+quint16 qChecksum(const char *data, uint len)
+{
+ return qChecksum(data, len, Qt::ChecksumIso3309);
+}
+
+/*!
+ \relates QByteArray
+ \since 5.9
+
+ Returns the CRC-16 checksum of the first \a len bytes of \a data.
+
+ The checksum is independent of the byte order (endianness) and will
+ be calculated accorded to the algorithm published in \a standard.
+
+ \note This function is a 16-bit cache conserving (16 entry table)
+ implementation of the CRC-16-CCITT algorithm.
+*/
+quint16 qChecksum(const char *data, uint len, Qt::ChecksumType standard)
+{
+ quint16 crc = 0x0000;
+ switch (standard) {
+ case Qt::ChecksumIso3309:
+ crc = 0xffff;
+ break;
+ case Qt::ChecksumItuV41:
+ crc = 0x6363;
+ break;
+ }
+ uchar c;
+ const uchar *p = reinterpret_cast<const uchar *>(data);
+ while (len--) {
+ c = *p++;
+ crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
+ c >>= 4;
+ crc = ((crc >> 4) & 0x0fff) ^ crc_tbl[((crc ^ c) & 15)];
+ }
+ switch (standard) {
+ case Qt::ChecksumIso3309:
+ crc = ~crc;
+ break;
+ case Qt::ChecksumItuV41:
+ break;
+ }
+ return crc & 0xffff;
+}
+
+/*!
+ \fn QByteArray qCompress(const QByteArray& data, int compressionLevel)
+
+ \relates QByteArray
+
+ Compresses the \a data byte array and returns the compressed data
+ in a new byte array.
+
+ The \a compressionLevel parameter specifies how much compression
+ should be used. Valid values are between 0 and 9, with 9
+ corresponding to the greatest compression (i.e. smaller compressed
+ data) at the cost of using a slower algorithm. Smaller values (8,
+ 7, ..., 1) provide successively less compression at slightly
+ faster speeds. The value 0 corresponds to no compression at all.
+ The default value is -1, which specifies zlib's default
+ compression.
+
+ \sa qUncompress()
+*/
+
+/*! \relates QByteArray
+
+ \overload
+
+ Compresses the first \a nbytes of \a data at compression level
+ \a compressionLevel and returns the compressed data in a new byte array.
+*/
+
+#ifndef QT_NO_COMPRESS
+QByteArray qCompress(const uchar* data, int nbytes, int compressionLevel)
+{
+ if (nbytes == 0) {
+ return QByteArray(4, '\0');
+ }
+ if (!data) {
+ qWarning("qCompress: Data is null");
+ return QByteArray();
+ }
+ if (compressionLevel < -1 || compressionLevel > 9)
+ compressionLevel = -1;
+
+ ulong len = nbytes + nbytes / 100 + 13;
+ QByteArray bazip;
+ int res;
+ do {
+ bazip.resize(len + 4);
+ res = ::compress2((uchar*)bazip.data()+4, &len, data, nbytes, compressionLevel);
+
+ switch (res) {
+ case Z_OK:
+ bazip.resize(len + 4);
+ bazip[0] = (nbytes & 0xff000000) >> 24;
+ bazip[1] = (nbytes & 0x00ff0000) >> 16;
+ bazip[2] = (nbytes & 0x0000ff00) >> 8;
+ bazip[3] = (nbytes & 0x000000ff);
+ break;
+ case Z_MEM_ERROR:
+ qWarning("qCompress: Z_MEM_ERROR: Not enough memory");
+ bazip.resize(0);
+ break;
+ case Z_BUF_ERROR:
+ len *= 2;
+ break;
+ }
+ } while (res == Z_BUF_ERROR);
+
+ return bazip;
+}
+#endif
+
+/*!
+ \fn QByteArray qUncompress(const QByteArray &data)
+
+ \relates QByteArray
+
+ Uncompresses the \a data byte array and returns a new byte array
+ with the uncompressed data.
+
+ Returns an empty QByteArray if the input data was corrupt.
+
+ This function will uncompress data compressed with qCompress()
+ from this and any earlier Qt version, back to Qt 3.1 when this
+ feature was added.
+
+ \b{Note:} If you want to use this function to uncompress external
+ data that was compressed using zlib, you first need to prepend a four
+ byte header to the byte array containing the data. The header must
+ contain the expected length (in bytes) of the uncompressed data,
+ expressed as an unsigned, big-endian, 32-bit integer.
+
+ \sa qCompress()
+*/
+
+#ifndef QT_NO_COMPRESS
+namespace {
+struct QByteArrayDataDeleter
+{
+ static inline void cleanup(QTypedArrayData<char> *d)
+ { if (d) QTypedArrayData<char>::deallocate(d); }
+};
+}
+
+static QByteArray invalidCompressedData()
+{
+ qWarning("qUncompress: Input data is corrupted");
+ return QByteArray();
+}
+
+/*! \relates QByteArray
+
+ \overload
+
+ Uncompresses the first \a nbytes of \a data and returns a new byte
+ array with the uncompressed data.
+*/
+QByteArray qUncompress(const uchar* data, int nbytes)
+{
+ if (!data) {
+ qWarning("qUncompress: Data is null");
+ return QByteArray();
+ }
+ if (nbytes <= 4) {
+ if (nbytes < 4 || (data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0))
+ qWarning("qUncompress: Input data is corrupted");
+ return QByteArray();
+ }
+ ulong expectedSize = uint((data[0] << 24) | (data[1] << 16) |
+ (data[2] << 8) | (data[3] ));
+ ulong len = qMax(expectedSize, 1ul);
+ const ulong maxPossibleSize = MaxAllocSize - sizeof(QByteArray::Data);
+ if (Q_UNLIKELY(len >= maxPossibleSize)) {
+ // QByteArray does not support that huge size anyway.
+ return invalidCompressedData();
+ }
+
+ QScopedPointer<QByteArray::Data, QByteArrayDataDeleter> d(QByteArray::Data::allocate(expectedSize + 1));
+ if (Q_UNLIKELY(d.data() == nullptr))
+ return invalidCompressedData();
+
+ d->size = expectedSize;
+ forever {
+ ulong alloc = len;
+
+ int res = ::uncompress((uchar*)d->data(), &len,
+ data+4, nbytes-4);
+
+ switch (res) {
+ case Z_OK:
+ Q_ASSERT(len <= alloc);
+ Q_UNUSED(alloc);
+ d->size = len;
+ d->data()[len] = 0;
+ {
+ QByteArrayDataPtr dataPtr = { d.take() };
+ return QByteArray(dataPtr);
+ }
+
+ case Z_MEM_ERROR:
+ qWarning("qUncompress: Z_MEM_ERROR: Not enough memory");
+ return QByteArray();
+
+ case Z_BUF_ERROR:
+ len *= 2;
+ if (Q_UNLIKELY(len >= maxPossibleSize)) {
+ // QByteArray does not support that huge size anyway.
+ return invalidCompressedData();
+ } else {
+ // grow the block
+ QByteArray::Data *p = QByteArray::Data::reallocateUnaligned(d.data(), len + 1);
+ if (Q_UNLIKELY(p == nullptr))
+ return invalidCompressedData();
+ d.take(); // don't free
+ d.reset(p);
+ }
+ continue;
+
+ case Z_DATA_ERROR:
+ qWarning("qUncompress: Z_DATA_ERROR: Input data is corrupted");
+ return QByteArray();
+ }
+ }
+}
+#endif
+
+/*!
+ \class QByteArray
+ \inmodule QtCore
+ \brief The QByteArray class provides an array of bytes.
+
+ \ingroup tools
+ \ingroup shared
+ \ingroup string-processing
+
+ \reentrant
+
+ QByteArray can be used to store both raw bytes (including '\\0's)
+ and traditional 8-bit '\\0'-terminated strings. Using QByteArray
+ is much more convenient than using \c{const char *}. Behind the
+ scenes, it always ensures that the data is followed by a '\\0'
+ terminator, and uses \l{implicit sharing} (copy-on-write) to
+ reduce memory usage and avoid needless copying of data.
+
+ In addition to QByteArray, Qt also provides the QString class to
+ store string data. For most purposes, QString is the class you
+ want to use. It stores 16-bit Unicode characters, making it easy
+ to store non-ASCII/non-Latin-1 characters in your application.
+ Furthermore, QString is used throughout in the Qt API. The two
+ main cases where QByteArray is appropriate are when you need to
+ store raw binary data, and when memory conservation is critical
+ (e.g., with Qt for Embedded Linux).
+
+ One way to initialize a QByteArray is simply to pass a \c{const
+ char *} to its constructor. For example, the following code
+ creates a byte array of size 5 containing the data "Hello":
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 0
+
+ Although the size() is 5, the byte array also maintains an extra
+ '\\0' character at the end so that if a function is used that
+ asks for a pointer to the underlying data (e.g. a call to
+ data()), the data pointed to is guaranteed to be
+ '\\0'-terminated.
+
+ QByteArray makes a deep copy of the \c{const char *} data, so you
+ can modify it later without experiencing side effects. (If for
+ performance reasons you don't want to take a deep copy of the
+ character data, use QByteArray::fromRawData() instead.)
+
+ Another approach is to set the size of the array using resize()
+ and to initialize the data byte per byte. QByteArray uses 0-based
+ indexes, just like C++ arrays. To access the byte at a particular
+ index position, you can use operator[](). On non-const byte
+ arrays, operator[]() returns a reference to a byte that can be
+ used on the left side of an assignment. For example:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 1
+
+ For read-only access, an alternative syntax is to use at():
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 2
+
+ at() can be faster than operator[](), because it never causes a
+ \l{deep copy} to occur.
+
+ To extract many bytes at a time, use left(), right(), or mid().
+
+ A QByteArray can embed '\\0' bytes. The size() function always
+ returns the size of the whole array, including embedded '\\0'
+ bytes, but excluding the terminating '\\0' added by QByteArray.
+ For example:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 48
+
+ If you want to obtain the length of the data up to and
+ excluding the first '\\0' character, call qstrlen() on the byte
+ array.
+
+ After a call to resize(), newly allocated bytes have undefined
+ values. To set all the bytes to a particular value, call fill().
+
+ To obtain a pointer to the actual character data, call data() or
+ constData(). These functions return a pointer to the beginning of the data.
+ The pointer is guaranteed to remain valid until a non-const function is
+ called on the QByteArray. It is also guaranteed that the data ends with a
+ '\\0' byte unless the QByteArray was created from a \l{fromRawData()}{raw
+ data}. This '\\0' byte is automatically provided by QByteArray and is not
+ counted in size().
+
+ QByteArray provides the following basic functions for modifying
+ the byte data: append(), prepend(), insert(), replace(), and
+ remove(). For example:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 3
+
+ The replace() and remove() functions' first two arguments are the
+ position from which to start erasing and the number of bytes that
+ should be erased.
+
+ When you append() data to a non-empty array, the array will be
+ reallocated and the new data copied to it. You can avoid this
+ behavior by calling reserve(), which preallocates a certain amount
+ of memory. You can also call capacity() to find out how much
+ memory QByteArray actually allocated. Data appended to an empty
+ array is not copied.
+
+ A frequent requirement is to remove whitespace characters from a
+ byte array ('\\n', '\\t', ' ', etc.). If you want to remove
+ whitespace from both ends of a QByteArray, use trimmed(). If you
+ want to remove whitespace from both ends and replace multiple
+ consecutive whitespaces with a single space character within the
+ byte array, use simplified().
+
+ If you want to find all occurrences of a particular character or
+ substring in a QByteArray, use indexOf() or lastIndexOf(). The
+ former searches forward starting from a given index position, the
+ latter searches backward. Both return the index position of the
+ character or substring if they find it; otherwise, they return -1.
+ For example, here's a typical loop that finds all occurrences of a
+ particular substring:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 4
+
+ If you simply want to check whether a QByteArray contains a
+ particular character or substring, use contains(). If you want to
+ find out how many times a particular character or substring
+ occurs in the byte array, use count(). If you want to replace all
+ occurrences of a particular value with another, use one of the
+ two-parameter replace() overloads.
+
+ \l{QByteArray}s can be compared using overloaded operators such as
+ operator<(), operator<=(), operator==(), operator>=(), and so on.
+ The comparison is based exclusively on the numeric values
+ of the characters and is very fast, but is not what a human would
+ expect. QString::localeAwareCompare() is a better choice for
+ sorting user-interface strings.
+
+ For historical reasons, QByteArray distinguishes between a null
+ byte array and an empty byte array. A \e null byte array is a
+ byte array that is initialized using QByteArray's default
+ constructor or by passing (const char *)0 to the constructor. An
+ \e empty byte array is any byte array with size 0. A null byte
+ array is always empty, but an empty byte array isn't necessarily
+ null:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 5
+
+ All functions except isNull() treat null byte arrays the same as
+ empty byte arrays. For example, data() returns a valid pointer
+ (\e not nullptr) to a '\\0' character for a byte array
+ and QByteArray() compares equal to QByteArray(""). We recommend
+ that you always use isEmpty() and avoid isNull().
+
+ \section1 Maximum size and out-of-memory conditions
+
+ The current version of QByteArray is limited to just under 2 GB (2^31
+ bytes) in size. The exact value is architecture-dependent, since it depends
+ on the overhead required for managing the data block, but is no more than
+ 32 bytes. Raw data blocks are also limited by the use of \c int type in the
+ current version to 2 GB minus 1 byte.
+
+ In case memory allocation fails, QByteArray will throw a \c std::bad_alloc
+ exception. Out of memory conditions in the Qt containers are the only case
+ where Qt will throw exceptions.
+
+ Note that the operating system may impose further limits on applications
+ holding a lot of allocated memory, especially large, contiguous blocks.
+ Such considerations, the configuration of such behavior or any mitigation
+ are outside the scope of the QByteArray API.
+
+ \section1 Notes on Locale
+
+ \section2 Number-String Conversions
+
+ Functions that perform conversions between numeric data types and
+ strings are performed in the C locale, irrespective of the user's
+ locale settings. Use QString to perform locale-aware conversions
+ between numbers and strings.
+
+ \section2 8-bit Character Comparisons
+
+ In QByteArray, the notion of uppercase and lowercase and of which
+ character is greater than or less than another character is
+ locale dependent. This affects functions that support a case
+ insensitive option or that compare or lowercase or uppercase
+ their arguments. Case insensitive operations and comparisons will
+ be accurate if both strings contain only ASCII characters. (If \c
+ $LC_CTYPE is set, most Unix systems do "the right thing".)
+ Functions that this affects include contains(), indexOf(),
+ lastIndexOf(), operator<(), operator<=(), operator>(),
+ operator>=(), isLower(), isUpper(), toLower() and toUpper().
+
+ This issue does not apply to \l{QString}s since they represent
+ characters using Unicode.
+
+ \sa QString, QBitArray
+*/
+
+/*!
+ \enum QByteArray::Base64Option
+ \since 5.2
+
+ This enum contains the options available for encoding and decoding Base64.
+ Base64 is defined by \l{RFC 4648}, with the following options:
+
+ \value Base64Encoding (default) The regular Base64 alphabet, called simply "base64"
+ \value Base64UrlEncoding An alternate alphabet, called "base64url", which replaces two
+ characters in the alphabet to be more friendly to URLs.
+ \value KeepTrailingEquals (default) Keeps the trailing padding equal signs at the end
+ of the encoded data, so the data is always a size multiple of
+ four.
+ \value OmitTrailingEquals Omits adding the padding equal signs at the end of the encoded
+ data.
+
+ QByteArray::fromBase64() ignores the KeepTrailingEquals and
+ OmitTrailingEquals options and will not flag errors in case they are
+ missing or if there are too many of them.
+*/
+
+/*! \fn QByteArray::iterator QByteArray::begin()
+
+ Returns an \l{STL-style iterators}{STL-style iterator} pointing to the first character in
+ the byte-array.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::begin() const
+
+ \overload begin()
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::cbegin() const
+ \since 5.0
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first character
+ in the byte-array.
+
+ \sa begin(), cend()
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::constBegin() const
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first character
+ in the byte-array.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QByteArray::iterator QByteArray::end()
+
+ Returns an \l{STL-style iterators}{STL-style iterator} pointing to the imaginary character
+ after the last character in the byte-array.
+
+ \sa begin(), constEnd()
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::end() const
+
+ \overload end()
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::cend() const
+ \since 5.0
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
+ character after the last character in the list.
+
+ \sa cbegin(), end()
+*/
+
+/*! \fn QByteArray::const_iterator QByteArray::constEnd() const
+
+ Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary
+ character after the last character in the list.
+
+ \sa constBegin(), end()
+*/
+
+/*! \fn QByteArray::reverse_iterator QByteArray::rbegin()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ character in the byte-array, in reverse order.
+
+ \sa begin(), crbegin(), rend()
+*/
+
+/*! \fn QByteArray::const_reverse_iterator QByteArray::rbegin() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QByteArray::const_reverse_iterator QByteArray::crbegin() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to the first
+ character in the byte-array, in reverse order.
+
+ \sa begin(), rbegin(), rend()
+*/
+
+/*! \fn QByteArray::reverse_iterator QByteArray::rend()
+ \since 5.6
+
+ Returns a \l{STL-style iterators}{STL-style} reverse iterator pointing to one past
+ the last character in the byte-array, in reverse order.
+
+ \sa end(), crend(), rbegin()
+*/
+
+/*! \fn QByteArray::const_reverse_iterator QByteArray::rend() const
+ \since 5.6
+ \overload
+*/
+
+/*! \fn QByteArray::const_reverse_iterator QByteArray::crend() const
+ \since 5.6
+
+ Returns a const \l{STL-style iterators}{STL-style} reverse iterator pointing to one
+ past the last character in the byte-array, in reverse order.
+
+ \sa end(), rend(), rbegin()
+*/
+
+/*! \fn void QByteArray::push_back(const QByteArray &other)
+
+ This function is provided for STL compatibility. It is equivalent
+ to append(\a other).
+*/
+
+/*! \fn void QByteArray::push_back(const char *str)
+
+ \overload
+
+ Same as append(\a str).
+*/
+
+/*! \fn void QByteArray::push_back(char ch)
+
+ \overload
+
+ Same as append(\a ch).
+*/
+
+/*! \fn void QByteArray::push_front(const QByteArray &other)
+
+ This function is provided for STL compatibility. It is equivalent
+ to prepend(\a other).
+*/
+
+/*! \fn void QByteArray::push_front(const char *str)
+
+ \overload
+
+ Same as prepend(\a str).
+*/
+
+/*! \fn void QByteArray::push_front(char ch)
+
+ \overload
+
+ Same as prepend(\a ch).
+*/
+
+/*! \fn void QByteArray::shrink_to_fit()
+ \since 5.10
+
+ This function is provided for STL compatibility. It is equivalent to
+ squeeze().
+*/
+
+/*! \fn QByteArray::QByteArray(const QByteArray &other)
+
+ Constructs a copy of \a other.
+
+ This operation takes \l{constant time}, because QByteArray is
+ \l{implicitly shared}. This makes returning a QByteArray from a
+ function very fast. If a shared instance is modified, it will be
+ copied (copy-on-write), taking \l{linear time}.
+
+ \sa operator=()
+*/
+
+/*!
+ \fn QByteArray::QByteArray(QByteArray &&other)
+
+ Move-constructs a QByteArray instance, making it point at the same
+ object that \a other was pointing to.
+
+ \since 5.2
+*/
+
+/*! \fn QByteArray::QByteArray(QByteArrayDataPtr dd)
+
+ \internal
+
+ Constructs a byte array pointing to the same data as \a dd.
+*/
+
+/*! \fn QByteArray::~QByteArray()
+ Destroys the byte array.
+*/
+
+/*!
+ Assigns \a other to this byte array and returns a reference to
+ this byte array.
+*/
+QByteArray &QByteArray::operator=(const QByteArray & other) noexcept
+{
+ other.d->ref.ref();
+ if (!d->ref.deref())
+ Data::deallocate(d);
+ d = other.d;
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Assigns \a str to this byte array.
+*/
+
+QByteArray &QByteArray::operator=(const char *str)
+{
+ Data *x;
+ if (!str) {
+ x = Data::sharedNull();
+ } else if (!*str) {
+ x = Data::allocate(0);
+ } else {
+ const int len = int(strlen(str));
+ const uint fullLen = len + 1;
+ if (d->ref.isShared() || fullLen > d->alloc
+ || (len < d->size && fullLen < uint(d->alloc >> 1)))
+ reallocData(fullLen, d->detachFlags());
+ x = d;
+ memcpy(x->data(), str, fullLen); // include null terminator
+ x->size = len;
+ }
+ x->ref.ref();
+ if (!d->ref.deref())
+ Data::deallocate(d);
+ d = x;
+ return *this;
+}
+
+/*!
+ \fn QByteArray &QByteArray::operator=(QByteArray &&other)
+
+ Move-assigns \a other to this QByteArray instance.
+
+ \since 5.2
+*/
+
+/*! \fn void QByteArray::swap(QByteArray &other)
+ \since 4.8
+
+ Swaps byte array \a other with this byte array. This operation is very
+ fast and never fails.
+*/
+
+/*! \fn int QByteArray::size() const
+
+ Returns the number of bytes in this byte array.
+
+ The last byte in the byte array is at position size() - 1. In addition,
+ QByteArray ensures that the byte at position size() is always '\\0', so
+ that you can use the return value of data() and constData() as arguments to
+ functions that expect '\\0'-terminated strings. If the QByteArray object
+ was created from a \l{fromRawData()}{raw data} that didn't include the
+ trailing null-termination character then QByteArray doesn't add it
+ automaticall unless the \l{deep copy} is created.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 6
+
+ \sa isEmpty(), resize()
+*/
+
+/*! \fn bool QByteArray::isEmpty() const
+
+ Returns \c true if the byte array has size 0; otherwise returns \c false.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 7
+
+ \sa size()
+*/
+
+/*! \fn int QByteArray::capacity() const
+
+ Returns the maximum number of bytes that can be stored in the
+ byte array without forcing a reallocation.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QByteArray's memory usage. In general, you will rarely
+ ever need to call this function. If you want to know how many
+ bytes are in the byte array, call size().
+
+ \sa reserve(), squeeze()
+*/
+
+/*! \fn void QByteArray::reserve(int size)
+
+ Attempts to allocate memory for at least \a size bytes. If you
+ know in advance how large the byte array will be, you can call
+ this function, and if you call resize() often you are likely to
+ get better performance. If \a size is an underestimate, the worst
+ that will happen is that the QByteArray will be a bit slower.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QByteArray's memory usage. In general, you will rarely
+ ever need to call this function. If you want to change the size
+ of the byte array, call resize().
+
+ \sa squeeze(), capacity()
+*/
+
+/*! \fn void QByteArray::squeeze()
+
+ Releases any memory not required to store the array's data.
+
+ The sole purpose of this function is to provide a means of fine
+ tuning QByteArray's memory usage. In general, you will rarely
+ ever need to call this function.
+
+ \sa reserve(), capacity()
+*/
+
+/*! \fn QByteArray::operator const char *() const
+ \fn QByteArray::operator const void *() const
+
+ \obsolete Use constData() instead.
+
+ Returns a pointer to the data stored in the byte array. The
+ pointer can be used to access the bytes that compose the array.
+ The data is '\\0'-terminated. The pointer remains valid as long
+ as the array isn't reallocated or destroyed.
+
+ This operator is mostly useful to pass a byte array to a function
+ that accepts a \c{const char *}.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_BYTEARRAY when you compile your applications.
+
+ Note: A QByteArray can store any byte values including '\\0's,
+ but most functions that take \c{char *} arguments assume that the
+ data ends at the first '\\0' they encounter.
+
+ \sa constData()
+*/
+
+/*!
+ \macro QT_NO_CAST_FROM_BYTEARRAY
+ \relates QByteArray
+
+ Disables automatic conversions from QByteArray to
+ const char * or const void *.
+
+ \sa QT_NO_CAST_TO_ASCII, QT_NO_CAST_FROM_ASCII
+*/
+
+/*! \fn char *QByteArray::data()
+
+ Returns a pointer to the data stored in the byte array. The
+ pointer can be used to access and modify the bytes that compose
+ the array. The data is '\\0'-terminated, i.e. the number of
+ bytes in the returned character string is size() + 1 for the
+ '\\0' terminator.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 8
+
+ The pointer remains valid as long as the byte array isn't
+ reallocated or destroyed. For read-only access, constData() is
+ faster because it never causes a \l{deep copy} to occur.
+
+ This function is mostly useful to pass a byte array to a function
+ that accepts a \c{const char *}.
+
+ The following example makes a copy of the char* returned by
+ data(), but it will corrupt the heap and cause a crash because it
+ does not allocate a byte for the '\\0' at the end:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 46
+
+ This one allocates the correct amount of space:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 47
+
+ Note: A QByteArray can store any byte values including '\\0's,
+ but most functions that take \c{char *} arguments assume that the
+ data ends at the first '\\0' they encounter.
+
+ \sa constData(), operator[]()
+*/
+
+/*! \fn const char *QByteArray::data() const
+
+ \overload
+*/
+
+/*! \fn const char *QByteArray::constData() const
+
+ Returns a pointer to the data stored in the byte array. The pointer can be
+ used to access the bytes that compose the array. The data is
+ '\\0'-terminated unless the QByteArray object was created from raw data.
+ The pointer remains valid as long as the byte array isn't reallocated or
+ destroyed.
+
+ This function is mostly useful to pass a byte array to a function
+ that accepts a \c{const char *}.
+
+ Note: A QByteArray can store any byte values including '\\0's,
+ but most functions that take \c{char *} arguments assume that the
+ data ends at the first '\\0' they encounter.
+
+ \sa data(), operator[](), fromRawData()
+*/
+
+/*! \fn void QByteArray::detach()
+
+ \internal
+*/
+
+/*! \fn bool QByteArray::isDetached() const
+
+ \internal
+*/
+
+/*! \fn bool QByteArray::isSharedWith(const QByteArray &other) const
+
+ \internal
+*/
+
+/*! \fn char QByteArray::at(int i) const
+
+ Returns the character at index position \a i in the byte array.
+
+ \a i must be a valid index position in the byte array (i.e., 0 <=
+ \a i < size()).
+
+ \sa operator[]()
+*/
+
+/*! \fn QByteRef QByteArray::operator[](int i)
+
+ Returns the byte at index position \a i as a modifiable reference.
+
+ If an assignment is made beyond the end of the byte array, the
+ array is extended with resize() before the assignment takes
+ place.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 9
+
+ The return value is of type QByteRef, a helper class for
+ QByteArray. When you get an object of type QByteRef, you can use
+ it as if it were a char &. If you assign to it, the assignment
+ will apply to the character in the QByteArray from which you got
+ the reference.
+
+ \note Before Qt 5.14 it was possible to use this operator to access
+ a character at an out-of-bounds position in the byte array, and
+ then assign to such a position, causing the byte array to be
+ automatically resized. Furthermore, assigning a value to the
+ returned QByteRef would cause a detach of the byte array, even if the
+ byte array has been copied in the meanwhile (and the QByteRef kept
+ alive while the copy was taken). These behaviors are deprecated,
+ and will be changed in a future version of Qt.
+
+ \sa at()
+*/
+
+/*! \fn char QByteArray::operator[](int i) const
+
+ \overload
+
+ Same as at(\a i).
+*/
+
+/*! \fn QByteRef QByteArray::operator[](uint i)
+
+ \overload
+*/
+
+/*! \fn char QByteArray::operator[](uint i) const
+
+ \overload
+*/
+
+/*!
+ \fn char QByteArray::front() const
+ \since 5.10
+
+ Returns the first character in the byte array.
+ Same as \c{at(0)}.
+
+ This function is provided for STL compatibility.
+
+ \warning Calling this function on an empty byte array constitutes
+ undefined behavior.
+
+ \sa back(), at(), operator[]()
+*/
+
+/*!
+ \fn char QByteArray::back() const
+ \since 5.10
+
+ Returns the last character in the byte array.
+ Same as \c{at(size() - 1)}.
+
+ This function is provided for STL compatibility.
+
+ \warning Calling this function on an empty byte array constitutes
+ undefined behavior.
+
+ \sa front(), at(), operator[]()
+*/
+
+/*!
+ \fn QByteRef QByteArray::front()
+ \since 5.10
+
+ Returns a reference to the first character in the byte array.
+ Same as \c{operator[](0)}.
+
+ This function is provided for STL compatibility.
+
+ \warning Calling this function on an empty byte array constitutes
+ undefined behavior.
+
+ \sa back(), at(), operator[]()
+*/
+
+/*!
+ \fn QByteRef QByteArray::back()
+ \since 5.10
+
+ Returns a reference to the last character in the byte array.
+ Same as \c{operator[](size() - 1)}.
+
+ This function is provided for STL compatibility.
+
+ \warning Calling this function on an empty byte array constitutes
+ undefined behavior.
+
+ \sa front(), at(), operator[]()
+*/
+
+/*! \fn bool QByteArray::contains(const QByteArray &ba) const
+
+ Returns \c true if the byte array contains an occurrence of the byte
+ array \a ba; otherwise returns \c false.
+
+ \sa indexOf(), count()
+*/
+
+/*! \fn bool QByteArray::contains(const char *str) const
+
+ \overload
+
+ Returns \c true if the byte array contains the string \a str;
+ otherwise returns \c false.
+*/
+
+/*! \fn bool QByteArray::contains(char ch) const
+
+ \overload
+
+ Returns \c true if the byte array contains the character \a ch;
+ otherwise returns \c false.
+*/
+
+/*!
+
+ Truncates the byte array at index position \a pos.
+
+ If \a pos is beyond the end of the array, nothing happens.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 10
+
+ \sa chop(), resize(), left()
+*/
+void QByteArray::truncate(int pos)
+{
+ if (pos < d->size)
+ resize(pos);
+}
+
+/*!
+
+ Removes \a n bytes from the end of the byte array.
+
+ If \a n is greater than size(), the result is an empty byte
+ array.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 11
+
+ \sa truncate(), resize(), left()
+*/
+
+void QByteArray::chop(int n)
+{
+ if (n > 0)
+ resize(d->size - n);
+}
+
+
+/*! \fn QByteArray &QByteArray::operator+=(const QByteArray &ba)
+
+ Appends the byte array \a ba onto the end of this byte array and
+ returns a reference to this byte array.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 12
+
+ Note: QByteArray is an \l{implicitly shared} class. Consequently,
+ if you append to an empty byte array, then the byte array will just
+ share the data held in \a ba. In this case, no copying of data is done,
+ taking \l{constant time}. If a shared instance is modified, it will
+ be copied (copy-on-write), taking \l{linear time}.
+
+ If the byte array being appended to is not empty, a deep copy of the
+ data is performed, taking \l{linear time}.
+
+ This operation typically does not suffer from allocation overhead,
+ because QByteArray preallocates extra space at the end of the data
+ so that it may grow without reallocating for each append operation.
+
+ \sa append(), prepend()
+*/
+
+/*! \fn QByteArray &QByteArray::operator+=(const QString &str)
+
+ \overload
+
+ Appends the string \a str onto the end of this byte array and
+ returns a reference to this byte array. The Unicode data is
+ converted into 8-bit characters using QString::toUtf8().
+
+ You can disable this function by defining \c QT_NO_CAST_TO_ASCII when you
+ compile your applications. You then need to call QString::toUtf8() (or
+ QString::toLatin1() or QString::toLocal8Bit()) explicitly if you want to
+ convert the data to \c{const char *}.
+*/
+
+/*! \fn QByteArray &QByteArray::operator+=(const char *str)
+
+ \overload
+
+ Appends the string \a str onto the end of this byte array and
+ returns a reference to this byte array.
+*/
+
+/*! \fn QByteArray &QByteArray::operator+=(char ch)
+
+ \overload
+
+ Appends the character \a ch onto the end of this byte array and
+ returns a reference to this byte array.
+*/
+
+/*! \fn int QByteArray::length() const
+
+ Same as size().
+*/
+
+/*! \fn bool QByteArray::isNull() const
+
+ Returns \c true if this byte array is null; otherwise returns \c false.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 13
+
+ Qt makes a distinction between null byte arrays and empty byte
+ arrays for historical reasons. For most applications, what
+ matters is whether or not a byte array contains any data,
+ and this can be determined using isEmpty().
+
+ \sa isEmpty()
+*/
+
+/*! \fn QByteArray::QByteArray()
+
+ Constructs an empty byte array.
+
+ \sa isEmpty()
+*/
+
+/*!
+ Constructs a byte array containing the first \a size bytes of
+ array \a data.
+
+ If \a data is 0, a null byte array is constructed.
+
+ If \a size is negative, \a data is assumed to point to a
+ '\\0'-terminated string and its length is determined dynamically.
+ The terminating \\0 character is not considered part of the
+ byte array.
+
+ QByteArray makes a deep copy of the string data.
+
+ \sa fromRawData()
+*/
+
+QByteArray::QByteArray(const char *data, int size)
+{
+ if (!data) {
+ d = Data::sharedNull();
+ } else {
+ if (size < 0)
+ size = int(strlen(data));
+ if (!size) {
+ d = Data::allocate(0);
+ } else {
+ d = Data::allocate(uint(size) + 1u);
+ Q_CHECK_PTR(d);
+ d->size = size;
+ memcpy(d->data(), data, size);
+ d->data()[size] = '\0';
+ }
+ }
+}
+
+/*!
+ Constructs a byte array of size \a size with every byte set to
+ character \a ch.
+
+ \sa fill()
+*/
+
+QByteArray::QByteArray(int size, char ch)
+{
+ if (size <= 0) {
+ d = Data::allocate(0);
+ } else {
+ d = Data::allocate(uint(size) + 1u);
+ Q_CHECK_PTR(d);
+ d->size = size;
+ memset(d->data(), ch, size);
+ d->data()[size] = '\0';
+ }
+}
+
+/*!
+ \internal
+
+ Constructs a byte array of size \a size with uninitialized contents.
+*/
+
+QByteArray::QByteArray(int size, Qt::Initialization)
+{
+ d = Data::allocate(uint(size) + 1u);
+ Q_CHECK_PTR(d);
+ d->size = size;
+ d->data()[size] = '\0';
+}
+
+/*!
+ Sets the size of the byte array to \a size bytes.
+
+ If \a size is greater than the current size, the byte array is
+ extended to make it \a size bytes with the extra bytes added to
+ the end. The new bytes are uninitialized.
+
+ If \a size is less than the current size, bytes are removed from
+ the end.
+
+ \sa size(), truncate()
+*/
+void QByteArray::resize(int size)
+{
+ if (size < 0)
+ size = 0;
+
+ if (IS_RAW_DATA(d) && !d->ref.isShared() && size < d->size) {
+ d->size = size;
+ return;
+ }
+
+ if (size == 0 && !d->capacityReserved) {
+ Data *x = Data::allocate(0);
+ if (!d->ref.deref())
+ Data::deallocate(d);
+ d = x;
+ } else if (d->size == 0 && d->ref.isStatic()) {
+ //
+ // Optimize the idiom:
+ // QByteArray a;
+ // a.resize(sz);
+ // ...
+ // which is used in place of the Qt 3 idiom:
+ // QByteArray a(sz);
+ //
+ Data *x = Data::allocate(uint(size) + 1u);
+ Q_CHECK_PTR(x);
+ x->size = size;
+ x->data()[size] = '\0';
+ d = x;
+ } else {
+ if (d->ref.isShared() || uint(size) + 1u > d->alloc
+ || (!d->capacityReserved && size < d->size
+ && uint(size) + 1u < uint(d->alloc >> 1)))
+ reallocData(uint(size) + 1u, d->detachFlags() | Data::Grow);
+ if (d->alloc) {
+ d->size = size;
+ d->data()[size] = '\0';
+ }
+ }
+}
+
+/*!
+ Sets every byte in the byte array to character \a ch. If \a size
+ is different from -1 (the default), the byte array is resized to
+ size \a size beforehand.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 14
+
+ \sa resize()
+*/
+
+QByteArray &QByteArray::fill(char ch, int size)
+{
+ resize(size < 0 ? d->size : size);
+ if (d->size)
+ memset(d->data(), ch, d->size);
+ return *this;
+}
+
+void QByteArray::reallocData(uint alloc, Data::AllocationOptions options)
+{
+ if (d->ref.isShared() || IS_RAW_DATA(d)) {
+ Data *x = Data::allocate(alloc, options);
+ Q_CHECK_PTR(x);
+ x->size = qMin(int(alloc) - 1, d->size);
+ ::memcpy(x->data(), d->data(), x->size);
+ x->data()[x->size] = '\0';
+ if (!d->ref.deref())
+ Data::deallocate(d);
+ d = x;
+ } else {
+ Data *x = Data::reallocateUnaligned(d, alloc, options);
+ Q_CHECK_PTR(x);
+ d = x;
+ }
+}
+
+void QByteArray::expand(int i)
+{
+ resize(qMax(i + 1, d->size));
+}
+
+/*!
+ \internal
+ Return a QByteArray that is sure to be '\\0'-terminated.
+
+ By default, all QByteArray have an extra NUL at the end,
+ guaranteeing that assumption. However, if QByteArray::fromRawData
+ is used, then the NUL is there only if the user put it there. We
+ can't be sure.
+*/
+QByteArray QByteArray::nulTerminated() const
+{
+ // is this fromRawData?
+ if (!IS_RAW_DATA(d))
+ return *this; // no, then we're sure we're zero terminated
+
+ QByteArray copy(*this);
+ copy.detach();
+ return copy;
+}
+
+/*!
+ Prepends the byte array \a ba to this byte array and returns a
+ reference to this byte array.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 15
+
+ This is the same as insert(0, \a ba).
+
+ Note: QByteArray is an \l{implicitly shared} class. Consequently,
+ if you prepend to an empty byte array, then the byte array will just
+ share the data held in \a ba. In this case, no copying of data is done,
+ taking \l{constant time}. If a shared instance is modified, it will
+ be copied (copy-on-write), taking \l{linear time}.
+
+ If the byte array being prepended to is not empty, a deep copy of the
+ data is performed, taking \l{linear time}.
+
+ \sa append(), insert()
+*/
+
+QByteArray &QByteArray::prepend(const QByteArray &ba)
+{
+ if (d->size == 0 && d->ref.isStatic() && !IS_RAW_DATA(ba.d)) {
+ *this = ba;
+ } else if (ba.d->size != 0) {
+ QByteArray tmp = *this;
+ *this = ba;
+ append(tmp);
+ }
+ return *this;
+}
+
+/*!
+ \overload
+
+ Prepends the string \a str to this byte array.
+*/
+
+QByteArray &QByteArray::prepend(const char *str)
+{
+ return prepend(str, qstrlen(str));
+}
+
+/*!
+ \overload
+ \since 4.6
+
+ Prepends \a len bytes of the string \a str to this byte array.
+*/
+
+QByteArray &QByteArray::prepend(const char *str, int len)
+{
+ if (str) {
+ if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc)
+ reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::Grow);
+ memmove(d->data()+len, d->data(), d->size);
+ memcpy(d->data(), str, len);
+ d->size += len;
+ d->data()[d->size] = '\0';
+ }
+ return *this;
+}
+
+/*! \fn QByteArray &QByteArray::prepend(int count, char ch)
+
+ \overload
+ \since 5.7
+
+ Prepends \a count copies of character \a ch to this byte array.
+*/
+
+/*!
+ \overload
+
+ Prepends the character \a ch to this byte array.
+*/
+
+QByteArray &QByteArray::prepend(char ch)
+{
+ if (d->ref.isShared() || uint(d->size) + 2u > d->alloc)
+ reallocData(uint(d->size) + 2u, d->detachFlags() | Data::Grow);
+ memmove(d->data()+1, d->data(), d->size);
+ d->data()[0] = ch;
+ ++d->size;
+ d->data()[d->size] = '\0';
+ return *this;
+}
+
+/*!
+ Appends the byte array \a ba onto the end of this byte array.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 16
+
+ This is the same as insert(size(), \a ba).
+
+ Note: QByteArray is an \l{implicitly shared} class. Consequently,
+ if you append to an empty byte array, then the byte array will just
+ share the data held in \a ba. In this case, no copying of data is done,
+ taking \l{constant time}. If a shared instance is modified, it will
+ be copied (copy-on-write), taking \l{linear time}.
+
+ If the byte array being appended to is not empty, a deep copy of the
+ data is performed, taking \l{linear time}.
+
+ This operation typically does not suffer from allocation overhead,
+ because QByteArray preallocates extra space at the end of the data
+ so that it may grow without reallocating for each append operation.
+
+ \sa operator+=(), prepend(), insert()
+*/
+
+QByteArray &QByteArray::append(const QByteArray &ba)
+{
+ if (d->size == 0 && d->ref.isStatic() && !IS_RAW_DATA(ba.d)) {
+ *this = ba;
+ } else if (ba.d->size != 0) {
+ if (d->ref.isShared() || uint(d->size + ba.d->size) + 1u > d->alloc)
+ reallocData(uint(d->size + ba.d->size) + 1u, d->detachFlags() | Data::Grow);
+ memcpy(d->data() + d->size, ba.d->data(), ba.d->size);
+ d->size += ba.d->size;
+ d->data()[d->size] = '\0';
+ }
+ return *this;
+}
+
+/*! \fn QByteArray &QByteArray::append(const QString &str)
+
+ \overload
+
+ Appends the string \a str to this byte array. The Unicode data is
+ converted into 8-bit characters using QString::toUtf8().
+
+ You can disable this function by defining \c QT_NO_CAST_TO_ASCII when you
+ compile your applications. You then need to call QString::toUtf8() (or
+ QString::toLatin1() or QString::toLocal8Bit()) explicitly if you want to
+ convert the data to \c{const char *}.
+*/
+
+/*!
+ \overload
+
+ Appends the string \a str to this byte array.
+*/
+
+QByteArray& QByteArray::append(const char *str)
+{
+ if (str) {
+ const int len = int(strlen(str));
+ if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc)
+ reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::Grow);
+ memcpy(d->data() + d->size, str, len + 1); // include null terminator
+ d->size += len;
+ }
+ return *this;
+}
+
+/*!
+ \overload append()
+
+ Appends the first \a len characters of the string \a str to this byte
+ array and returns a reference to this byte array.
+
+ If \a len is negative, the length of the string will be determined
+ automatically using qstrlen(). If \a len is zero or \a str is
+ null, nothing is appended to the byte array. Ensure that \a len is
+ \e not longer than \a str.
+*/
+
+QByteArray &QByteArray::append(const char *str, int len)
+{
+ if (len < 0)
+ len = qstrlen(str);
+ if (str && len) {
+ if (d->ref.isShared() || uint(d->size + len) + 1u > d->alloc)
+ reallocData(uint(d->size + len) + 1u, d->detachFlags() | Data::Grow);
+ memcpy(d->data() + d->size, str, len); // include null terminator
+ d->size += len;
+ d->data()[d->size] = '\0';
+ }
+ return *this;
+}
+
+/*! \fn QByteArray &QByteArray::append(int count, char ch)
+
+ \overload
+ \since 5.7
+
+ Appends \a count copies of character \a ch to this byte
+ array and returns a reference to this byte array.
+
+ If \a count is negative or zero nothing is appended to the byte array.
+*/
+
+/*!
+ \overload
+
+ Appends the character \a ch to this byte array.
+*/
+
+QByteArray& QByteArray::append(char ch)
+{
+ if (d->ref.isShared() || uint(d->size) + 2u > d->alloc)
+ reallocData(uint(d->size) + 2u, d->detachFlags() | Data::Grow);
+ d->data()[d->size++] = ch;
+ d->data()[d->size] = '\0';
+ return *this;
+}
+
+/*!
+ \internal
+ Inserts \a len bytes from the array \a arr at position \a pos and returns a
+ reference the modified byte array.
+*/
+static inline QByteArray &qbytearray_insert(QByteArray *ba,
+ int pos, const char *arr, int len)
+{
+ Q_ASSERT(pos >= 0);
+
+ if (pos < 0 || len <= 0 || arr == nullptr)
+ return *ba;
+
+ int oldsize = ba->size();
+ ba->resize(qMax(pos, oldsize) + len);
+ char *dst = ba->data();
+ if (pos > oldsize)
+ ::memset(dst + oldsize, 0x20, pos - oldsize);
+ else
+ ::memmove(dst + pos + len, dst + pos, oldsize - pos);
+ memcpy(dst + pos, arr, len);
+ return *ba;
+}
+
+/*!
+ Inserts the byte array \a ba at index position \a i and returns a
+ reference to this byte array.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 17
+
+ \sa append(), prepend(), replace(), remove()
+*/
+
+QByteArray &QByteArray::insert(int i, const QByteArray &ba)
+{
+ QByteArray copy(ba);
+ return qbytearray_insert(this, i, copy.d->data(), copy.d->size);
+}
+
+/*!
+ \fn QByteArray &QByteArray::insert(int i, const QString &str)
+
+ \overload
+
+ Inserts the string \a str at index position \a i in the byte
+ array. The Unicode data is converted into 8-bit characters using
+ QString::toUtf8().
+
+ If \a i is greater than size(), the array is first extended using
+ resize().
+
+ You can disable this function by defining \c QT_NO_CAST_TO_ASCII when you
+ compile your applications. You then need to call QString::toUtf8() (or
+ QString::toLatin1() or QString::toLocal8Bit()) explicitly if you want to
+ convert the data to \c{const char *}.
+*/
+
+/*!
+ \overload
+
+ Inserts the string \a str at position \a i in the byte array.
+
+ If \a i is greater than size(), the array is first extended using
+ resize().
+*/
+
+QByteArray &QByteArray::insert(int i, const char *str)
+{
+ return qbytearray_insert(this, i, str, qstrlen(str));
+}
+
+/*!
+ \overload
+ \since 4.6
+
+ Inserts \a len bytes of the string \a str at position
+ \a i in the byte array.
+
+ If \a i is greater than size(), the array is first extended using
+ resize().
+*/
+
+QByteArray &QByteArray::insert(int i, const char *str, int len)
+{
+ return qbytearray_insert(this, i, str, len);
+}
+
+/*!
+ \overload
+
+ Inserts character \a ch at index position \a i in the byte array.
+ If \a i is greater than size(), the array is first extended using
+ resize().
+*/
+
+QByteArray &QByteArray::insert(int i, char ch)
+{
+ return qbytearray_insert(this, i, &ch, 1);
+}
+
+/*! \fn QByteArray &QByteArray::insert(int i, int count, char ch)
+
+ \overload
+ \since 5.7
+
+ Inserts \a count copies of character \a ch at index position \a i in the
+ byte array.
+
+ If \a i is greater than size(), the array is first extended using resize().
+*/
+
+QByteArray &QByteArray::insert(int i, int count, char ch)
+{
+ if (i < 0 || count <= 0)
+ return *this;
+
+ int oldsize = size();
+ resize(qMax(i, oldsize) + count);
+ char *dst = d->data();
+ if (i > oldsize)
+ ::memset(dst + oldsize, 0x20, i - oldsize);
+ else if (i < oldsize)
+ ::memmove(dst + i + count, dst + i, oldsize - i);
+ ::memset(dst + i, ch, count);
+ return *this;
+}
+
+/*!
+ Removes \a len bytes from the array, starting at index position \a
+ pos, and returns a reference to the array.
+
+ If \a pos is out of range, nothing happens. If \a pos is valid,
+ but \a pos + \a len is larger than the size of the array, the
+ array is truncated at position \a pos.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 18
+
+ \sa insert(), replace()
+*/
+
+QByteArray &QByteArray::remove(int pos, int len)
+{
+ if (len <= 0 || uint(pos) >= uint(d->size))
+ return *this;
+ detach();
+ if (len >= d->size - pos) {
+ resize(pos);
+ } else {
+ memmove(d->data() + pos, d->data() + pos + len, d->size - pos - len);
+ resize(d->size - len);
+ }
+ return *this;
+}
+
+/*!
+ Replaces \a len bytes from index position \a pos with the byte
+ array \a after, and returns a reference to this byte array.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 19
+
+ \sa insert(), remove()
+*/
+
+QByteArray &QByteArray::replace(int pos, int len, const QByteArray &after)
+{
+ if (len == after.d->size && (pos + len <= d->size)) {
+ detach();
+ memmove(d->data() + pos, after.d->data(), len*sizeof(char));
+ return *this;
+ } else {
+ QByteArray copy(after);
+ // ### optimize me
+ remove(pos, len);
+ return insert(pos, copy);
+ }
+}
+
+/*! \fn QByteArray &QByteArray::replace(int pos, int len, const char *after)
+
+ \overload
+
+ Replaces \a len bytes from index position \a pos with the
+ '\\0'-terminated string \a after.
+
+ Notice: this can change the length of the byte array.
+*/
+QByteArray &QByteArray::replace(int pos, int len, const char *after)
+{
+ return replace(pos,len,after,qstrlen(after));
+}
+
+/*! \fn QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen)
+
+ \overload
+
+ Replaces \a len bytes from index position \a pos with \a alen bytes
+ from the string \a after. \a after is allowed to have '\\0' characters.
+
+ \since 4.7
+*/
+QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen)
+{
+ if (len == alen && (pos + len <= d->size)) {
+ detach();
+ memcpy(d->data() + pos, after, len*sizeof(char));
+ return *this;
+ } else {
+ remove(pos, len);
+ return qbytearray_insert(this, pos, after, alen);
+ }
+}
+
+// ### optimize all other replace method, by offering
+// QByteArray::replace(const char *before, int blen, const char *after, int alen)
+
+/*!
+ \overload
+
+ Replaces every occurrence of the byte array \a before with the
+ byte array \a after.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 20
+*/
+
+QByteArray &QByteArray::replace(const QByteArray &before, const QByteArray &after)
+{
+ if (isNull() || before.d == after.d)
+ return *this;
+
+ QByteArray aft = after;
+ if (after.d == d)
+ aft.detach();
+
+ return replace(before.constData(), before.size(), aft.constData(), aft.size());
+}
+
+/*!
+ \fn QByteArray &QByteArray::replace(const char *before, const QByteArray &after)
+ \overload
+
+ Replaces every occurrence of the string \a before with the
+ byte array \a after.
+*/
+
+QByteArray &QByteArray::replace(const char *c, const QByteArray &after)
+{
+ QByteArray aft = after;
+ if (after.d == d)
+ aft.detach();
+
+ return replace(c, qstrlen(c), aft.constData(), aft.size());
+}
+
+/*!
+ \fn QByteArray &QByteArray::replace(const char *before, int bsize, const char *after, int asize)
+ \overload
+
+ Replaces every occurrence of the string \a before with the string \a after.
+ Since the sizes of the strings are given by \a bsize and \a asize, they
+ may contain zero characters and do not need to be '\\0'-terminated.
+*/
+
+QByteArray &QByteArray::replace(const char *before, int bsize, const char *after, int asize)
+{
+ if (isNull() || (before == after && bsize == asize))
+ return *this;
+
+ // protect against before or after being part of this
+ const char *a = after;
+ const char *b = before;
+ if (after >= d->data() && after < d->data() + d->size) {
+ char *copy = (char *)malloc(asize);
+ Q_CHECK_PTR(copy);
+ memcpy(copy, after, asize);
+ a = copy;
+ }
+ if (before >= d->data() && before < d->data() + d->size) {
+ char *copy = (char *)malloc(bsize);
+ Q_CHECK_PTR(copy);
+ memcpy(copy, before, bsize);
+ b = copy;
+ }
+
+ QByteArrayMatcher matcher(before, bsize);
+ int index = 0;
+ int len = d->size;
+ char *d = data();
+
+ if (bsize == asize) {
+ if (bsize) {
+ while ((index = matcher.indexIn(*this, index)) != -1) {
+ memcpy(d + index, after, asize);
+ index += bsize;
+ }
+ }
+ } else if (asize < bsize) {
+ uint to = 0;
+ uint movestart = 0;
+ uint num = 0;
+ while ((index = matcher.indexIn(*this, index)) != -1) {
+ if (num) {
+ int msize = index - movestart;
+ if (msize > 0) {
+ memmove(d + to, d + movestart, msize);
+ to += msize;
+ }
+ } else {
+ to = index;
+ }
+ if (asize) {
+ memcpy(d + to, after, asize);
+ to += asize;
+ }
+ index += bsize;
+ movestart = index;
+ num++;
+ }
+ if (num) {
+ int msize = len - movestart;
+ if (msize > 0)
+ memmove(d + to, d + movestart, msize);
+ resize(len - num*(bsize-asize));
+ }
+ } else {
+ // the most complex case. We don't want to lose performance by doing repeated
+ // copies and reallocs of the string.
+ while (index != -1) {
+ uint indices[4096];
+ uint pos = 0;
+ while(pos < 4095) {
+ index = matcher.indexIn(*this, index);
+ if (index == -1)
+ break;
+ indices[pos++] = index;
+ index += bsize;
+ // avoid infinite loop
+ if (!bsize)
+ index++;
+ }
+ if (!pos)
+ break;
+
+ // we have a table of replacement positions, use them for fast replacing
+ int adjust = pos*(asize-bsize);
+ // index has to be adjusted in case we get back into the loop above.
+ if (index != -1)
+ index += adjust;
+ int newlen = len + adjust;
+ int moveend = len;
+ if (newlen > len) {
+ resize(newlen);
+ len = newlen;
+ }
+ d = this->d->data();
+
+ while(pos) {
+ pos--;
+ int movestart = indices[pos] + bsize;
+ int insertstart = indices[pos] + pos*(asize-bsize);
+ int moveto = insertstart + asize;
+ memmove(d + moveto, d + movestart, (moveend - movestart));
+ if (asize)
+ memcpy(d + insertstart, after, asize);
+ moveend = movestart - bsize;
+ }
+ }
+ }
+
+ if (a != after)
+ ::free(const_cast<char *>(a));
+ if (b != before)
+ ::free(const_cast<char *>(b));
+
+
+ return *this;
+}
+
+
+/*!
+ \fn QByteArray &QByteArray::replace(const QByteArray &before, const char *after)
+ \overload
+
+ Replaces every occurrence of the byte array \a before with the
+ string \a after.
+*/
+
+/*! \fn QByteArray &QByteArray::replace(const QString &before, const QByteArray &after)
+
+ \overload
+
+ Replaces every occurrence of the string \a before with the byte
+ array \a after. The Unicode data is converted into 8-bit
+ characters using QString::toUtf8().
+
+ You can disable this function by defining \c QT_NO_CAST_TO_ASCII when you
+ compile your applications. You then need to call QString::toUtf8() (or
+ QString::toLatin1() or QString::toLocal8Bit()) explicitly if you want to
+ convert the data to \c{const char *}.
+*/
+
+/*! \fn QByteArray &QByteArray::replace(const QString &before, const char *after)
+ \overload
+
+ Replaces every occurrence of the string \a before with the string
+ \a after.
+*/
+
+/*! \fn QByteArray &QByteArray::replace(const char *before, const char *after)
+
+ \overload
+
+ Replaces every occurrence of the string \a before with the string
+ \a after.
+*/
+
+/*!
+ \overload
+
+ Replaces every occurrence of the character \a before with the
+ byte array \a after.
+*/
+
+QByteArray &QByteArray::replace(char before, const QByteArray &after)
+{
+ char b[2] = { before, '\0' };
+ QByteArray cb = fromRawData(b, 1);
+ return replace(cb, after);
+}
+
+/*! \fn QByteArray &QByteArray::replace(char before, const QString &after)
+
+ \overload
+
+ Replaces every occurrence of the character \a before with the
+ string \a after. The Unicode data is converted into 8-bit
+ characters using QString::toUtf8().
+
+ You can disable this function by defining \c QT_NO_CAST_TO_ASCII when you
+ compile your applications. You then need to call QString::toUtf8() (or
+ QString::toLatin1() or QString::toLocal8Bit()) explicitly if you want to
+ convert the data to \c{const char *}.
+*/
+
+/*! \fn QByteArray &QByteArray::replace(char before, const char *after)
+
+ \overload
+
+ Replaces every occurrence of the character \a before with the
+ string \a after.
+*/
+
+/*!
+ \overload
+
+ Replaces every occurrence of the character \a before with the
+ character \a after.
+*/
+
+QByteArray &QByteArray::replace(char before, char after)
+{
+ if (d->size) {
+ char *i = data();
+ char *e = i + d->size;
+ for (; i != e; ++i)
+ if (*i == before)
+ * i = after;
+ }
+ return *this;
+}
+
+/*!
+ Splits the byte array into subarrays wherever \a sep occurs, and
+ returns the list of those arrays. If \a sep does not match
+ anywhere in the byte array, split() returns a single-element list
+ containing this byte array.
+*/
+
+QList<QByteArray> QByteArray::split(char sep) const
+{
+ QList<QByteArray> list;
+ int start = 0;
+ int end;
+ while ((end = indexOf(sep, start)) != -1) {
+ list.append(mid(start, end - start));
+ start = end + 1;
+ }
+ list.append(mid(start));
+ return list;
+}
+
+/*!
+ \since 4.5
+
+ Returns a copy of this byte array repeated the specified number of \a times.
+
+ If \a times is less than 1, an empty byte array is returned.
+
+ Example:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 49
+*/
+QByteArray QByteArray::repeated(int times) const
+{
+ if (d->size == 0)
+ return *this;
+
+ if (times <= 1) {
+ if (times == 1)
+ return *this;
+ return QByteArray();
+ }
+
+ const int resultSize = times * d->size;
+
+ QByteArray result;
+ result.reserve(resultSize);
+ if (result.d->alloc != uint(resultSize) + 1u)
+ return QByteArray(); // not enough memory
+
+ memcpy(result.d->data(), d->data(), d->size);
+
+ int sizeSoFar = d->size;
+ char *end = result.d->data() + sizeSoFar;
+
+ const int halfResultSize = resultSize >> 1;
+ while (sizeSoFar <= halfResultSize) {
+ memcpy(end, result.d->data(), sizeSoFar);
+ end += sizeSoFar;
+ sizeSoFar <<= 1;
+ }
+ memcpy(end, result.d->data(), resultSize - sizeSoFar);
+ result.d->data()[resultSize] = '\0';
+ result.d->size = resultSize;
+ return result;
+}
+
+#define REHASH(a) \
+ if (ol_minus_1 < sizeof(uint) * CHAR_BIT) \
+ hashHaystack -= (a) << ol_minus_1; \
+ hashHaystack <<= 1
+
+/*!
+ Returns the index position of the first occurrence of the byte
+ array \a ba in this byte array, searching forward from index
+ position \a from. Returns -1 if \a ba could not be found.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 21
+
+ \sa lastIndexOf(), contains(), count()
+*/
+
+int QByteArray::indexOf(const QByteArray &ba, int from) const
+{
+ const int ol = ba.d->size;
+ if (ol == 0)
+ return from;
+ if (ol == 1)
+ return indexOf(*ba.d->data(), from);
+
+ const int l = d->size;
+ if (from > d->size || ol + from > l)
+ return -1;
+
+ return qFindByteArray(d->data(), d->size, from, ba.d->data(), ol);
+}
+
+/*! \fn int QByteArray::indexOf(const QString &str, int from) const
+
+ \overload
+
+ Returns the index position of the first occurrence of the string
+ \a str in the byte array, searching forward from index position
+ \a from. Returns -1 if \a str could not be found.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toUtf8().
+
+ You can disable this function by defining \c QT_NO_CAST_TO_ASCII when you
+ compile your applications. You then need to call QString::toUtf8() (or
+ QString::toLatin1() or QString::toLocal8Bit()) explicitly if you want to
+ convert the data to \c{const char *}.
+*/
+
+/*! \fn int QByteArray::indexOf(const char *str, int from) const
+
+ \overload
+
+ Returns the index position of the first occurrence of the string
+ \a str in the byte array, searching forward from index position \a
+ from. Returns -1 if \a str could not be found.
+*/
+int QByteArray::indexOf(const char *c, int from) const
+{
+ const int ol = qstrlen(c);
+ if (ol == 1)
+ return indexOf(*c, from);
+
+ const int l = d->size;
+ if (from > d->size || ol + from > l)
+ return -1;
+ if (ol == 0)
+ return from;
+
+ return qFindByteArray(d->data(), d->size, from, c, ol);
+}
+
+/*!
+ \overload
+
+ Returns the index position of the first occurrence of the
+ character \a ch in the byte array, searching forward from index
+ position \a from. Returns -1 if \a ch could not be found.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 22
+
+ \sa lastIndexOf(), contains()
+*/
+
+int QByteArray::indexOf(char ch, int from) const
+{
+ if (from < 0)
+ from = qMax(from + d->size, 0);
+ if (from < d->size) {
+ const char *n = d->data() + from - 1;
+ const char *e = d->data() + d->size;
+ while (++n != e)
+ if (*n == ch)
+ return n - d->data();
+ }
+ return -1;
+}
+
+
+static int lastIndexOfHelper(const char *haystack, int l, const char *needle, int ol, int from)
+{
+ int delta = l - ol;
+ if (from < 0)
+ from = delta;
+ if (from < 0 || from > l)
+ return -1;
+ if (from > delta)
+ from = delta;
+
+ const char *end = haystack;
+ haystack += from;
+ const uint ol_minus_1 = ol - 1;
+ const char *n = needle + ol_minus_1;
+ const char *h = haystack + ol_minus_1;
+ uint hashNeedle = 0, hashHaystack = 0;
+ int idx;
+ for (idx = 0; idx < ol; ++idx) {
+ hashNeedle = ((hashNeedle<<1) + *(n-idx));
+ hashHaystack = ((hashHaystack<<1) + *(h-idx));
+ }
+ hashHaystack -= *haystack;
+ while (haystack >= end) {
+ hashHaystack += *haystack;
+ if (hashHaystack == hashNeedle && memcmp(needle, haystack, ol) == 0)
+ return haystack - end;
+ --haystack;
+ REHASH(*(haystack + ol));
+ }
+ return -1;
+
+}
+
+/*!
+ \fn int QByteArray::lastIndexOf(const QByteArray &ba, int from) const
+
+ Returns the index position of the last occurrence of the byte
+ array \a ba in this byte array, searching backward from index
+ position \a from. If \a from is -1 (the default), the search
+ starts at the last byte. Returns -1 if \a ba could not be found.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 23
+
+ \sa indexOf(), contains(), count()
+*/
+
+int QByteArray::lastIndexOf(const QByteArray &ba, int from) const
+{
+ const int ol = ba.d->size;
+ if (ol == 1)
+ return lastIndexOf(*ba.d->data(), from);
+
+ return lastIndexOfHelper(d->data(), d->size, ba.d->data(), ol, from);
+}
+
+/*! \fn int QByteArray::lastIndexOf(const QString &str, int from) const
+
+ \overload
+
+ Returns the index position of the last occurrence of the string \a
+ str in the byte array, searching backward from index position \a
+ from. If \a from is -1 (the default), the search starts at the
+ last (size() - 1) byte. Returns -1 if \a str could not be found.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toUtf8().
+
+ You can disable this function by defining \c QT_NO_CAST_TO_ASCII when you
+ compile your applications. You then need to call QString::toUtf8() (or
+ QString::toLatin1() or QString::toLocal8Bit()) explicitly if you want to
+ convert the data to \c{const char *}.
+*/
+
+/*! \fn int QByteArray::lastIndexOf(const char *str, int from) const
+ \overload
+
+ Returns the index position of the last occurrence of the string \a
+ str in the byte array, searching backward from index position \a
+ from. If \a from is -1 (the default), the search starts at the
+ last (size() - 1) byte. Returns -1 if \a str could not be found.
+*/
+int QByteArray::lastIndexOf(const char *str, int from) const
+{
+ const int ol = qstrlen(str);
+ if (ol == 1)
+ return lastIndexOf(*str, from);
+
+ return lastIndexOfHelper(d->data(), d->size, str, ol, from);
+}
+
+/*!
+ \overload
+
+ Returns the index position of the last occurrence of character \a
+ ch in the byte array, searching backward from index position \a
+ from. If \a from is -1 (the default), the search starts at the
+ last (size() - 1) byte. Returns -1 if \a ch could not be found.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 24
+
+ \sa indexOf(), contains()
+*/
+
+int QByteArray::lastIndexOf(char ch, int from) const
+{
+ if (from < 0)
+ from += d->size;
+ else if (from > d->size)
+ from = d->size-1;
+ if (from >= 0) {
+ const char *b = d->data();
+ const char *n = d->data() + from + 1;
+ while (n-- != b)
+ if (*n == ch)
+ return n - b;
+ }
+ return -1;
+}
+
+/*!
+ Returns the number of (potentially overlapping) occurrences of
+ byte array \a ba in this byte array.
+
+ \sa contains(), indexOf()
+*/
+
+int QByteArray::count(const QByteArray &ba) const
+{
+ int num = 0;
+ int i = -1;
+ if (d->size > 500 && ba.d->size > 5) {
+ QByteArrayMatcher matcher(ba);
+ while ((i = matcher.indexIn(*this, i + 1)) != -1)
+ ++num;
+ } else {
+ while ((i = indexOf(ba, i + 1)) != -1)
+ ++num;
+ }
+ return num;
+}
+
+/*!
+ \overload
+
+ Returns the number of (potentially overlapping) occurrences of
+ string \a str in the byte array.
+*/
+
+int QByteArray::count(const char *str) const
+{
+ return count(fromRawData(str, qstrlen(str)));
+}
+
+/*!
+ \overload
+
+ Returns the number of occurrences of character \a ch in the byte
+ array.
+
+ \sa contains(), indexOf()
+*/
+
+int QByteArray::count(char ch) const
+{
+ int num = 0;
+ const char *i = d->data() + d->size;
+ const char *b = d->data();
+ while (i != b)
+ if (*--i == ch)
+ ++num;
+ return num;
+}
+
+/*! \fn int QByteArray::count() const
+
+ \overload
+
+ Same as size().
+*/
+
+/*!
+ \fn int QByteArray::compare(const char *c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \since 5.12
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether this QByteArray sorts before, at the same position, or after the
+ string pointed to by \a c. The comparison is performed according to case
+ sensitivity \a cs.
+
+ \sa operator==
+*/
+
+/*!
+ \fn int QByteArray::compare(const QByteArray &a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \overload
+ \since 5.12
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether this QByteArray sorts before, at the same position, or after the
+ QByteArray \a a. The comparison is performed according to case sensitivity
+ \a cs.
+
+ \sa operator==
+*/
+
+/*!
+ Returns \c true if this byte array starts with byte array \a ba;
+ otherwise returns \c false.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 25
+
+ \sa endsWith(), left()
+*/
+bool QByteArray::startsWith(const QByteArray &ba) const
+{
+ if (d == ba.d || ba.d->size == 0)
+ return true;
+ if (d->size < ba.d->size)
+ return false;
+ return memcmp(d->data(), ba.d->data(), ba.d->size) == 0;
+}
+
+/*! \overload
+
+ Returns \c true if this byte array starts with string \a str;
+ otherwise returns \c false.
+*/
+bool QByteArray::startsWith(const char *str) const
+{
+ if (!str || !*str)
+ return true;
+ const int len = int(strlen(str));
+ if (d->size < len)
+ return false;
+ return qstrncmp(d->data(), str, len) == 0;
+}
+
+/*! \overload
+
+ Returns \c true if this byte array starts with character \a ch;
+ otherwise returns \c false.
+*/
+bool QByteArray::startsWith(char ch) const
+{
+ if (d->size == 0)
+ return false;
+ return d->data()[0] == ch;
+}
+
+/*!
+ Returns \c true if this byte array ends with byte array \a ba;
+ otherwise returns \c false.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 26
+
+ \sa startsWith(), right()
+*/
+bool QByteArray::endsWith(const QByteArray &ba) const
+{
+ if (d == ba.d || ba.d->size == 0)
+ return true;
+ if (d->size < ba.d->size)
+ return false;
+ return memcmp(d->data() + d->size - ba.d->size, ba.d->data(), ba.d->size) == 0;
+}
+
+/*! \overload
+
+ Returns \c true if this byte array ends with string \a str; otherwise
+ returns \c false.
+*/
+bool QByteArray::endsWith(const char *str) const
+{
+ if (!str || !*str)
+ return true;
+ const int len = int(strlen(str));
+ if (d->size < len)
+ return false;
+ return qstrncmp(d->data() + d->size - len, str, len) == 0;
+}
+
+/*
+ Returns true if \a c is an uppercase Latin1 letter.
+ \note The multiplication sign 0xD7 and the sz ligature 0xDF are not
+ treated as uppercase Latin1.
+ */
+static inline bool isUpperCaseLatin1(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return true;
+
+ return (uchar(c) >= 0xC0 && uchar(c) <= 0xDE && uchar(c) != 0xD7);
+}
+
+/*!
+ Returns \c true if this byte array contains only uppercase letters,
+ otherwise returns \c false. The byte array is interpreted as a Latin-1
+ encoded string.
+ \since 5.12
+
+ \sa isLower(), toUpper()
+*/
+bool QByteArray::isUpper() const
+{
+ if (isEmpty())
+ return false;
+
+ const char *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!isUpperCaseLatin1(d[i]))
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ Returns true if \a c is an lowercase Latin1 letter.
+ \note The division sign 0xF7 is not treated as lowercase Latin1,
+ but the small y dieresis 0xFF is.
+ */
+static inline bool isLowerCaseLatin1(char c)
+{
+ if (c >= 'a' && c <= 'z')
+ return true;
+
+ return (uchar(c) >= 0xD0 && uchar(c) != 0xF7);
+}
+
+/*!
+ Returns \c true if this byte array contains only lowercase letters,
+ otherwise returns \c false. The byte array is interpreted as a Latin-1
+ encoded string.
+ \since 5.12
+
+ \sa isUpper(), toLower()
+ */
+bool QByteArray::isLower() const
+{
+ if (isEmpty())
+ return false;
+
+ const char *d = data();
+
+ for (int i = 0, max = size(); i < max; ++i) {
+ if (!isLowerCaseLatin1(d[i]))
+ return false;
+ }
+
+ return true;
+}
+
+/*! \overload
+
+ Returns \c true if this byte array ends with character \a ch;
+ otherwise returns \c false.
+*/
+bool QByteArray::endsWith(char ch) const
+{
+ if (d->size == 0)
+ return false;
+ return d->data()[d->size - 1] == ch;
+}
+
+/*!
+ Returns a byte array that contains the leftmost \a len bytes of
+ this byte array.
+
+ The entire byte array is returned if \a len is greater than
+ size().
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 27
+
+ \sa startsWith(), right(), mid(), chopped(), chop(), truncate()
+*/
+
+QByteArray QByteArray::left(int len) const
+{
+ if (len >= d->size)
+ return *this;
+ if (len < 0)
+ len = 0;
+ return QByteArray(d->data(), len);
+}
+
+/*!
+ Returns a byte array that contains the rightmost \a len bytes of
+ this byte array.
+
+ The entire byte array is returned if \a len is greater than
+ size().
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 28
+
+ \sa endsWith(), left(), mid(), chopped(), chop(), truncate()
+*/
+
+QByteArray QByteArray::right(int len) const
+{
+ if (len >= d->size)
+ return *this;
+ if (len < 0)
+ len = 0;
+ return QByteArray(d->data() + d->size - len, len);
+}
+
+/*!
+ Returns a byte array containing \a len bytes from this byte array,
+ starting at position \a pos.
+
+ If \a len is -1 (the default), or \a pos + \a len >= size(),
+ returns a byte array containing all bytes starting at position \a
+ pos until the end of the byte array.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 29
+
+ \sa left(), right(), chopped(), chop(), truncate()
+*/
+
+QByteArray QByteArray::mid(int pos, int len) const
+{
+ using namespace QtPrivate;
+ switch (QContainerImplHelper::mid(size(), &pos, &len)) {
+ case QContainerImplHelper::Null:
+ return QByteArray();
+ case QContainerImplHelper::Empty:
+ {
+ QByteArrayDataPtr empty = { Data::allocate(0) };
+ return QByteArray(empty);
+ }
+ case QContainerImplHelper::Full:
+ return *this;
+ case QContainerImplHelper::Subset:
+ return QByteArray(d->data() + pos, len);
+ }
+ Q_UNREACHABLE();
+ return QByteArray();
+}
+
+/*!
+ \fn QByteArray::chopped(int len) const
+ \since 5.10
+
+ Returns a byte array that contains the leftmost size() - \a len bytes of
+ this byte array.
+
+ \note The behavior is undefined if \a len is negative or greater than size().
+
+ \sa endsWith(), left(), right(), mid(), chop(), truncate()
+*/
+
+/*!
+ \fn QByteArray QByteArray::toLower() const
+
+ Returns a lowercase copy of the byte array. The bytearray is
+ interpreted as a Latin-1 encoded string.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 30
+
+ \sa isLower(), toUpper(), {8-bit Character Comparisons}
+*/
+
+// prevent the compiler from inlining the function in each of
+// toLower and toUpper when the only difference is the table being used
+// (even with constant propagation, there's no gain in performance).
+template <typename T>
+Q_NEVER_INLINE
+static QByteArray toCase_template(T &input, const uchar * table)
+{
+ // find the first bad character in input
+ const char *orig_begin = input.constBegin();
+ const char *firstBad = orig_begin;
+ const char *e = input.constEnd();
+ for ( ; firstBad != e ; ++firstBad) {
+ uchar ch = uchar(*firstBad);
+ uchar converted = table[ch];
+ if (ch != converted)
+ break;
+ }
+
+ if (firstBad == e)
+ return std::move(input);
+
+ // transform the rest
+ QByteArray s = std::move(input); // will copy if T is const QByteArray
+ char *b = s.begin(); // will detach if necessary
+ char *p = b + (firstBad - orig_begin);
+ e = b + s.size();
+ for ( ; p != e; ++p) {
+ *p = char(uchar(table[uchar(*p)]));
+ }
+ return s;
+}
+
+QByteArray QByteArray::toLower_helper(const QByteArray &a)
+{
+ return toCase_template(a, latin1_lowercased);
+}
+
+QByteArray QByteArray::toLower_helper(QByteArray &a)
+{
+ return toCase_template(a, latin1_lowercased);
+}
+
+/*!
+ \fn QByteArray QByteArray::toUpper() const
+
+ Returns an uppercase copy of the byte array. The bytearray is
+ interpreted as a Latin-1 encoded string.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 31
+
+ \sa isUpper(), toLower(), {8-bit Character Comparisons}
+*/
+
+QByteArray QByteArray::toUpper_helper(const QByteArray &a)
+{
+ return toCase_template(a, latin1_uppercased);
+}
+
+QByteArray QByteArray::toUpper_helper(QByteArray &a)
+{
+ return toCase_template(a, latin1_uppercased);
+}
+
+/*! \fn void QByteArray::clear()
+
+ Clears the contents of the byte array and makes it null.
+
+ \sa resize(), isNull()
+*/
+
+void QByteArray::clear()
+{
+ if (!d->ref.deref())
+ Data::deallocate(d);
+ d = Data::sharedNull();
+}
+
+#if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE))
+
+/*! \relates QByteArray
+
+ Writes byte array \a ba to the stream \a out and returns a reference
+ to the stream.
+
+ \sa {Serializing Qt Data Types}
+*/
+
+QDataStream &operator<<(QDataStream &out, const QByteArray &ba)
+{
+ if (ba.isNull() && out.version() >= 6) {
+ out << (quint32)0xffffffff;
+ return out;
+ }
+ return out.writeBytes(ba.constData(), ba.size());
+}
+
+/*! \relates QByteArray
+
+ Reads a byte array into \a ba from the stream \a in and returns a
+ reference to the stream.
+
+ \sa {Serializing Qt Data Types}
+*/
+
+QDataStream &operator>>(QDataStream &in, QByteArray &ba)
+{
+ ba.clear();
+ quint32 len;
+ in >> len;
+ if (len == 0xffffffff)
+ return in;
+
+ const quint32 Step = 1024 * 1024;
+ quint32 allocated = 0;
+
+ do {
+ int blockSize = qMin(Step, len - allocated);
+ ba.resize(allocated + blockSize);
+ if (in.readRawData(ba.data() + allocated, blockSize) != blockSize) {
+ ba.clear();
+ in.setStatus(QDataStream::ReadPastEnd);
+ return in;
+ }
+ allocated += blockSize;
+ } while (allocated < len);
+
+ return in;
+}
+#endif // QT_NO_DATASTREAM
+
+/*! \fn bool QByteArray::operator==(const QString &str) const
+
+ Returns \c true if this byte array is equal to string \a str;
+ otherwise returns \c false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toUtf8().
+
+ The comparison is case sensitive.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. You
+ then need to call QString::fromUtf8(), QString::fromLatin1(),
+ or QString::fromLocal8Bit() explicitly if you want to convert the byte
+ array to a QString before doing the comparison.
+*/
+
+/*! \fn bool QByteArray::operator!=(const QString &str) const
+
+ Returns \c true if this byte array is not equal to string \a str;
+ otherwise returns \c false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toUtf8().
+
+ The comparison is case sensitive.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. You
+ then need to call QString::fromUtf8(), QString::fromLatin1(),
+ or QString::fromLocal8Bit() explicitly if you want to convert the byte
+ array to a QString before doing the comparison.
+*/
+
+/*! \fn bool QByteArray::operator<(const QString &str) const
+
+ Returns \c true if this byte array is lexically less than string \a
+ str; otherwise returns \c false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toUtf8().
+
+ The comparison is case sensitive.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. You
+ then need to call QString::fromUtf8(), QString::fromLatin1(),
+ or QString::fromLocal8Bit() explicitly if you want to convert the byte
+ array to a QString before doing the comparison.
+*/
+
+/*! \fn bool QByteArray::operator>(const QString &str) const
+
+ Returns \c true if this byte array is lexically greater than string
+ \a str; otherwise returns \c false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toUtf8().
+
+ The comparison is case sensitive.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. You
+ then need to call QString::fromUtf8(), QString::fromLatin1(),
+ or QString::fromLocal8Bit() explicitly if you want to convert the byte
+ array to a QString before doing the comparison.
+*/
+
+/*! \fn bool QByteArray::operator<=(const QString &str) const
+
+ Returns \c true if this byte array is lexically less than or equal
+ to string \a str; otherwise returns \c false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toUtf8().
+
+ The comparison is case sensitive.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. You
+ then need to call QString::fromUtf8(), QString::fromLatin1(),
+ or QString::fromLocal8Bit() explicitly if you want to convert the byte
+ array to a QString before doing the comparison.
+*/
+
+/*! \fn bool QByteArray::operator>=(const QString &str) const
+
+ Returns \c true if this byte array is greater than or equal to string
+ \a str; otherwise returns \c false.
+
+ The Unicode data is converted into 8-bit characters using
+ QString::toUtf8().
+
+ The comparison is case sensitive.
+
+ You can disable this operator by defining \c
+ QT_NO_CAST_FROM_ASCII when you compile your applications. You
+ then need to call QString::fromUtf8(), QString::fromLatin1(),
+ or QString::fromLocal8Bit() explicitly if you want to convert the byte
+ array to a QString before doing the comparison.
+*/
+
+/*! \fn bool operator==(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is equal to byte array \a a2;
+ otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator==(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is equal to string \a a2;
+ otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator==(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if string \a a1 is equal to byte array \a a2;
+ otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator!=(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is not equal to byte array \a a2;
+ otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator!=(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is not equal to string \a a2;
+ otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator!=(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if string \a a1 is not equal to byte array \a a2;
+ otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator<(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is lexically less than byte array
+ \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn inline bool operator<(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is lexically less than string
+ \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator<(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if string \a a1 is lexically less than byte array
+ \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator<=(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is lexically less than or equal
+ to byte array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator<=(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is lexically less than or equal
+ to string \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator<=(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if string \a a1 is lexically less than or equal
+ to byte array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator>(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is lexically greater than byte
+ array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator>(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is lexically greater than string
+ \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator>(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if string \a a1 is lexically greater than byte array
+ \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator>=(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is lexically greater than or
+ equal to byte array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator>=(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if byte array \a a1 is lexically greater than or
+ equal to string \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn bool operator>=(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns \c true if string \a a1 is lexically greater than or
+ equal to byte array \a a2; otherwise returns \c false.
+
+ \sa QByteArray::compare()
+*/
+
+/*! \fn const QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
+ \relates QByteArray
+
+ Returns a byte array that is the result of concatenating byte
+ array \a a1 and byte array \a a2.
+
+ \sa QByteArray::operator+=()
+*/
+
+/*! \fn const QByteArray operator+(const QByteArray &a1, const char *a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns a byte array that is the result of concatenating byte
+ array \a a1 and string \a a2.
+*/
+
+/*! \fn const QByteArray operator+(const QByteArray &a1, char a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns a byte array that is the result of concatenating byte
+ array \a a1 and character \a a2.
+*/
+
+/*! \fn const QByteArray operator+(const char *a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns a byte array that is the result of concatenating string
+ \a a1 and byte array \a a2.
+*/
+
+/*! \fn const QByteArray operator+(char a1, const QByteArray &a2)
+ \relates QByteArray
+
+ \overload
+
+ Returns a byte array that is the result of concatenating character
+ \a a1 and byte array \a a2.
+*/
+
+/*!
+ \fn QByteArray QByteArray::simplified() const
+
+ Returns a byte array that has whitespace removed from the start
+ and the end, and which has each sequence of internal whitespace
+ replaced with a single space.
+
+ Whitespace means any character for which the standard C++
+ \c isspace() function returns \c true in the C locale. This includes the ASCII
+ isspace() function returns \c true in the C locale. This includes the ASCII
+ characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' '.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 32
+
+ \sa trimmed()
+*/
+QByteArray QByteArray::simplified_helper(const QByteArray &a)
+{
+ return QStringAlgorithms<const QByteArray>::simplified_helper(a);
+}
+
+QByteArray QByteArray::simplified_helper(QByteArray &a)
+{
+ return QStringAlgorithms<QByteArray>::simplified_helper(a);
+}
+
+/*!
+ \fn QByteArray QByteArray::trimmed() const
+
+ Returns a byte array that has whitespace removed from the start
+ and the end.
+
+ Whitespace means any character for which the standard C++
+ \c isspace() function returns \c true in the C locale. This includes the ASCII
+ characters '\\t', '\\n', '\\v', '\\f', '\\r', and ' '.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 33
+
+ Unlike simplified(), \l {QByteArray::trimmed()}{trimmed()} leaves internal whitespace alone.
+
+ \sa simplified()
+*/
+QByteArray QByteArray::trimmed_helper(const QByteArray &a)
+{
+ return QStringAlgorithms<const QByteArray>::trimmed_helper(a);
+}
+
+QByteArray QByteArray::trimmed_helper(QByteArray &a)
+{
+ return QStringAlgorithms<QByteArray>::trimmed_helper(a);
+}
+
+
+/*!
+ Returns a byte array of size \a width that contains this byte
+ array padded by the \a fill character.
+
+ If \a truncate is false and the size() of the byte array is more
+ than \a width, then the returned byte array is a copy of this byte
+ array.
+
+ If \a truncate is true and the size() of the byte array is more
+ than \a width, then any bytes in a copy of the byte array
+ after position \a width are removed, and the copy is returned.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 34
+
+ \sa rightJustified()
+*/
+
+QByteArray QByteArray::leftJustified(int width, char fill, bool truncate) const
+{
+ QByteArray result;
+ int len = d->size;
+ int padlen = width - len;
+ if (padlen > 0) {
+ result.resize(len+padlen);
+ if (len)
+ memcpy(result.d->data(), d->data(), len);
+ memset(result.d->data()+len, fill, padlen);
+ } else {
+ if (truncate)
+ result = left(width);
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a byte array of size \a width that contains the \a fill
+ character followed by this byte array.
+
+ If \a truncate is false and the size of the byte array is more
+ than \a width, then the returned byte array is a copy of this byte
+ array.
+
+ If \a truncate is true and the size of the byte array is more
+ than \a width, then the resulting byte array is truncated at
+ position \a width.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 35
+
+ \sa leftJustified()
+*/
+
+QByteArray QByteArray::rightJustified(int width, char fill, bool truncate) const
+{
+ QByteArray result;
+ int len = d->size;
+ int padlen = width - len;
+ if (padlen > 0) {
+ result.resize(len+padlen);
+ if (len)
+ memcpy(result.d->data()+padlen, data(), len);
+ memset(result.d->data(), fill, padlen);
+ } else {
+ if (truncate)
+ result = left(width);
+ else
+ result = *this;
+ }
+ return result;
+}
+
+bool QByteArray::isNull() const { return d == QArrayData::sharedNull(); }
+
+static qlonglong toIntegral_helper(const char *data, bool *ok, int base, qlonglong)
+{
+ return QLocaleData::bytearrayToLongLong(data, base, ok);
+}
+
+static qulonglong toIntegral_helper(const char *data, bool *ok, int base, qulonglong)
+{
+ return QLocaleData::bytearrayToUnsLongLong(data, base, ok);
+}
+
+template <typename T> static inline
+T toIntegral_helper(const char *data, bool *ok, int base)
+{
+ using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
+
+#if defined(QT_CHECK_RANGE)
+ if (base != 0 && (base < 2 || base > 36)) {
+ qWarning("QByteArray::toIntegral: Invalid base %d", base);
+ base = 10;
+ }
+#endif
+
+ // we select the right overload by the last, unused parameter
+ Int64 val = toIntegral_helper(data, ok, base, Int64());
+ if (T(val) != val) {
+ if (ok)
+ *ok = false;
+ val = 0;
+ }
+ return T(val);
+}
+
+/*!
+ Returns the byte array converted to a \c {long long} using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+
+ If \a base is 0, the base is determined automatically using the
+ following rules: If the byte array begins with "0x", it is assumed to
+ be hexadecimal; if it begins with "0", it is assumed to be octal;
+ otherwise it is assumed to be decimal.
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+
+qlonglong QByteArray::toLongLong(bool *ok, int base) const
+{
+ return toIntegral_helper<qlonglong>(nulTerminated().constData(), ok, base);
+}
+
+/*!
+ Returns the byte array converted to an \c {unsigned long long}
+ using base \a base, which is 10 by default and must be between 2
+ and 36, or 0.
+
+ If \a base is 0, the base is determined automatically using the
+ following rules: If the byte array begins with "0x", it is assumed to
+ be hexadecimal; if it begins with "0", it is assumed to be octal;
+ otherwise it is assumed to be decimal.
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+
+qulonglong QByteArray::toULongLong(bool *ok, int base) const
+{
+ return toIntegral_helper<qulonglong>(nulTerminated().constData(), ok, base);
+}
+
+/*!
+ Returns the byte array converted to an \c int using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+
+ If \a base is 0, the base is determined automatically using the
+ following rules: If the byte array begins with "0x", it is assumed to
+ be hexadecimal; if it begins with "0", it is assumed to be octal;
+ otherwise it is assumed to be decimal.
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 36
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+
+int QByteArray::toInt(bool *ok, int base) const
+{
+ return toIntegral_helper<int>(nulTerminated().constData(), ok, base);
+}
+
+/*!
+ Returns the byte array converted to an \c {unsigned int} using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+
+ If \a base is 0, the base is determined automatically using the
+ following rules: If the byte array begins with "0x", it is assumed to
+ be hexadecimal; if it begins with "0", it is assumed to be octal;
+ otherwise it is assumed to be decimal.
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+
+uint QByteArray::toUInt(bool *ok, int base) const
+{
+ return toIntegral_helper<uint>(nulTerminated().constData(), ok, base);
+}
+
+/*!
+ \since 4.1
+
+ Returns the byte array converted to a \c long int using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+
+ If \a base is 0, the base is determined automatically using the
+ following rules: If the byte array begins with "0x", it is assumed to
+ be hexadecimal; if it begins with "0", it is assumed to be octal;
+ otherwise it is assumed to be decimal.
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 37
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+long QByteArray::toLong(bool *ok, int base) const
+{
+ return toIntegral_helper<long>(nulTerminated().constData(), ok, base);
+}
+
+/*!
+ \since 4.1
+
+ Returns the byte array converted to an \c {unsigned long int} using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+
+ If \a base is 0, the base is determined automatically using the
+ following rules: If the byte array begins with "0x", it is assumed to
+ be hexadecimal; if it begins with "0", it is assumed to be octal;
+ otherwise it is assumed to be decimal.
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+ulong QByteArray::toULong(bool *ok, int base) const
+{
+ return toIntegral_helper<ulong>(nulTerminated().constData(), ok, base);
+}
+
+/*!
+ Returns the byte array converted to a \c short using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+
+ If \a base is 0, the base is determined automatically using the
+ following rules: If the byte array begins with "0x", it is assumed to
+ be hexadecimal; if it begins with "0", it is assumed to be octal;
+ otherwise it is assumed to be decimal.
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+
+short QByteArray::toShort(bool *ok, int base) const
+{
+ return toIntegral_helper<short>(nulTerminated().constData(), ok, base);
+}
+
+/*!
+ Returns the byte array converted to an \c {unsigned short} using base \a
+ base, which is 10 by default and must be between 2 and 36, or 0.
+
+ If \a base is 0, the base is determined automatically using the
+ following rules: If the byte array begins with "0x", it is assumed to
+ be hexadecimal; if it begins with "0", it is assumed to be octal;
+ otherwise it is assumed to be decimal.
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ \sa number()
+*/
+
+ushort QByteArray::toUShort(bool *ok, int base) const
+{
+ return toIntegral_helper<ushort>(nulTerminated().constData(), ok, base);
+}
+
+
+/*!
+ Returns the byte array converted to a \c double value.
+
+ Returns an infinity if the conversion overflows or 0.0 if the
+ conversion fails for other reasons (e.g. underflow).
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 38
+
+ \warning The QByteArray content may only contain valid numerical characters
+ which includes the plus/minus sign, the character e used in scientific
+ notation, and the decimal point. Including the unit or additional characters
+ leads to a conversion error.
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa number()
+*/
+
+double QByteArray::toDouble(bool *ok) const
+{
+ bool nonNullOk = false;
+ int processed = 0;
+ double d = qt_asciiToDouble(constData(), size(),
+ nonNullOk, processed, WhitespacesAllowed);
+ if (ok)
+ *ok = nonNullOk;
+ return d;
+}
+
+/*!
+ Returns the byte array converted to a \c float value.
+
+ Returns an infinity if the conversion overflows or 0.0 if the
+ conversion fails for other reasons (e.g. underflow).
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 38float
+
+ \warning The QByteArray content may only contain valid numerical characters
+ which includes the plus/minus sign, the character e used in scientific
+ notation, and the decimal point. Including the unit or additional characters
+ leads to a conversion error.
+
+ \note The conversion of the number is performed in the default C locale,
+ irrespective of the user's locale.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa number()
+*/
+
+float QByteArray::toFloat(bool *ok) const
+{
+ return QLocaleData::convertDoubleToFloat(toDouble(ok), ok);
+}
+
+/*!
+ Returns a copy of the byte array, encoded as Base64.
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 39
+
+ The algorithm used to encode Base64-encoded data is defined in \l{RFC 4648}.
+
+ \sa fromBase64()
+*/
+QByteArray QByteArray::toBase64() const
+{
+ return toBase64(Base64Encoding);
+}
+
+/*!
+ \since 5.2
+ \overload
+
+ Returns a copy of the byte array, encoded using the options \a options.
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 39bis
+
+ The algorithm used to encode Base64-encoded data is defined in \l{RFC 4648}.
+
+ \sa fromBase64()
+*/
+QByteArray QByteArray::toBase64(Base64Options options) const
+{
+ const char alphabet_base64[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
+ "ghijklmn" "opqrstuv" "wxyz0123" "456789+/";
+ const char alphabet_base64url[] = "ABCDEFGH" "IJKLMNOP" "QRSTUVWX" "YZabcdef"
+ "ghijklmn" "opqrstuv" "wxyz0123" "456789-_";
+ const char *const alphabet = options & Base64UrlEncoding ? alphabet_base64url : alphabet_base64;
+ const char padchar = '=';
+ int padlen = 0;
+
+ QByteArray tmp((d->size + 2) / 3 * 4, Qt::Uninitialized);
+
+ int i = 0;
+ char *out = tmp.data();
+ while (i < d->size) {
+ // encode 3 bytes at a time
+ int chunk = 0;
+ chunk |= int(uchar(d->data()[i++])) << 16;
+ if (i == d->size) {
+ padlen = 2;
+ } else {
+ chunk |= int(uchar(d->data()[i++])) << 8;
+ if (i == d->size)
+ padlen = 1;
+ else
+ chunk |= int(uchar(data()[i++]));
+ }
+
+ int j = (chunk & 0x00fc0000) >> 18;
+ int k = (chunk & 0x0003f000) >> 12;
+ int l = (chunk & 0x00000fc0) >> 6;
+ int m = (chunk & 0x0000003f);
+ *out++ = alphabet[j];
+ *out++ = alphabet[k];
+
+ if (padlen > 1) {
+ if ((options & OmitTrailingEquals) == 0)
+ *out++ = padchar;
+ } else {
+ *out++ = alphabet[l];
+ }
+ if (padlen > 0) {
+ if ((options & OmitTrailingEquals) == 0)
+ *out++ = padchar;
+ } else {
+ *out++ = alphabet[m];
+ }
+ }
+ Q_ASSERT((options & OmitTrailingEquals) || (out == tmp.size() + tmp.data()));
+ if (options & OmitTrailingEquals)
+ tmp.truncate(out - tmp.data());
+ return tmp;
+}
+
+/*!
+ \fn QByteArray &QByteArray::setNum(int n, int base)
+
+ Sets the byte array to the printed value of \a n in base \a base (10
+ by default) and returns a reference to the byte array. The \a base can
+ be any value between 2 and 36. For bases other than 10, n is treated
+ as an unsigned integer.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 40
+
+ \note The format of the number is not localized; the default C locale
+ is used irrespective of the user's locale.
+
+ \sa number(), toInt()
+*/
+
+/*!
+ \fn QByteArray &QByteArray::setNum(uint n, int base)
+ \overload
+
+ \sa toUInt()
+*/
+
+/*!
+ \fn QByteArray &QByteArray::setNum(short n, int base)
+ \overload
+
+ \sa toShort()
+*/
+
+/*!
+ \fn QByteArray &QByteArray::setNum(ushort n, int base)
+ \overload
+
+ \sa toUShort()
+*/
+
+static char *qulltoa2(char *p, qulonglong n, int base)
+{
+#if defined(QT_CHECK_RANGE)
+ if (base < 2 || base > 36) {
+ qWarning("QByteArray::setNum: Invalid base %d", base);
+ base = 10;
+ }
+#endif
+ const char b = 'a' - 10;
+ do {
+ const int c = n % base;
+ n /= base;
+ *--p = c + (c < 10 ? '0' : b);
+ } while (n);
+
+ return p;
+}
+
+/*!
+ \overload
+
+ \sa toLongLong()
+*/
+QByteArray &QByteArray::setNum(qlonglong n, int base)
+{
+ const int buffsize = 66; // big enough for MAX_ULLONG in base 2
+ char buff[buffsize];
+ char *p;
+
+ if (n < 0 && base == 10) {
+ p = qulltoa2(buff + buffsize, qulonglong(-(1 + n)) + 1, base);
+ *--p = '-';
+ } else {
+ p = qulltoa2(buff + buffsize, qulonglong(n), base);
+ }
+
+ clear();
+ append(p, buffsize - (p - buff));
+ return *this;
+}
+
+/*!
+ \overload
+
+ \sa toULongLong()
+*/
+
+QByteArray &QByteArray::setNum(qulonglong n, int base)
+{
+ const int buffsize = 66; // big enough for MAX_ULLONG in base 2
+ char buff[buffsize];
+ char *p = qulltoa2(buff + buffsize, n, base);
+
+ clear();
+ append(p, buffsize - (p - buff));
+ return *this;
+}
+
+/*!
+ \overload
+
+ Sets the byte array to the printed value of \a n, formatted in format
+ \a f with precision \a prec, and returns a reference to the
+ byte array.
+
+ The format \a f can be any of the following:
+
+ \table
+ \header \li Format \li Meaning
+ \row \li \c e \li format as [-]9.9e[+|-]999
+ \row \li \c E \li format as [-]9.9E[+|-]999
+ \row \li \c f \li format as [-]9.9
+ \row \li \c g \li use \c e or \c f format, whichever is the most concise
+ \row \li \c G \li use \c E or \c f format, whichever is the most concise
+ \endtable
+
+ With 'e', 'E', and 'f', \a prec is the number of digits after the
+ decimal point. With 'g' and 'G', \a prec is the maximum number of
+ significant digits (trailing zeroes are omitted).
+
+ \note The format of the number is not localized; the default C locale
+ is used irrespective of the user's locale.
+
+ \sa toDouble()
+*/
+
+QByteArray &QByteArray::setNum(double n, char f, int prec)
+{
+ QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
+ uint flags = QLocaleData::ZeroPadExponent;
+
+ char lower = latin1_lowercased[uchar(f)];
+ if (f != lower)
+ flags |= QLocaleData::CapitalEorX;
+ f = lower;
+
+ switch (f) {
+ case 'f':
+ form = QLocaleData::DFDecimal;
+ break;
+ case 'e':
+ form = QLocaleData::DFExponent;
+ break;
+ case 'g':
+ form = QLocaleData::DFSignificantDigits;
+ break;
+ default:
+#if defined(QT_CHECK_RANGE)
+ qWarning("QByteArray::setNum: Invalid format char '%c'", f);
+#endif
+ break;
+ }
+
+ *this = QLocaleData::c()->doubleToString(n, prec, form, -1, flags).toLatin1();
+ return *this;
+}
+
+/*!
+ \fn QByteArray &QByteArray::setNum(float n, char f, int prec)
+ \overload
+
+ Sets the byte array to the printed value of \a n, formatted in format
+ \a f with precision \a prec, and returns a reference to the
+ byte array.
+
+ \note The format of the number is not localized; the default C locale
+ is used irrespective of the user's locale.
+
+ \sa toFloat()
+*/
+
+/*!
+ Returns a byte array containing the string equivalent of the
+ number \a n to base \a base (10 by default). The \a base can be
+ any value between 2 and 36.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 41
+
+ \note The format of the number is not localized; the default C locale
+ is used irrespective of the user's locale.
+
+ \sa setNum(), toInt()
+*/
+QByteArray QByteArray::number(int n, int base)
+{
+ QByteArray s;
+ s.setNum(n, base);
+ return s;
+}
+
+/*!
+ \overload
+
+ \sa toUInt()
+*/
+QByteArray QByteArray::number(uint n, int base)
+{
+ QByteArray s;
+ s.setNum(n, base);
+ return s;
+}
+
+/*!
+ \overload
+
+ \sa toLongLong()
+*/
+QByteArray QByteArray::number(qlonglong n, int base)
+{
+ QByteArray s;
+ s.setNum(n, base);
+ return s;
+}
+
+/*!
+ \overload
+
+ \sa toULongLong()
+*/
+QByteArray QByteArray::number(qulonglong n, int base)
+{
+ QByteArray s;
+ s.setNum(n, base);
+ return s;
+}
+
+/*!
+ \overload
+
+ Returns a byte array that contains the printed value of \a n,
+ formatted in format \a f with precision \a prec.
+
+ Argument \a n is formatted according to the \a f format specified,
+ which is \c g by default, and can be any of the following:
+
+ \table
+ \header \li Format \li Meaning
+ \row \li \c e \li format as [-]9.9e[+|-]999
+ \row \li \c E \li format as [-]9.9E[+|-]999
+ \row \li \c f \li format as [-]9.9
+ \row \li \c g \li use \c e or \c f format, whichever is the most concise
+ \row \li \c G \li use \c E or \c f format, whichever is the most concise
+ \endtable
+
+ With 'e', 'E', and 'f', \a prec is the number of digits after the
+ decimal point. With 'g' and 'G', \a prec is the maximum number of
+ significant digits (trailing zeroes are omitted).
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 42
+
+ \note The format of the number is not localized; the default C locale
+ is used irrespective of the user's locale.
+
+ \sa toDouble()
+*/
+QByteArray QByteArray::number(double n, char f, int prec)
+{
+ QByteArray s;
+ s.setNum(n, f, prec);
+ return s;
+}
+
+/*!
+ Constructs a QByteArray that uses the first \a size bytes of the
+ \a data array. The bytes are \e not copied. The QByteArray will
+ contain the \a data pointer. The caller guarantees that \a data
+ will not be deleted or modified as long as this QByteArray and any
+ copies of it exist that have not been modified. In other words,
+ because QByteArray is an \l{implicitly shared} class and the
+ instance returned by this function contains the \a data pointer,
+ the caller must not delete \a data or modify it directly as long
+ as the returned QByteArray and any copies exist. However,
+ QByteArray does not take ownership of \a data, so the QByteArray
+ destructor will never delete the raw \a data, even when the
+ last QByteArray referring to \a data is destroyed.
+
+ A subsequent attempt to modify the contents of the returned
+ QByteArray or any copy made from it will cause it to create a deep
+ copy of the \a data array before doing the modification. This
+ ensures that the raw \a data array itself will never be modified
+ by QByteArray.
+
+ Here is an example of how to read data using a QDataStream on raw
+ data in memory without copying the raw data into a QByteArray:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 43
+
+ \warning A byte array created with fromRawData() is \e not
+ '\\0'-terminated, unless the raw data contains a 0 character at
+ position \a size. While that does not matter for QDataStream or
+ functions like indexOf(), passing the byte array to a function
+ accepting a \c{const char *} expected to be '\\0'-terminated will
+ fail.
+
+ \sa setRawData(), data(), constData()
+*/
+
+QByteArray QByteArray::fromRawData(const char *data, int size)
+{
+ Data *x;
+ if (!data) {
+ x = Data::sharedNull();
+ } else if (!size) {
+ x = Data::allocate(0);
+ } else {
+ x = Data::fromRawData(data, size);
+ Q_CHECK_PTR(x);
+ }
+ QByteArrayDataPtr dataPtr = { x };
+ return QByteArray(dataPtr);
+}
+
+/*!
+ \since 4.7
+
+ Resets the QByteArray to use the first \a size bytes of the
+ \a data array. The bytes are \e not copied. The QByteArray will
+ contain the \a data pointer. The caller guarantees that \a data
+ will not be deleted or modified as long as this QByteArray and any
+ copies of it exist that have not been modified.
+
+ This function can be used instead of fromRawData() to re-use
+ existing QByteArray objects to save memory re-allocations.
+
+ \sa fromRawData(), data(), constData()
+*/
+QByteArray &QByteArray::setRawData(const char *data, uint size)
+{
+ if (d->ref.isShared() || d->alloc) {
+ *this = fromRawData(data, size);
+ } else {
+ if (data) {
+ d->size = size;
+ d->offset = data - reinterpret_cast<char *>(d);
+ } else {
+ d->offset = sizeof(QByteArrayData);
+ d->size = 0;
+ }
+ }
+ return *this;
+}
+
+/*!
+ Returns a decoded copy of the Base64 array \a base64. Input is not checked
+ for validity; invalid characters in the input are skipped, enabling the
+ decoding process to continue with subsequent characters.
+
+ For example:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 44
+
+ The algorithm used to decode Base64-encoded data is defined in \l{RFC 4648}.
+
+ \sa toBase64()
+*/
+QByteArray QByteArray::fromBase64(const QByteArray &base64)
+{
+ return fromBase64(base64, Base64Encoding);
+}
+
+/*!
+ \since 5.2
+ \overload
+
+ Returns a decoded copy of the Base64 array \a base64, using the alphabet
+ defined by \a options. Input is not checked for validity; invalid
+ characters in the input are skipped, enabling the decoding process to
+ continue with subsequent characters.
+
+ For example:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 44bis
+
+ The algorithm used to decode Base64-encoded data is defined in \l{RFC 4648}.
+
+ \sa toBase64()
+*/
+QByteArray QByteArray::fromBase64(const QByteArray &base64, Base64Options options)
+{
+ unsigned int buf = 0;
+ int nbits = 0;
+ QByteArray tmp((base64.size() * 3) / 4, Qt::Uninitialized);
+
+ int offset = 0;
+ for (int i = 0; i < base64.size(); ++i) {
+ int ch = base64.at(i);
+ int d;
+
+ if (ch >= 'A' && ch <= 'Z')
+ d = ch - 'A';
+ else if (ch >= 'a' && ch <= 'z')
+ d = ch - 'a' + 26;
+ else if (ch >= '0' && ch <= '9')
+ d = ch - '0' + 52;
+ else if (ch == '+' && (options & Base64UrlEncoding) == 0)
+ d = 62;
+ else if (ch == '-' && (options & Base64UrlEncoding) != 0)
+ d = 62;
+ else if (ch == '/' && (options & Base64UrlEncoding) == 0)
+ d = 63;
+ else if (ch == '_' && (options & Base64UrlEncoding) != 0)
+ d = 63;
+ else
+ d = -1;
+
+ if (d != -1) {
+ buf = (buf << 6) | d;
+ nbits += 6;
+ if (nbits >= 8) {
+ nbits -= 8;
+ tmp[offset++] = buf >> nbits;
+ buf &= (1 << nbits) - 1;
+ }
+ }
+ }
+
+ tmp.truncate(offset);
+ return tmp;
+}
+
+/*!
+ Returns a decoded copy of the hex encoded array \a hexEncoded. Input is not checked
+ for validity; invalid characters in the input are skipped, enabling the
+ decoding process to continue with subsequent characters.
+
+ For example:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 45
+
+ \sa toHex()
+*/
+QByteArray QByteArray::fromHex(const QByteArray &hexEncoded)
+{
+ QByteArray res((hexEncoded.size() + 1)/ 2, Qt::Uninitialized);
+ uchar *result = (uchar *)res.data() + res.size();
+
+ bool odd_digit = true;
+ for (int i = hexEncoded.size() - 1; i >= 0; --i) {
+ uchar ch = uchar(hexEncoded.at(i));
+ int tmp = QtMiscUtils::fromHex(ch);
+ if (tmp == -1)
+ continue;
+ if (odd_digit) {
+ --result;
+ *result = tmp;
+ odd_digit = false;
+ } else {
+ *result |= tmp << 4;
+ odd_digit = true;
+ }
+ }
+
+ res.remove(0, result - (const uchar *)res.constData());
+ return res;
+}
+
+/*!
+ Returns a hex encoded copy of the byte array. The hex encoding uses the numbers 0-9 and
+ the letters a-f.
+
+ \sa fromHex()
+*/
+QByteArray QByteArray::toHex() const
+{
+ return toHex('\0');
+}
+
+/*! \overload
+ \since 5.9
+
+ Returns a hex encoded copy of the byte array. The hex encoding uses the numbers 0-9 and
+ the letters a-f.
+
+ If \a separator is not '\0', the separator character is inserted between the hex bytes.
+
+ Example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 50
+
+ \sa fromHex()
+*/
+QByteArray QByteArray::toHex(char separator) const
+{
+ if (!d->size)
+ return QByteArray();
+
+ const int length = separator ? (d->size * 3 - 1) : (d->size * 2);
+ QByteArray hex(length, Qt::Uninitialized);
+ char *hexData = hex.data();
+ const uchar *data = (const uchar *)d->data();
+ for (int i = 0, o = 0; i < d->size; ++i) {
+ hexData[o++] = QtMiscUtils::toHexLower(data[i] >> 4);
+ hexData[o++] = QtMiscUtils::toHexLower(data[i] & 0xf);
+
+ if ((separator) && (o < length))
+ hexData[o++] = separator;
+ }
+ return hex;
+}
+
+static void q_fromPercentEncoding(QByteArray *ba, char percent)
+{
+ if (ba->isEmpty())
+ return;
+
+ char *data = ba->data();
+ const char *inputPtr = data;
+
+ int i = 0;
+ int len = ba->count();
+ int outlen = 0;
+ int a, b;
+ char c;
+ while (i < len) {
+ c = inputPtr[i];
+ if (c == percent && i + 2 < len) {
+ a = inputPtr[++i];
+ b = inputPtr[++i];
+
+ if (a >= '0' && a <= '9') a -= '0';
+ else if (a >= 'a' && a <= 'f') a = a - 'a' + 10;
+ else if (a >= 'A' && a <= 'F') a = a - 'A' + 10;
+
+ if (b >= '0' && b <= '9') b -= '0';
+ else if (b >= 'a' && b <= 'f') b = b - 'a' + 10;
+ else if (b >= 'A' && b <= 'F') b = b - 'A' + 10;
+
+ *data++ = (char)((a << 4) | b);
+ } else {
+ *data++ = c;
+ }
+
+ ++i;
+ ++outlen;
+ }
+
+ if (outlen != len)
+ ba->truncate(outlen);
+}
+
+void q_fromPercentEncoding(QByteArray *ba)
+{
+ q_fromPercentEncoding(ba, '%');
+}
+
+/*!
+ \since 4.4
+
+ Returns a decoded copy of the URI/URL-style percent-encoded \a input.
+ The \a percent parameter allows you to replace the '%' character for
+ another (for instance, '_' or '=').
+
+ For example:
+ \snippet code/src_corelib_tools_qbytearray.cpp 51
+
+ \note Given invalid input (such as a string containing the sequence "%G5",
+ which is not a valid hexadecimal number) the output will be invalid as
+ well. As an example: the sequence "%G5" could be decoded to 'W'.
+
+ \sa toPercentEncoding(), QUrl::fromPercentEncoding()
+*/
+QByteArray QByteArray::fromPercentEncoding(const QByteArray &input, char percent)
+{
+ if (input.isNull())
+ return QByteArray(); // preserve null
+ if (input.isEmpty())
+ return QByteArray(input.data(), 0);
+
+ QByteArray tmp = input;
+ q_fromPercentEncoding(&tmp, percent);
+ return tmp;
+}
+
+/*! \fn QByteArray QByteArray::fromStdString(const std::string &str)
+ \since 5.4
+
+ Returns a copy of the \a str string as a QByteArray.
+
+ \sa toStdString(), QString::fromStdString()
+*/
+
+/*!
+ \fn std::string QByteArray::toStdString() const
+ \since 5.4
+
+ Returns a std::string object with the data contained in this
+ QByteArray.
+
+ This operator is mostly useful to pass a QByteArray to a function
+ that accepts a std::string object.
+
+ \sa fromStdString(), QString::toStdString()
+*/
+
+static inline bool q_strchr(const char str[], char chr)
+{
+ if (!str) return false;
+
+ const char *ptr = str;
+ char c;
+ while ((c = *ptr++))
+ if (c == chr)
+ return true;
+ return false;
+}
+
+static void q_toPercentEncoding(QByteArray *ba, const char *dontEncode, const char *alsoEncode, char percent)
+{
+ if (ba->isEmpty())
+ return;
+
+ QByteArray input = *ba;
+ int len = input.count();
+ const char *inputData = input.constData();
+ char *output = nullptr;
+ int length = 0;
+
+ for (int i = 0; i < len; ++i) {
+ unsigned char c = *inputData++;
+ if (((c >= 0x61 && c <= 0x7A) // ALPHA
+ || (c >= 0x41 && c <= 0x5A) // ALPHA
+ || (c >= 0x30 && c <= 0x39) // DIGIT
+ || c == 0x2D // -
+ || c == 0x2E // .
+ || c == 0x5F // _
+ || c == 0x7E // ~
+ || q_strchr(dontEncode, c))
+ && !q_strchr(alsoEncode, c)) {
+ if (output)
+ output[length] = c;
+ ++length;
+ } else {
+ if (!output) {
+ // detach now
+ ba->resize(len*3); // worst case
+ output = ba->data();
+ }
+ output[length++] = percent;
+ output[length++] = QtMiscUtils::toHexUpper((c & 0xf0) >> 4);
+ output[length++] = QtMiscUtils::toHexUpper(c & 0xf);
+ }
+ }
+ if (output)
+ ba->truncate(length);
+}
+
+void q_toPercentEncoding(QByteArray *ba, const char *exclude, const char *include)
+{
+ q_toPercentEncoding(ba, exclude, include, '%');
+}
+
+void q_normalizePercentEncoding(QByteArray *ba, const char *exclude)
+{
+ q_fromPercentEncoding(ba, '%');
+ q_toPercentEncoding(ba, exclude, nullptr, '%');
+}
+
+/*!
+ \since 4.4
+
+ Returns a URI/URL-style percent-encoded copy of this byte array. The
+ \a percent parameter allows you to override the default '%'
+ character for another.
+
+ By default, this function will encode all characters that are not
+ one of the following:
+
+ ALPHA ("a" to "z" and "A" to "Z") / DIGIT (0 to 9) / "-" / "." / "_" / "~"
+
+ To prevent characters from being encoded pass them to \a
+ exclude. To force characters to be encoded pass them to \a
+ include. The \a percent character is always encoded.
+
+ Example:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 52
+
+ The hex encoding uses the numbers 0-9 and the uppercase letters A-F.
+
+ \sa fromPercentEncoding(), QUrl::toPercentEncoding()
+*/
+QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteArray &include,
+ char percent) const
+{
+ if (isNull())
+ return QByteArray(); // preserve null
+ if (isEmpty())
+ return QByteArray(data(), 0);
+
+ QByteArray include2 = include;
+ if (percent != '%') // the default
+ if ((percent >= 0x61 && percent <= 0x7A) // ALPHA
+ || (percent >= 0x41 && percent <= 0x5A) // ALPHA
+ || (percent >= 0x30 && percent <= 0x39) // DIGIT
+ || percent == 0x2D // -
+ || percent == 0x2E // .
+ || percent == 0x5F // _
+ || percent == 0x7E) // ~
+ include2 += percent;
+
+ QByteArray result = *this;
+ q_toPercentEncoding(&result, exclude.nulTerminated().constData(), include2.nulTerminated().constData(), percent);
+
+ return result;
+}
+
+/*! \typedef QByteArray::ConstIterator
+ \internal
+*/
+
+/*! \typedef QByteArray::Iterator
+ \internal
+*/
+
+/*! \typedef QByteArray::const_iterator
+
+ This typedef provides an STL-style const iterator for QByteArray.
+
+ \sa QByteArray::const_reverse_iterator, QByteArray::iterator
+*/
+
+/*! \typedef QByteArray::iterator
+
+ This typedef provides an STL-style non-const iterator for QByteArray.
+
+ \sa QByteArray::reverse_iterator, QByteArray::const_iterator
+*/
+
+/*! \typedef QByteArray::const_reverse_iterator
+ \since 5.6
+
+ This typedef provides an STL-style const reverse iterator for QByteArray.
+
+ \sa QByteArray::reverse_iterator, QByteArray::const_iterator
+*/
+
+/*! \typedef QByteArray::reverse_iterator
+ \since 5.6
+
+ This typedef provides an STL-style non-const reverse iterator for QByteArray.
+
+ \sa QByteArray::const_reverse_iterator, QByteArray::iterator
+*/
+
+/*! \typedef QByteArray::size_type
+ \internal
+*/
+
+/*! \typedef QByteArray::difference_type
+ \internal
+*/
+
+/*! \typedef QByteArray::const_reference
+ \internal
+*/
+
+/*! \typedef QByteArray::reference
+ \internal
+*/
+
+/*! \typedef QByteArray::const_pointer
+ \internal
+*/
+
+/*! \typedef QByteArray::pointer
+ \internal
+*/
+
+/*! \typedef QByteArray::value_type
+ \internal
+ */
+
+/*!
+ \fn DataPtr &QByteArray::data_ptr()
+ \internal
+*/
+
+/*!
+ \typedef QByteArray::DataPtr
+ \internal
+*/
+
+/*!
+ \macro QByteArrayLiteral(ba)
+ \relates QByteArray
+
+ The macro generates the data for a QByteArray out of the string literal
+ \a ba at compile time. Creating a QByteArray from it is free in this case, and
+ the generated byte array data is stored in the read-only segment of the
+ compiled object file.
+
+ For instance:
+
+ \snippet code/src_corelib_tools_qbytearray.cpp 53
+
+ Using QByteArrayLiteral instead of a double quoted plain C++ string literal
+ can significantly speed up creation of QByteArray instances from data known
+ at compile time.
+
+ \sa QStringLiteral
+*/
+
+namespace QtPrivate {
+namespace DeprecatedRefClassBehavior {
+void warn(WarningType w, EmittingClass c)
+{
+ static const char deprecatedBehaviorString[] =
+ "The corresponding behavior is deprecated, and will be changed"
+ " in a future version of Qt.";
+
+ const char *emittingClassName = nullptr;
+ const char *containerClassName = nullptr;
+
+ switch (c) {
+ case EmittingClass::QByteRef:
+ emittingClassName = "QByteRef";
+ containerClassName = "QByteArray";
+ break;
+ case EmittingClass::QCharRef:
+ emittingClassName = "QCharRef";
+ containerClassName = "QString";
+ break;
+ }
+
+ switch (w) {
+ case WarningType::OutOfRange:
+ qWarning("Using %s with an index pointing outside the valid range of a %s. %s",
+ emittingClassName, containerClassName, deprecatedBehaviorString);
+ break;
+ case WarningType::DelayedDetach:
+ qWarning("Using %s with on a %s that is not already detached. %s",
+ emittingClassName, containerClassName, deprecatedBehaviorString);
+ break;
+ }
+}
+} // namespace DeprecatedRefClassBehavior
+} // namespace QtPrivate
+
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h
new file mode 100644
index 0000000000..7c571706d8
--- /dev/null
+++ b/src/corelib/text/qbytearray.h
@@ -0,0 +1,754 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2016 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBYTEARRAY_H
+#define QBYTEARRAY_H
+
+#include <QtCore/qrefcount.h>
+#include <QtCore/qnamespace.h>
+#include <QtCore/qarraydata.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <string>
+#include <iterator>
+
+#ifdef truncate
+#error qbytearray.h must be included before any header file that defines truncate
+#endif
+
+#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
+Q_FORWARD_DECLARE_CF_TYPE(CFData);
+Q_FORWARD_DECLARE_OBJC_CLASS(NSData);
+#endif
+
+QT_BEGIN_NAMESPACE
+
+
+/*****************************************************************************
+ Safe and portable C string functions; extensions to standard string.h
+ *****************************************************************************/
+
+Q_CORE_EXPORT char *qstrdup(const char *);
+
+inline uint qstrlen(const char *str)
+{ return str ? uint(strlen(str)) : 0; }
+
+inline uint qstrnlen(const char *str, uint maxlen)
+{
+ uint length = 0;
+ if (str) {
+ while (length < maxlen && *str++)
+ length++;
+ }
+ return length;
+}
+
+Q_CORE_EXPORT char *qstrcpy(char *dst, const char *src);
+Q_CORE_EXPORT char *qstrncpy(char *dst, const char *src, uint len);
+
+Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2);
+Q_CORE_EXPORT int qstrcmp(const QByteArray &str1, const QByteArray &str2);
+Q_CORE_EXPORT int qstrcmp(const QByteArray &str1, const char *str2);
+static inline int qstrcmp(const char *str1, const QByteArray &str2)
+{ return -qstrcmp(str2, str1); }
+
+inline int qstrncmp(const char *str1, const char *str2, uint len)
+{
+ return (str1 && str2) ? strncmp(str1, str2, len)
+ : (str1 ? 1 : (str2 ? -1 : 0));
+}
+Q_CORE_EXPORT int qstricmp(const char *, const char *);
+Q_CORE_EXPORT int qstrnicmp(const char *, const char *, uint len);
+Q_CORE_EXPORT int qstrnicmp(const char *, qsizetype, const char *, qsizetype = -1);
+
+// implemented in qvsnprintf.cpp
+Q_CORE_EXPORT int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap);
+Q_CORE_EXPORT int qsnprintf(char *str, size_t n, const char *fmt, ...);
+
+// qChecksum: Internet checksum
+Q_CORE_EXPORT quint16 qChecksum(const char *s, uint len); // ### Qt 6: Remove
+Q_CORE_EXPORT quint16 qChecksum(const char *s, uint len, Qt::ChecksumType standard); // ### Qt 6: Use Qt::ChecksumType standard = Qt::ChecksumIso3309
+
+class QByteRef;
+class QString;
+class QDataStream;
+template <typename T> class QList;
+
+typedef QArrayData QByteArrayData;
+
+template<int N> struct QStaticByteArrayData
+{
+ QByteArrayData ba;
+ char data[N + 1];
+
+ QByteArrayData *data_ptr() const
+ {
+ Q_ASSERT(ba.ref.isStatic());
+ return const_cast<QByteArrayData *>(&ba);
+ }
+};
+
+struct QByteArrayDataPtr
+{
+ QByteArrayData *ptr;
+};
+
+#define Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset) \
+ Q_STATIC_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, offset)
+ /**/
+
+#define Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(size) \
+ Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(size, sizeof(QByteArrayData)) \
+ /**/
+
+# define QByteArrayLiteral(str) \
+ ([]() -> QByteArray { \
+ enum { Size = sizeof(str) - 1 }; \
+ static const QStaticByteArrayData<Size> qbytearray_literal = { \
+ Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER(Size), \
+ str }; \
+ QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; \
+ const QByteArray ba(holder); \
+ return ba; \
+ }()) \
+ /**/
+
+class Q_CORE_EXPORT QByteArray
+{
+private:
+ typedef QTypedArrayData<char> Data;
+
+public:
+ enum Base64Option {
+ Base64Encoding = 0,
+ Base64UrlEncoding = 1,
+
+ KeepTrailingEquals = 0,
+ OmitTrailingEquals = 2
+ };
+ Q_DECLARE_FLAGS(Base64Options, Base64Option)
+
+ inline QByteArray() noexcept;
+ QByteArray(const char *, int size = -1);
+ QByteArray(int size, char c);
+ QByteArray(int size, Qt::Initialization);
+ inline QByteArray(const QByteArray &) noexcept;
+ inline ~QByteArray();
+
+ QByteArray &operator=(const QByteArray &) noexcept;
+ QByteArray &operator=(const char *str);
+ inline QByteArray(QByteArray && other) noexcept : d(other.d) { other.d = Data::sharedNull(); }
+ inline QByteArray &operator=(QByteArray &&other) noexcept
+ { qSwap(d, other.d); return *this; }
+
+ inline void swap(QByteArray &other) noexcept
+ { qSwap(d, other.d); }
+
+ inline int size() const;
+ inline bool isEmpty() const;
+ void resize(int size);
+
+ QByteArray &fill(char c, int size = -1);
+
+ inline int capacity() const;
+ inline void reserve(int size);
+ inline void squeeze();
+
+#ifndef QT_NO_CAST_FROM_BYTEARRAY
+ inline operator const char *() const;
+ inline operator const void *() const;
+#endif
+ inline char *data();
+ inline const char *data() const;
+ inline const char *constData() const;
+ inline void detach();
+ inline bool isDetached() const;
+ inline bool isSharedWith(const QByteArray &other) const { return d == other.d; }
+ void clear();
+
+ inline char at(int i) const;
+ inline char operator[](int i) const;
+ inline char operator[](uint i) const;
+ Q_REQUIRED_RESULT inline QByteRef operator[](int i);
+ Q_REQUIRED_RESULT inline QByteRef operator[](uint i);
+ Q_REQUIRED_RESULT char front() const { return at(0); }
+ Q_REQUIRED_RESULT inline QByteRef front();
+ Q_REQUIRED_RESULT char back() const { return at(size() - 1); }
+ Q_REQUIRED_RESULT inline QByteRef back();
+
+ int indexOf(char c, int from = 0) const;
+ int indexOf(const char *c, int from = 0) const;
+ int indexOf(const QByteArray &a, int from = 0) const;
+ int lastIndexOf(char c, int from = -1) const;
+ int lastIndexOf(const char *c, int from = -1) const;
+ int lastIndexOf(const QByteArray &a, int from = -1) const;
+
+ inline bool contains(char c) const;
+ inline bool contains(const char *a) const;
+ inline bool contains(const QByteArray &a) const;
+ int count(char c) const;
+ int count(const char *a) const;
+ int count(const QByteArray &a) const;
+
+ inline int compare(const char *c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+ inline int compare(const QByteArray &a, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
+
+ Q_REQUIRED_RESULT QByteArray left(int len) const;
+ Q_REQUIRED_RESULT QByteArray right(int len) const;
+ Q_REQUIRED_RESULT QByteArray mid(int index, int len = -1) const;
+ Q_REQUIRED_RESULT QByteArray chopped(int len) const
+ { Q_ASSERT(len >= 0); Q_ASSERT(len <= size()); return left(size() - len); }
+
+ bool startsWith(const QByteArray &a) const;
+ bool startsWith(char c) const;
+ bool startsWith(const char *c) const;
+
+ bool endsWith(const QByteArray &a) const;
+ bool endsWith(char c) const;
+ bool endsWith(const char *c) const;
+
+ bool isUpper() const;
+ bool isLower() const;
+
+ void truncate(int pos);
+ void chop(int n);
+
+#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP) && !defined(Q_CLANG_QDOC)
+# if defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && !defined(Q_CC_INTEL) && !QT_HAS_CPP_ATTRIBUTE(nodiscard)
+ // required due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61941
+# pragma push_macro("Q_REQUIRED_RESULT")
+# undef Q_REQUIRED_RESULT
+# define Q_REQUIRED_RESULT
+# define Q_REQUIRED_RESULT_pushed
+# endif
+ Q_REQUIRED_RESULT QByteArray toLower() const &
+ { return toLower_helper(*this); }
+ Q_REQUIRED_RESULT QByteArray toLower() &&
+ { return toLower_helper(*this); }
+ Q_REQUIRED_RESULT QByteArray toUpper() const &
+ { return toUpper_helper(*this); }
+ Q_REQUIRED_RESULT QByteArray toUpper() &&
+ { return toUpper_helper(*this); }
+ Q_REQUIRED_RESULT QByteArray trimmed() const &
+ { return trimmed_helper(*this); }
+ Q_REQUIRED_RESULT QByteArray trimmed() &&
+ { return trimmed_helper(*this); }
+ Q_REQUIRED_RESULT QByteArray simplified() const &
+ { return simplified_helper(*this); }
+ Q_REQUIRED_RESULT QByteArray simplified() &&
+ { return simplified_helper(*this); }
+# ifdef Q_REQUIRED_RESULT_pushed
+# pragma pop_macro("Q_REQUIRED_RESULT")
+# endif
+#else
+ Q_REQUIRED_RESULT QByteArray toLower() const;
+ Q_REQUIRED_RESULT QByteArray toUpper() const;
+ Q_REQUIRED_RESULT QByteArray trimmed() const;
+ Q_REQUIRED_RESULT QByteArray simplified() const;
+#endif
+
+ Q_REQUIRED_RESULT QByteArray leftJustified(int width, char fill = ' ', bool truncate = false) const;
+ Q_REQUIRED_RESULT QByteArray rightJustified(int width, char fill = ' ', bool truncate = false) const;
+
+ QByteArray &prepend(char c);
+ inline QByteArray &prepend(int count, char c);
+ QByteArray &prepend(const char *s);
+ QByteArray &prepend(const char *s, int len);
+ QByteArray &prepend(const QByteArray &a);
+ QByteArray &append(char c);
+ inline QByteArray &append(int count, char c);
+ QByteArray &append(const char *s);
+ QByteArray &append(const char *s, int len);
+ QByteArray &append(const QByteArray &a);
+ QByteArray &insert(int i, char c);
+ QByteArray &insert(int i, int count, char c);
+ QByteArray &insert(int i, const char *s);
+ QByteArray &insert(int i, const char *s, int len);
+ QByteArray &insert(int i, const QByteArray &a);
+ QByteArray &remove(int index, int len);
+ QByteArray &replace(int index, int len, const char *s);
+ QByteArray &replace(int index, int len, const char *s, int alen);
+ QByteArray &replace(int index, int len, const QByteArray &s);
+ inline QByteArray &replace(char before, const char *after);
+ QByteArray &replace(char before, const QByteArray &after);
+ inline QByteArray &replace(const char *before, const char *after);
+ QByteArray &replace(const char *before, int bsize, const char *after, int asize);
+ QByteArray &replace(const QByteArray &before, const QByteArray &after);
+ inline QByteArray &replace(const QByteArray &before, const char *after);
+ QByteArray &replace(const char *before, const QByteArray &after);
+ QByteArray &replace(char before, char after);
+ inline QByteArray &operator+=(char c);
+ inline QByteArray &operator+=(const char *s);
+ inline QByteArray &operator+=(const QByteArray &a);
+
+ QList<QByteArray> split(char sep) const;
+
+ Q_REQUIRED_RESULT QByteArray repeated(int times) const;
+
+#ifndef QT_NO_CAST_TO_ASCII
+ QT_ASCII_CAST_WARN QByteArray &append(const QString &s);
+ QT_ASCII_CAST_WARN QByteArray &insert(int i, const QString &s);
+ QT_ASCII_CAST_WARN QByteArray &replace(const QString &before, const char *after);
+ QT_ASCII_CAST_WARN QByteArray &replace(char c, const QString &after);
+ QT_ASCII_CAST_WARN QByteArray &replace(const QString &before, const QByteArray &after);
+
+ QT_ASCII_CAST_WARN QByteArray &operator+=(const QString &s);
+ QT_ASCII_CAST_WARN int indexOf(const QString &s, int from = 0) const;
+ QT_ASCII_CAST_WARN int lastIndexOf(const QString &s, int from = -1) const;
+#endif
+#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
+ inline QT_ASCII_CAST_WARN bool operator==(const QString &s2) const;
+ inline QT_ASCII_CAST_WARN bool operator!=(const QString &s2) const;
+ inline QT_ASCII_CAST_WARN bool operator<(const QString &s2) const;
+ inline QT_ASCII_CAST_WARN bool operator>(const QString &s2) const;
+ inline QT_ASCII_CAST_WARN bool operator<=(const QString &s2) const;
+ inline QT_ASCII_CAST_WARN bool operator>=(const QString &s2) const;
+#endif
+
+ short toShort(bool *ok = nullptr, int base = 10) const;
+ ushort toUShort(bool *ok = nullptr, int base = 10) const;
+ int toInt(bool *ok = nullptr, int base = 10) const;
+ uint toUInt(bool *ok = nullptr, int base = 10) const;
+ long toLong(bool *ok = nullptr, int base = 10) const;
+ ulong toULong(bool *ok = nullptr, int base = 10) const;
+ qlonglong toLongLong(bool *ok = nullptr, int base = 10) const;
+ qulonglong toULongLong(bool *ok = nullptr, int base = 10) const;
+ float toFloat(bool *ok = nullptr) const;
+ double toDouble(bool *ok = nullptr) const;
+ QByteArray toBase64(Base64Options options) const;
+ QByteArray toBase64() const; // ### Qt6 merge with previous
+ QByteArray toHex() const;
+ QByteArray toHex(char separator) const; // ### Qt6 merge with previous
+ QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
+ const QByteArray &include = QByteArray(),
+ char percent = '%') const;
+
+ inline QByteArray &setNum(short, int base = 10);
+ inline QByteArray &setNum(ushort, int base = 10);
+ inline QByteArray &setNum(int, int base = 10);
+ inline QByteArray &setNum(uint, int base = 10);
+ QByteArray &setNum(qlonglong, int base = 10);
+ QByteArray &setNum(qulonglong, int base = 10);
+ inline QByteArray &setNum(float, char f = 'g', int prec = 6);
+ QByteArray &setNum(double, char f = 'g', int prec = 6);
+ QByteArray &setRawData(const char *a, uint n); // ### Qt 6: use an int
+
+ Q_REQUIRED_RESULT static QByteArray number(int, int base = 10);
+ Q_REQUIRED_RESULT static QByteArray number(uint, int base = 10);
+ Q_REQUIRED_RESULT static QByteArray number(qlonglong, int base = 10);
+ Q_REQUIRED_RESULT static QByteArray number(qulonglong, int base = 10);
+ Q_REQUIRED_RESULT static QByteArray number(double, char f = 'g', int prec = 6);
+ Q_REQUIRED_RESULT static QByteArray fromRawData(const char *, int size);
+ Q_REQUIRED_RESULT static QByteArray fromBase64(const QByteArray &base64, Base64Options options);
+ Q_REQUIRED_RESULT static QByteArray fromBase64(const QByteArray &base64); // ### Qt6 merge with previous
+ Q_REQUIRED_RESULT static QByteArray fromHex(const QByteArray &hexEncoded);
+ Q_REQUIRED_RESULT static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
+
+#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
+ static QByteArray fromCFData(CFDataRef data);
+ static QByteArray fromRawCFData(CFDataRef data);
+ CFDataRef toCFData() const Q_DECL_CF_RETURNS_RETAINED;
+ CFDataRef toRawCFData() const Q_DECL_CF_RETURNS_RETAINED;
+ static QByteArray fromNSData(const NSData *data);
+ static QByteArray fromRawNSData(const NSData *data);
+ NSData *toNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
+ NSData *toRawNSData() const Q_DECL_NS_RETURNS_AUTORELEASED;
+#endif
+
+ typedef char *iterator;
+ typedef const char *const_iterator;
+ typedef iterator Iterator;
+ typedef const_iterator ConstIterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ inline iterator begin();
+ inline const_iterator begin() const;
+ inline const_iterator cbegin() const;
+ inline const_iterator constBegin() const;
+ inline iterator end();
+ inline const_iterator end() const;
+ inline const_iterator cend() const;
+ inline const_iterator constEnd() const;
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+ const_reverse_iterator crbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator crend() const { return const_reverse_iterator(begin()); }
+
+ // stl compatibility
+ typedef int size_type;
+ typedef qptrdiff difference_type;
+ typedef const char & const_reference;
+ typedef char & reference;
+ typedef char *pointer;
+ typedef const char *const_pointer;
+ typedef char value_type;
+ inline void push_back(char c);
+ inline void push_back(const char *c);
+ inline void push_back(const QByteArray &a);
+ inline void push_front(char c);
+ inline void push_front(const char *c);
+ inline void push_front(const QByteArray &a);
+ void shrink_to_fit() { squeeze(); }
+
+ static inline QByteArray fromStdString(const std::string &s);
+ inline std::string toStdString() const;
+
+ inline int count() const { return d->size; }
+ int length() const { return d->size; }
+ bool isNull() const;
+
+ inline QByteArray(QByteArrayDataPtr dd)
+ : d(static_cast<Data *>(dd.ptr))
+ {
+ }
+
+private:
+ operator QNoImplicitBoolCast() const;
+ Data *d;
+ void reallocData(uint alloc, Data::AllocationOptions options);
+ void expand(int i);
+ QByteArray nulTerminated() const;
+
+ static QByteArray toLower_helper(const QByteArray &a);
+ static QByteArray toLower_helper(QByteArray &a);
+ static QByteArray toUpper_helper(const QByteArray &a);
+ static QByteArray toUpper_helper(QByteArray &a);
+ static QByteArray trimmed_helper(const QByteArray &a);
+ static QByteArray trimmed_helper(QByteArray &a);
+ static QByteArray simplified_helper(const QByteArray &a);
+ static QByteArray simplified_helper(QByteArray &a);
+
+ friend class QByteRef;
+ friend class QString;
+ friend Q_CORE_EXPORT QByteArray qUncompress(const uchar *data, int nbytes);
+public:
+ typedef Data * DataPtr;
+ inline DataPtr &data_ptr() { return d; }
+};
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(QByteArray::Base64Options)
+
+inline QByteArray::QByteArray() noexcept : d(Data::sharedNull()) { }
+inline QByteArray::~QByteArray() { if (!d->ref.deref()) Data::deallocate(d); }
+inline int QByteArray::size() const
+{ return d->size; }
+
+inline char QByteArray::at(int i) const
+{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; }
+inline char QByteArray::operator[](int i) const
+{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; }
+inline char QByteArray::operator[](uint i) const
+{ Q_ASSERT(i < uint(size())); return d->data()[i]; }
+
+inline bool QByteArray::isEmpty() const
+{ return d->size == 0; }
+#ifndef QT_NO_CAST_FROM_BYTEARRAY
+inline QByteArray::operator const char *() const
+{ return d->data(); }
+inline QByteArray::operator const void *() const
+{ return d->data(); }
+#endif
+inline char *QByteArray::data()
+{ detach(); return d->data(); }
+inline const char *QByteArray::data() const
+{ return d->data(); }
+inline const char *QByteArray::constData() const
+{ return d->data(); }
+inline void QByteArray::detach()
+{ if (d->ref.isShared() || (d->offset != sizeof(QByteArrayData))) reallocData(uint(d->size) + 1u, d->detachFlags()); }
+inline bool QByteArray::isDetached() const
+{ return !d->ref.isShared(); }
+inline QByteArray::QByteArray(const QByteArray &a) noexcept : d(a.d)
+{ d->ref.ref(); }
+
+inline int QByteArray::capacity() const
+{ return d->alloc ? d->alloc - 1 : 0; }
+
+inline void QByteArray::reserve(int asize)
+{
+ if (d->ref.isShared() || uint(asize) + 1u > d->alloc) {
+ reallocData(qMax(uint(size()), uint(asize)) + 1u, d->detachFlags() | Data::CapacityReserved);
+ } else {
+ // cannot set unconditionally, since d could be the shared_null or
+ // otherwise static
+ d->capacityReserved = true;
+ }
+}
+
+inline void QByteArray::squeeze()
+{
+ if (d->ref.isShared() || uint(d->size) + 1u < d->alloc) {
+ reallocData(uint(d->size) + 1u, d->detachFlags() & ~Data::CapacityReserved);
+ } else {
+ // cannot set unconditionally, since d could be shared_null or
+ // otherwise static.
+ d->capacityReserved = false;
+ }
+}
+
+namespace QtPrivate {
+namespace DeprecatedRefClassBehavior {
+ enum class EmittingClass {
+ QByteRef,
+ QCharRef,
+ };
+
+ enum class WarningType {
+ OutOfRange,
+ DelayedDetach,
+ };
+
+ Q_CORE_EXPORT Q_DECL_COLD_FUNCTION void warn(WarningType w, EmittingClass c);
+} // namespace DeprecatedAssignmentOperatorBehavior
+} // namespace QtPrivate
+
+class
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+Q_CORE_EXPORT
+#endif
+QByteRef { // ### Qt 7: remove
+ QByteArray &a;
+ int i;
+ inline QByteRef(QByteArray &array, int idx)
+ : a(array),i(idx) {}
+ friend class QByteArray;
+public:
+ inline operator char() const
+ {
+ using namespace QtPrivate::DeprecatedRefClassBehavior;
+ if (Q_LIKELY(i < a.d->size))
+ return a.d->data()[i];
+#ifdef QT_DEBUG
+ warn(WarningType::OutOfRange, EmittingClass::QByteRef);
+#endif
+ return char(0);
+ }
+ inline QByteRef &operator=(char c)
+ {
+ using namespace QtPrivate::DeprecatedRefClassBehavior;
+ if (Q_UNLIKELY(i >= a.d->size)) {
+#ifdef QT_DEBUG
+ warn(WarningType::OutOfRange, EmittingClass::QByteRef);
+#endif
+ a.expand(i);
+ } else {
+#ifdef QT_DEBUG
+ if (Q_UNLIKELY(!a.isDetached()))
+ warn(WarningType::DelayedDetach, EmittingClass::QByteRef);
+#endif
+ a.detach();
+ }
+ a.d->data()[i] = c;
+ return *this;
+ }
+ inline QByteRef &operator=(const QByteRef &c)
+ {
+ return operator=(char(c));
+ }
+ inline bool operator==(char c) const
+ { return a.d->data()[i] == c; }
+ inline bool operator!=(char c) const
+ { return a.d->data()[i] != c; }
+ inline bool operator>(char c) const
+ { return a.d->data()[i] > c; }
+ inline bool operator>=(char c) const
+ { return a.d->data()[i] >= c; }
+ inline bool operator<(char c) const
+ { return a.d->data()[i] < c; }
+ inline bool operator<=(char c) const
+ { return a.d->data()[i] <= c; }
+};
+
+inline QByteRef QByteArray::operator[](int i)
+{ Q_ASSERT(i >= 0); detach(); return QByteRef(*this, i); }
+inline QByteRef QByteArray::operator[](uint i)
+{ detach(); return QByteRef(*this, i); }
+inline QByteRef QByteArray::front() { return operator[](0); }
+inline QByteRef QByteArray::back() { return operator[](size() - 1); }
+inline QByteArray::iterator QByteArray::begin()
+{ detach(); return d->data(); }
+inline QByteArray::const_iterator QByteArray::begin() const
+{ return d->data(); }
+inline QByteArray::const_iterator QByteArray::cbegin() const
+{ return d->data(); }
+inline QByteArray::const_iterator QByteArray::constBegin() const
+{ return d->data(); }
+inline QByteArray::iterator QByteArray::end()
+{ detach(); return d->data() + d->size; }
+inline QByteArray::const_iterator QByteArray::end() const
+{ return d->data() + d->size; }
+inline QByteArray::const_iterator QByteArray::cend() const
+{ return d->data() + d->size; }
+inline QByteArray::const_iterator QByteArray::constEnd() const
+{ return d->data() + d->size; }
+inline QByteArray &QByteArray::append(int n, char ch)
+{ return insert(d->size, n, ch); }
+inline QByteArray &QByteArray::prepend(int n, char ch)
+{ return insert(0, n, ch); }
+inline QByteArray &QByteArray::operator+=(char c)
+{ return append(c); }
+inline QByteArray &QByteArray::operator+=(const char *s)
+{ return append(s); }
+inline QByteArray &QByteArray::operator+=(const QByteArray &a)
+{ return append(a); }
+inline void QByteArray::push_back(char c)
+{ append(c); }
+inline void QByteArray::push_back(const char *c)
+{ append(c); }
+inline void QByteArray::push_back(const QByteArray &a)
+{ append(a); }
+inline void QByteArray::push_front(char c)
+{ prepend(c); }
+inline void QByteArray::push_front(const char *c)
+{ prepend(c); }
+inline void QByteArray::push_front(const QByteArray &a)
+{ prepend(a); }
+inline bool QByteArray::contains(const QByteArray &a) const
+{ return indexOf(a) != -1; }
+inline bool QByteArray::contains(char c) const
+{ return indexOf(c) != -1; }
+inline int QByteArray::compare(const char *c, Qt::CaseSensitivity cs) const
+{
+ return cs == Qt::CaseSensitive ? qstrcmp(*this, c) :
+ qstrnicmp(data(), size(), c, -1);
+}
+inline int QByteArray::compare(const QByteArray &a, Qt::CaseSensitivity cs) const
+{
+ return cs == Qt::CaseSensitive ? qstrcmp(*this, a) :
+ qstrnicmp(data(), size(), a.data(), a.size());
+}
+inline bool operator==(const QByteArray &a1, const QByteArray &a2) noexcept
+{ return (a1.size() == a2.size()) && (memcmp(a1.constData(), a2.constData(), a1.size())==0); }
+inline bool operator==(const QByteArray &a1, const char *a2) noexcept
+{ return a2 ? qstrcmp(a1,a2) == 0 : a1.isEmpty(); }
+inline bool operator==(const char *a1, const QByteArray &a2) noexcept
+{ return a1 ? qstrcmp(a1,a2) == 0 : a2.isEmpty(); }
+inline bool operator!=(const QByteArray &a1, const QByteArray &a2) noexcept
+{ return !(a1==a2); }
+inline bool operator!=(const QByteArray &a1, const char *a2) noexcept
+{ return a2 ? qstrcmp(a1,a2) != 0 : !a1.isEmpty(); }
+inline bool operator!=(const char *a1, const QByteArray &a2) noexcept
+{ return a1 ? qstrcmp(a1,a2) != 0 : !a2.isEmpty(); }
+inline bool operator<(const QByteArray &a1, const QByteArray &a2) noexcept
+{ return qstrcmp(a1, a2) < 0; }
+ inline bool operator<(const QByteArray &a1, const char *a2) noexcept
+{ return qstrcmp(a1, a2) < 0; }
+inline bool operator<(const char *a1, const QByteArray &a2) noexcept
+{ return qstrcmp(a1, a2) < 0; }
+inline bool operator<=(const QByteArray &a1, const QByteArray &a2) noexcept
+{ return qstrcmp(a1, a2) <= 0; }
+inline bool operator<=(const QByteArray &a1, const char *a2) noexcept
+{ return qstrcmp(a1, a2) <= 0; }
+inline bool operator<=(const char *a1, const QByteArray &a2) noexcept
+{ return qstrcmp(a1, a2) <= 0; }
+inline bool operator>(const QByteArray &a1, const QByteArray &a2) noexcept
+{ return qstrcmp(a1, a2) > 0; }
+inline bool operator>(const QByteArray &a1, const char *a2) noexcept
+{ return qstrcmp(a1, a2) > 0; }
+inline bool operator>(const char *a1, const QByteArray &a2) noexcept
+{ return qstrcmp(a1, a2) > 0; }
+inline bool operator>=(const QByteArray &a1, const QByteArray &a2) noexcept
+{ return qstrcmp(a1, a2) >= 0; }
+inline bool operator>=(const QByteArray &a1, const char *a2) noexcept
+{ return qstrcmp(a1, a2) >= 0; }
+inline bool operator>=(const char *a1, const QByteArray &a2) noexcept
+{ return qstrcmp(a1, a2) >= 0; }
+#if !defined(QT_USE_QSTRINGBUILDER)
+inline const QByteArray operator+(const QByteArray &a1, const QByteArray &a2)
+{ return QByteArray(a1) += a2; }
+inline const QByteArray operator+(const QByteArray &a1, const char *a2)
+{ return QByteArray(a1) += a2; }
+inline const QByteArray operator+(const QByteArray &a1, char a2)
+{ return QByteArray(a1) += a2; }
+inline const QByteArray operator+(const char *a1, const QByteArray &a2)
+{ return QByteArray(a1) += a2; }
+inline const QByteArray operator+(char a1, const QByteArray &a2)
+{ return QByteArray(&a1, 1) += a2; }
+#endif // QT_USE_QSTRINGBUILDER
+inline bool QByteArray::contains(const char *c) const
+{ return indexOf(c) != -1; }
+inline QByteArray &QByteArray::replace(char before, const char *c)
+{ return replace(&before, 1, c, qstrlen(c)); }
+inline QByteArray &QByteArray::replace(const QByteArray &before, const char *c)
+{ return replace(before.constData(), before.size(), c, qstrlen(c)); }
+inline QByteArray &QByteArray::replace(const char *before, const char *after)
+{ return replace(before, qstrlen(before), after, qstrlen(after)); }
+
+inline QByteArray &QByteArray::setNum(short n, int base)
+{ return base == 10 ? setNum(qlonglong(n), base) : setNum(qulonglong(ushort(n)), base); }
+inline QByteArray &QByteArray::setNum(ushort n, int base)
+{ return setNum(qulonglong(n), base); }
+inline QByteArray &QByteArray::setNum(int n, int base)
+{ return base == 10 ? setNum(qlonglong(n), base) : setNum(qulonglong(uint(n)), base); }
+inline QByteArray &QByteArray::setNum(uint n, int base)
+{ return setNum(qulonglong(n), base); }
+inline QByteArray &QByteArray::setNum(float n, char f, int prec)
+{ return setNum(double(n),f,prec); }
+
+inline std::string QByteArray::toStdString() const
+{ return std::string(constData(), length()); }
+
+inline QByteArray QByteArray::fromStdString(const std::string &s)
+{ return QByteArray(s.data(), int(s.size())); }
+
+#if !defined(QT_NO_DATASTREAM) || (defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE))
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QByteArray &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QByteArray &);
+#endif
+
+#ifndef QT_NO_COMPRESS
+Q_CORE_EXPORT QByteArray qCompress(const uchar* data, int nbytes, int compressionLevel = -1);
+Q_CORE_EXPORT QByteArray qUncompress(const uchar* data, int nbytes);
+inline QByteArray qCompress(const QByteArray& data, int compressionLevel = -1)
+{ return qCompress(reinterpret_cast<const uchar *>(data.constData()), data.size(), compressionLevel); }
+inline QByteArray qUncompress(const QByteArray& data)
+{ return qUncompress(reinterpret_cast<const uchar*>(data.constData()), data.size()); }
+#endif
+
+Q_DECLARE_SHARED(QByteArray)
+
+QT_END_NAMESPACE
+
+#endif // QBYTEARRAY_H
diff --git a/src/corelib/text/qbytearray_p.h b/src/corelib/text/qbytearray_p.h
new file mode 100644
index 0000000000..3c6257f786
--- /dev/null
+++ b/src/corelib/text/qbytearray_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBYTEARRAY_P_H
+#define QBYTEARRAY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qbytearray.h>
+#include "private/qtools_p.h"
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ // Define as enum to force inlining. Don't expose MaxAllocSize in a public header.
+ MaxByteArraySize = MaxAllocSize - sizeof(std::remove_pointer<QByteArray::DataPtr>::type)
+};
+
+QT_END_NAMESPACE
+
+#endif // QBYTEARRAY_P_H
diff --git a/src/corelib/text/qbytearraylist.cpp b/src/corelib/text/qbytearraylist.cpp
new file mode 100644
index 0000000000..d04555ed4d
--- /dev/null
+++ b/src/corelib/text/qbytearraylist.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2014 by Southwest Research Institute (R)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qbytearraylist.h>
+
+QT_BEGIN_NAMESPACE
+
+/*! \typedef QByteArrayListIterator
+ \relates QByteArrayList
+
+ The QByteArrayListIterator type definition provides a Java-style const
+ iterator for QByteArrayList.
+
+ QByteArrayList provides both \l{Java-style iterators} and
+ \l{STL-style iterators}. The Java-style const iterator is simply
+ a type definition for QListIterator<QByteArray>.
+
+ \sa QMutableByteArrayListIterator, QByteArrayList::const_iterator
+*/
+
+/*! \typedef QMutableByteArrayListIterator
+ \relates QByteArrayList
+
+ The QByteArrayListIterator type definition provides a Java-style
+ non-const iterator for QByteArrayList.
+
+ QByteArrayList provides both \l{Java-style iterators} and
+ \l{STL-style iterators}. The Java-style non-const iterator is
+ simply a type definition for QMutableListIterator<QByteArray>.
+
+ \sa QByteArrayListIterator, QByteArrayList::iterator
+*/
+
+/*!
+ \class QByteArrayList
+ \inmodule QtCore
+ \since 5.4
+ \brief The QByteArrayList class provides a list of byte arrays.
+
+ \ingroup tools
+ \ingroup shared
+ \ingroup string-processing
+
+ \reentrant
+
+ QByteArrayList is actually just a QList<QByteArray>. It is documented as a
+ full class just for simplicity of documenting the member methods that exist
+ only in QList<QByteArray>.
+
+ All of QList's functionality also applies to QByteArrayList. For example, you
+ can use isEmpty() to test whether the list is empty, and you can call
+ functions like append(), prepend(), insert(), replace(), removeAll(),
+ removeAt(), removeFirst(), removeLast(), and removeOne() to modify a
+ QByteArrayList. In addition, QByteArrayList provides several join()
+ methods for concatenating the list into a single QByteArray.
+
+ The purpose of QByteArrayList is quite different from that of QStringList.
+ Whereas QStringList has many methods for manipulation of elements within
+ the list, QByteArrayList does not.
+ Normally, QStringList should be used whenever working with a list of printable
+ strings. QByteArrayList should be used to handle and efficiently join large blobs
+ of binary data, as when sequentially receiving serialized data through a
+ QIODevice.
+
+ \sa QByteArray, QStringList
+*/
+
+/*!
+ \fn QByteArray QByteArrayList::join() const
+
+ Joins all the byte arrays into a single byte array.
+*/
+
+/*!
+ \fn QByteArray QByteArrayList::join(const QByteArray &separator) const
+
+ Joins all the byte arrays into a single byte array with each
+ element separated by the given \a separator.
+*/
+
+/*!
+ \fn QByteArray QByteArrayList::join(char separator) const
+
+ Joins all the byte arrays into a single byte array with each
+ element separated by the given \a separator.
+*/
+
+static int QByteArrayList_joinedSize(const QByteArrayList *that, int seplen)
+{
+ int totalLength = 0;
+ const int size = that->size();
+
+ for (int i = 0; i < size; ++i)
+ totalLength += that->at(i).size();
+
+ if (size > 0)
+ totalLength += seplen * (size - 1);
+
+ return totalLength;
+}
+
+QByteArray QtPrivate::QByteArrayList_join(const QByteArrayList *that, const char *sep, int seplen)
+{
+ QByteArray res;
+ if (const int joinedSize = QByteArrayList_joinedSize(that, seplen))
+ res.reserve(joinedSize); // don't call reserve(0) - it allocates one byte for the NUL
+ const int size = that->size();
+ for (int i = 0; i < size; ++i) {
+ if (i)
+ res.append(sep, seplen);
+ res += that->at(i);
+ }
+ return res;
+}
+
+/*!
+ \fn int QByteArrayList::indexOf(const char *needle, int from) const
+
+ Returns the index position of the first occurrence of \a needle in
+ the list, searching forward from index position \a from. Returns
+ -1 if no item matched.
+
+ \a needle must be NUL-terminated.
+
+ This overload doesn't require creating a QByteArray, thus saving a
+ memory allocation and some CPU time.
+
+ \since 5.13
+ \overload
+*/
+
+int QtPrivate::QByteArrayList_indexOf(const QByteArrayList *that, const char *needle, int from)
+{
+ const auto it = std::find_if(that->begin() + from, that->end(), [needle](const QByteArray &item) { return item == needle; });
+ return it == that->end() ? -1 : int(std::distance(that->begin(), it));
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qbytearraylist.h b/src/corelib/text/qbytearraylist.h
new file mode 100644
index 0000000000..0250b649b8
--- /dev/null
+++ b/src/corelib/text/qbytearraylist.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2016 Intel Corporation.
+** Copyright (C) 2014 by Southwest Research Institute (R)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qlist.h>
+
+#ifndef QBYTEARRAYLIST_H
+#define QBYTEARRAYLIST_H
+
+#include <QtCore/qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
+typedef QListIterator<QByteArray> QByteArrayListIterator;
+typedef QMutableListIterator<QByteArray> QMutableByteArrayListIterator;
+#endif
+
+#ifndef Q_CLANG_QDOC
+typedef QList<QByteArray> QByteArrayList;
+
+namespace QtPrivate {
+ QByteArray Q_CORE_EXPORT QByteArrayList_join(const QByteArrayList *that, const char *separator, int separatorLength);
+ int Q_CORE_EXPORT QByteArrayList_indexOf(const QByteArrayList *that, const char *needle, int from);
+}
+#endif
+
+#ifdef Q_CLANG_QDOC
+class QByteArrayList : public QList<QByteArray>
+#else
+template <> struct QListSpecialMethods<QByteArray>
+#endif
+{
+#ifndef Q_CLANG_QDOC
+protected:
+ ~QListSpecialMethods() = default;
+#endif
+public:
+ inline QByteArray join() const
+ { return QtPrivate::QByteArrayList_join(self(), nullptr, 0); }
+ inline QByteArray join(const QByteArray &sep) const
+ { return QtPrivate::QByteArrayList_join(self(), sep.constData(), sep.size()); }
+ inline QByteArray join(char sep) const
+ { return QtPrivate::QByteArrayList_join(self(), &sep, 1); }
+
+ inline int indexOf(const char *needle, int from = 0) const
+ { return QtPrivate::QByteArrayList_indexOf(self(), needle, from); }
+
+private:
+ typedef QList<QByteArray> Self;
+ Self *self() { return static_cast<Self *>(this); }
+ const Self *self() const { return static_cast<const Self *>(this); }
+};
+
+QT_END_NAMESPACE
+
+#endif // QBYTEARRAYLIST_H
diff --git a/src/corelib/text/qbytearraymatcher.cpp b/src/corelib/text/qbytearraymatcher.cpp
new file mode 100644
index 0000000000..72e09226af
--- /dev/null
+++ b/src/corelib/text/qbytearraymatcher.cpp
@@ -0,0 +1,435 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbytearraymatcher.h"
+
+#include <limits.h>
+
+QT_BEGIN_NAMESPACE
+
+static inline void bm_init_skiptable(const uchar *cc, int len, uchar *skiptable)
+{
+ int l = qMin(len, 255);
+ memset(skiptable, l, 256*sizeof(uchar));
+ cc += len - l;
+ while (l--)
+ skiptable[*cc++] = l;
+}
+
+static inline int bm_find(const uchar *cc, int l, int index, const uchar *puc, uint pl,
+ const uchar *skiptable)
+{
+ if (pl == 0)
+ return index > l ? -1 : index;
+ const uint pl_minus_one = pl - 1;
+
+ const uchar *current = cc + index + pl_minus_one;
+ const uchar *end = cc + l;
+ while (current < end) {
+ uint skip = skiptable[*current];
+ if (!skip) {
+ // possible match
+ while (skip < pl) {
+ if (*(current - skip) != puc[pl_minus_one - skip])
+ break;
+ skip++;
+ }
+ if (skip > pl_minus_one) // we have a match
+ return (current - cc) - skip + 1;
+
+ // in case we don't have a match we are a bit inefficient as we only skip by one
+ // when we have the non matching char in the string.
+ if (skiptable[*(current - skip)] == pl)
+ skip = pl - skip;
+ else
+ skip = 1;
+ }
+ if (current > end - skip)
+ break;
+ current += skip;
+ }
+ return -1; // not found
+}
+
+/*! \class QByteArrayMatcher
+ \inmodule QtCore
+ \brief The QByteArrayMatcher class holds a sequence of bytes that
+ can be quickly matched in a byte array.
+
+ \ingroup tools
+ \ingroup string-processing
+
+ This class is useful when you have a sequence of bytes that you
+ want to repeatedly match against some byte arrays (perhaps in a
+ loop), or when you want to search for the same sequence of bytes
+ multiple times in the same byte array. Using a matcher object and
+ indexIn() is faster than matching a plain QByteArray with
+ QByteArray::indexOf() if repeated matching takes place. This
+ class offers no benefit if you are doing one-off byte array
+ matches.
+
+ Create the QByteArrayMatcher with the QByteArray you want to
+ search for. Then call indexIn() on the QByteArray that you want to
+ search.
+
+ \sa QByteArray, QStringMatcher
+*/
+
+/*!
+ Constructs an empty byte array matcher that won't match anything.
+ Call setPattern() to give it a pattern to match.
+*/
+QByteArrayMatcher::QByteArrayMatcher()
+ : d(nullptr)
+{
+ p.p = nullptr;
+ p.l = 0;
+ memset(p.q_skiptable, 0, sizeof(p.q_skiptable));
+}
+
+/*!
+ Constructs a byte array matcher from \a pattern. \a pattern
+ has the given \a length. \a pattern must remain in scope, but
+ the destructor does not delete \a pattern.
+ */
+QByteArrayMatcher::QByteArrayMatcher(const char *pattern, int length)
+ : d(nullptr)
+{
+ p.p = reinterpret_cast<const uchar *>(pattern);
+ p.l = length;
+ bm_init_skiptable(p.p, p.l, p.q_skiptable);
+}
+
+/*!
+ Constructs a byte array matcher that will search for \a pattern.
+ Call indexIn() to perform a search.
+*/
+QByteArrayMatcher::QByteArrayMatcher(const QByteArray &pattern)
+ : d(nullptr), q_pattern(pattern)
+{
+ p.p = reinterpret_cast<const uchar *>(pattern.constData());
+ p.l = pattern.size();
+ bm_init_skiptable(p.p, p.l, p.q_skiptable);
+}
+
+/*!
+ Copies the \a other byte array matcher to this byte array matcher.
+*/
+QByteArrayMatcher::QByteArrayMatcher(const QByteArrayMatcher &other)
+ : d(nullptr)
+{
+ operator=(other);
+}
+
+/*!
+ Destroys the byte array matcher.
+*/
+QByteArrayMatcher::~QByteArrayMatcher()
+{
+ Q_UNUSED(d);
+}
+
+/*!
+ Assigns the \a other byte array matcher to this byte array matcher.
+*/
+QByteArrayMatcher &QByteArrayMatcher::operator=(const QByteArrayMatcher &other)
+{
+ q_pattern = other.q_pattern;
+ memcpy(&p, &other.p, sizeof(p));
+ return *this;
+}
+
+/*!
+ Sets the byte array that this byte array matcher will search for
+ to \a pattern.
+
+ \sa pattern(), indexIn()
+*/
+void QByteArrayMatcher::setPattern(const QByteArray &pattern)
+{
+ q_pattern = pattern;
+ p.p = reinterpret_cast<const uchar *>(pattern.constData());
+ p.l = pattern.size();
+ bm_init_skiptable(p.p, p.l, p.q_skiptable);
+}
+
+/*!
+ Searches the byte array \a ba, from byte position \a from (default
+ 0, i.e. from the first byte), for the byte array pattern() that
+ was set in the constructor or in the most recent call to
+ setPattern(). Returns the position where the pattern() matched in
+ \a ba, or -1 if no match was found.
+*/
+int QByteArrayMatcher::indexIn(const QByteArray &ba, int from) const
+{
+ if (from < 0)
+ from = 0;
+ return bm_find(reinterpret_cast<const uchar *>(ba.constData()), ba.size(), from,
+ p.p, p.l, p.q_skiptable);
+}
+
+/*!
+ Searches the char string \a str, which has length \a len, from
+ byte position \a from (default 0, i.e. from the first byte), for
+ the byte array pattern() that was set in the constructor or in the
+ most recent call to setPattern(). Returns the position where the
+ pattern() matched in \a str, or -1 if no match was found.
+*/
+int QByteArrayMatcher::indexIn(const char *str, int len, int from) const
+{
+ if (from < 0)
+ from = 0;
+ return bm_find(reinterpret_cast<const uchar *>(str), len, from,
+ p.p, p.l, p.q_skiptable);
+}
+
+/*!
+ \fn QByteArray QByteArrayMatcher::pattern() const
+
+ Returns the byte array pattern that this byte array matcher will
+ search for.
+
+ \sa setPattern()
+*/
+
+
+static int findChar(const char *str, int len, char ch, int from)
+{
+ const uchar *s = (const uchar *)str;
+ uchar c = (uchar)ch;
+ if (from < 0)
+ from = qMax(from + len, 0);
+ if (from < len) {
+ const uchar *n = s + from - 1;
+ const uchar *e = s + len;
+ while (++n != e)
+ if (*n == c)
+ return n - s;
+ }
+ return -1;
+}
+
+/*!
+ \internal
+ */
+static int qFindByteArrayBoyerMoore(
+ const char *haystack, int haystackLen, int haystackOffset,
+ const char *needle, int needleLen)
+{
+ uchar skiptable[256];
+ bm_init_skiptable((const uchar *)needle, needleLen, skiptable);
+ if (haystackOffset < 0)
+ haystackOffset = 0;
+ return bm_find((const uchar *)haystack, haystackLen, haystackOffset,
+ (const uchar *)needle, needleLen, skiptable);
+}
+
+#define REHASH(a) \
+ if (sl_minus_1 < sizeof(uint) * CHAR_BIT) \
+ hashHaystack -= uint(a) << sl_minus_1; \
+ hashHaystack <<= 1
+
+/*!
+ \internal
+ */
+int qFindByteArray(
+ const char *haystack0, int haystackLen, int from,
+ const char *needle, int needleLen)
+{
+ const int l = haystackLen;
+ const int sl = needleLen;
+ if (from < 0)
+ from += l;
+ if (uint(sl + from) > (uint)l)
+ return -1;
+ if (!sl)
+ return from;
+ if (!l)
+ return -1;
+
+ if (sl == 1)
+ return findChar(haystack0, haystackLen, needle[0], from);
+
+ /*
+ We use the Boyer-Moore algorithm in cases where the overhead
+ for the skip table should pay off, otherwise we use a simple
+ hash function.
+ */
+ if (l > 500 && sl > 5)
+ return qFindByteArrayBoyerMoore(haystack0, haystackLen, from,
+ needle, needleLen);
+
+ /*
+ We use some hashing for efficiency's sake. Instead of
+ comparing strings, we compare the hash value of str with that
+ of a part of this QString. Only if that matches, we call memcmp().
+ */
+ const char *haystack = haystack0 + from;
+ const char *end = haystack0 + (l - sl);
+ const uint sl_minus_1 = sl - 1;
+ uint hashNeedle = 0, hashHaystack = 0;
+ int idx;
+ for (idx = 0; idx < sl; ++idx) {
+ hashNeedle = ((hashNeedle<<1) + needle[idx]);
+ hashHaystack = ((hashHaystack<<1) + haystack[idx]);
+ }
+ hashHaystack -= *(haystack + sl_minus_1);
+
+ while (haystack <= end) {
+ hashHaystack += *(haystack + sl_minus_1);
+ if (hashHaystack == hashNeedle && *needle == *haystack
+ && memcmp(needle, haystack, sl) == 0)
+ return haystack - haystack0;
+
+ REHASH(*haystack);
+ ++haystack;
+ }
+ return -1;
+}
+
+/*!
+ \class QStaticByteArrayMatcherBase
+ \since 5.9
+ \internal
+ \brief Non-template base class of QStaticByteArrayMatcher.
+*/
+
+/*!
+ \class QStaticByteArrayMatcher
+ \since 5.9
+ \inmodule QtCore
+ \brief The QStaticByteArrayMatcher class is a compile-time version of QByteArrayMatcher.
+
+ \ingroup tools
+ \ingroup string-processing
+
+ This class is useful when you have a sequence of bytes that you
+ want to repeatedly match against some byte arrays (perhaps in a
+ loop), or when you want to search for the same sequence of bytes
+ multiple times in the same byte array. Using a matcher object and
+ indexIn() is faster than matching a plain QByteArray with
+ QByteArray::indexOf(), in particular if repeated matching takes place.
+
+ Unlike QByteArrayMatcher, this class calculates the internal
+ representation at \e{compile-time}, if your compiler supports
+ C++14-level \c{constexpr} (C++11 is not sufficient), so it can
+ even benefit if you are doing one-off byte array matches.
+
+ Create the QStaticByteArrayMatcher by calling qMakeStaticByteArrayMatcher(),
+ passing it the C string literal you want to search for. Store the return
+ value of that function in a \c{static const auto} variable, so you don't need
+ to pass the \c{N} template parameter explicitly:
+
+ \snippet code/src_corelib_tools_qbytearraymatcher.cpp 0
+
+ Then call indexIn() on the QByteArray in which you want to search, just like
+ with QByteArrayMatcher.
+
+ Since this class is designed to do all the up-front calculations at compile-time,
+ it does not offer a setPattern() method.
+
+ \note Qt detects the necessary C++14 compiler support by way of the feature
+ test recommendations from
+ \l{https://isocpp.org/std/standing-documents/sd-6-sg10-feature-test-recommendations}
+ {C++ Committee's Standing Document 6}.
+
+ \sa QByteArrayMatcher, QStringMatcher
+*/
+
+/*!
+ \fn template <uint N> int QStaticByteArrayMatcher<N>::indexIn(const char *haystack, int hlen, int from = 0) const
+
+ Searches the char string \a haystack, which has length \a hlen, from
+ byte position \a from (default 0, i.e. from the first byte), for
+ the byte array pattern() that was set in the constructor.
+
+ Returns the position where the pattern() matched in \a haystack, or -1 if no match was found.
+*/
+
+/*!
+ \fn template <uint N> int QStaticByteArrayMatcher<N>::indexIn(const QByteArray &haystack, int from = 0) const
+
+ Searches the char string \a haystack, from byte position \a from
+ (default 0, i.e. from the first byte), for the byte array pattern()
+ that was set in the constructor.
+
+ Returns the position where the pattern() matched in \a haystack, or -1 if no match was found.
+*/
+
+/*!
+ \fn template <uint N> QByteArray QStaticByteArrayMatcher<N>::pattern() const
+
+ Returns the byte array pattern that this byte array matcher will
+ search for.
+
+ \sa QByteArrayMatcher::setPattern()
+*/
+
+/*!
+ \internal
+*/
+int QStaticByteArrayMatcherBase::indexOfIn(const char *needle, uint nlen, const char *haystack, int hlen, int from) const noexcept
+{
+ if (from < 0)
+ from = 0;
+ return bm_find(reinterpret_cast<const uchar *>(haystack), hlen, from,
+ reinterpret_cast<const uchar *>(needle), nlen, m_skiptable.data);
+}
+
+/*!
+ \fn template <uint N> QStaticByteArrayMatcher<N>::QStaticByteArrayMatcher(const char (&pattern)[N])
+ \internal
+*/
+
+/*!
+ \fn template <uint N> QStaticByteArrayMatcher qMakeStaticByteArrayMatcher(const char (&pattern)[N])
+ \since 5.9
+ \relates QStaticByteArrayMatcher
+
+ Return a QStaticByteArrayMatcher with the correct \c{N} determined
+ automatically from the \a pattern passed.
+
+ To take full advantage of this function, assign the result to an
+ \c{auto} variable:
+
+ \snippet code/src_corelib_tools_qbytearraymatcher.cpp 1
+*/
+
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qbytearraymatcher.h b/src/corelib/text/qbytearraymatcher.h
new file mode 100644
index 0000000000..0eedfc1d20
--- /dev/null
+++ b/src/corelib/text/qbytearraymatcher.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBYTEARRAYMATCHER_H
+#define QBYTEARRAYMATCHER_H
+
+#include <QtCore/qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+
+class QByteArrayMatcherPrivate;
+
+class Q_CORE_EXPORT QByteArrayMatcher
+{
+public:
+ QByteArrayMatcher();
+ explicit QByteArrayMatcher(const QByteArray &pattern);
+ explicit QByteArrayMatcher(const char *pattern, int length);
+ QByteArrayMatcher(const QByteArrayMatcher &other);
+ ~QByteArrayMatcher();
+
+ QByteArrayMatcher &operator=(const QByteArrayMatcher &other);
+
+ void setPattern(const QByteArray &pattern);
+
+ int indexIn(const QByteArray &ba, int from = 0) const;
+ int indexIn(const char *str, int len, int from = 0) const;
+ inline QByteArray pattern() const
+ {
+ if (q_pattern.isNull())
+ return QByteArray(reinterpret_cast<const char*>(p.p), p.l);
+ return q_pattern;
+ }
+
+private:
+ QByteArrayMatcherPrivate *d;
+ QByteArray q_pattern;
+ struct Data {
+ uchar q_skiptable[256];
+ const uchar *p;
+ int l;
+ };
+ union {
+ uint dummy[256];
+ Data p;
+ };
+};
+
+class QStaticByteArrayMatcherBase
+{
+ Q_DECL_ALIGN(16)
+ struct Skiptable {
+ uchar data[256];
+ } m_skiptable;
+protected:
+ explicit Q_DECL_RELAXED_CONSTEXPR QStaticByteArrayMatcherBase(const char *pattern, uint n) noexcept
+ : m_skiptable(generate(pattern, n)) {}
+ // compiler-generated copy/more ctors/assignment operators are ok!
+ // compiler-generated dtor is ok!
+
+ Q_CORE_EXPORT int indexOfIn(const char *needle, uint nlen, const char *haystack, int hlen, int from) const noexcept;
+
+private:
+ static Q_DECL_RELAXED_CONSTEXPR Skiptable generate(const char *pattern, uint n) noexcept
+ {
+ const auto uchar_max = (std::numeric_limits<uchar>::max)();
+ uchar max = n > uchar_max ? uchar_max : n;
+ Skiptable table = {
+ // this verbose initialization code aims to avoid some opaque error messages
+ // even on powerful compilers such as GCC 5.3. Even though for GCC a loop
+ // format can be found that v5.3 groks, it's probably better to go with this
+ // for the time being:
+ {
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ max, max, max, max, max, max, max, max, max, max, max, max, max, max, max, max,
+ }
+ };
+ pattern += n - max;
+ while (max--)
+ table.data[uchar(*pattern++)] = max;
+ return table;
+ }
+};
+
+template <uint N>
+class QStaticByteArrayMatcher : QStaticByteArrayMatcherBase
+{
+ char m_pattern[N];
+ Q_STATIC_ASSERT_X(N > 2, "QStaticByteArrayMatcher makes no sense for finding a single-char pattern");
+public:
+ explicit Q_DECL_RELAXED_CONSTEXPR QStaticByteArrayMatcher(const char (&patternToMatch)[N]) noexcept
+ : QStaticByteArrayMatcherBase(patternToMatch, N - 1), m_pattern()
+ {
+ for (uint i = 0; i < N; ++i)
+ m_pattern[i] = patternToMatch[i];
+ }
+
+ int indexIn(const QByteArray &haystack, int from = 0) const noexcept
+ { return this->indexOfIn(m_pattern, N - 1, haystack.data(), haystack.size(), from); }
+ int indexIn(const char *haystack, int hlen, int from = 0) const noexcept
+ { return this->indexOfIn(m_pattern, N - 1, haystack, hlen, from); }
+
+ QByteArray pattern() const { return QByteArray(m_pattern, int(N - 1)); }
+};
+
+template <uint N>
+Q_DECL_RELAXED_CONSTEXPR QStaticByteArrayMatcher<N> qMakeStaticByteArrayMatcher(const char (&pattern)[N]) noexcept
+{ return QStaticByteArrayMatcher<N>(pattern); }
+
+QT_END_NAMESPACE
+
+#endif // QBYTEARRAYMATCHER_H
diff --git a/src/corelib/text/qbytedata_p.h b/src/corelib/text/qbytedata_p.h
new file mode 100644
index 0000000000..b319d75811
--- /dev/null
+++ b/src/corelib/text/qbytedata_p.h
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBYTEDATA_P_H
+#define QBYTEDATA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qglobal_p.h>
+#include <qbytearray.h>
+
+QT_BEGIN_NAMESPACE
+
+// this class handles a list of QByteArrays. It is a variant of QRingBuffer
+// that avoid malloc/realloc/memcpy.
+class QByteDataBuffer
+{
+private:
+ QList<QByteArray> buffers;
+ qint64 bufferCompleteSize;
+ qint64 firstPos;
+public:
+ QByteDataBuffer() : bufferCompleteSize(0), firstPos(0)
+ {
+ }
+
+ ~QByteDataBuffer()
+ {
+ clear();
+ }
+
+ static inline void popFront(QByteArray &ba, qint64 n)
+ {
+ ba = QByteArray(ba.constData() + n, ba.size() - n);
+ }
+
+ inline void squeezeFirst()
+ {
+ if (!buffers.isEmpty() && firstPos > 0) {
+ popFront(buffers.first(), firstPos);
+ firstPos = 0;
+ }
+ }
+
+ inline void append(const QByteDataBuffer& other)
+ {
+ if (other.isEmpty())
+ return;
+
+ buffers.append(other.buffers);
+ bufferCompleteSize += other.byteAmount();
+
+ if (other.firstPos > 0)
+ popFront(buffers[bufferCount() - other.bufferCount()], other.firstPos);
+ }
+
+
+ inline void append(const QByteArray& bd)
+ {
+ if (bd.isEmpty())
+ return;
+
+ buffers.append(bd);
+ bufferCompleteSize += bd.size();
+ }
+
+ inline void prepend(const QByteArray& bd)
+ {
+ if (bd.isEmpty())
+ return;
+
+ squeezeFirst();
+
+ buffers.prepend(bd);
+ bufferCompleteSize += bd.size();
+ }
+
+ // return the first QByteData. User of this function has to free() its .data!
+ // preferably use this function to read data.
+ inline QByteArray read()
+ {
+ squeezeFirst();
+ bufferCompleteSize -= buffers.first().size();
+ return buffers.takeFirst();
+ }
+
+ // return everything. User of this function has to free() its .data!
+ // avoid to use this, it might malloc and memcpy.
+ inline QByteArray readAll()
+ {
+ return read(byteAmount());
+ }
+
+ // return amount. User of this function has to free() its .data!
+ // avoid to use this, it might malloc and memcpy.
+ inline QByteArray read(qint64 amount)
+ {
+ amount = qMin(byteAmount(), amount);
+ QByteArray byteData;
+ byteData.resize(amount);
+ read(byteData.data(), byteData.size());
+ return byteData;
+ }
+
+ // return amount bytes. User of this function has to free() its .data!
+ // avoid to use this, it will memcpy.
+ qint64 read(char* dst, qint64 amount)
+ {
+ amount = qMin(amount, byteAmount());
+ qint64 originalAmount = amount;
+ char *writeDst = dst;
+
+ while (amount > 0) {
+ const QByteArray &first = buffers.first();
+ qint64 firstSize = first.size() - firstPos;
+ if (amount >= firstSize) {
+ // take it completely
+ bufferCompleteSize -= firstSize;
+ amount -= firstSize;
+ memcpy(writeDst, first.constData() + firstPos, firstSize);
+ writeDst += firstSize;
+ firstPos = 0;
+ buffers.takeFirst();
+ } else {
+ // take a part of it & it is the last one to take
+ bufferCompleteSize -= amount;
+ memcpy(writeDst, first.constData() + firstPos, amount);
+ firstPos += amount;
+ amount = 0;
+ }
+ }
+
+ return originalAmount;
+ }
+
+ inline char getChar()
+ {
+ char c;
+ read(&c, 1);
+ return c;
+ }
+
+ inline void clear()
+ {
+ buffers.clear();
+ bufferCompleteSize = 0;
+ firstPos = 0;
+ }
+
+ // The byte count of all QByteArrays
+ inline qint64 byteAmount() const
+ {
+ return bufferCompleteSize;
+ }
+
+ // the number of QByteArrays
+ inline int bufferCount() const
+ {
+ return buffers.length();
+ }
+
+ inline bool isEmpty() const
+ {
+ return byteAmount() == 0;
+ }
+
+ inline qint64 sizeNextBlock() const
+ {
+ if(buffers.isEmpty())
+ return 0;
+ else
+ return buffers.first().size() - firstPos;
+ }
+
+ inline QByteArray& operator[](int i)
+ {
+ if (i == 0)
+ squeezeFirst();
+
+ return buffers[i];
+ }
+
+ inline bool canReadLine() const {
+ int i = 0;
+ if (i < buffers.length()) {
+ if (buffers.at(i).indexOf('\n', firstPos) != -1)
+ return true;
+ ++i;
+
+ for (; i < buffers.length(); i++)
+ if (buffers.at(i).contains('\n'))
+ return true;
+ }
+ return false;
+ }
+};
+
+QT_END_NAMESPACE
+
+#endif // QBYTEDATA_P_H
diff --git a/src/corelib/text/qchar.cpp b/src/corelib/text/qchar.cpp
new file mode 100644
index 0000000000..0c190c6a3d
--- /dev/null
+++ b/src/corelib/text/qchar.cpp
@@ -0,0 +1,2059 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Don't define it while compiling this module, or USERS of Qt will
+// not be able to link.
+#ifdef QT_NO_CAST_FROM_ASCII
+# undef QT_NO_CAST_FROM_ASCII
+#endif
+#ifdef QT_NO_CAST_TO_ASCII
+# undef QT_NO_CAST_TO_ASCII
+#endif
+#include "qchar.h"
+
+#include "qdatastream.h"
+
+#include "qunicodetables_p.h"
+#include "qunicodetables.cpp"
+
+#include <algorithm>
+
+QT_BEGIN_NAMESPACE
+
+#define FLAG(x) (1 << (x))
+
+/*!
+ \class QLatin1Char
+ \inmodule QtCore
+ \brief The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
+
+ \ingroup string-processing
+
+ This class is only useful to construct a QChar with 8-bit character.
+
+ \sa QChar, QLatin1String, QString
+*/
+
+/*!
+ \fn const char QLatin1Char::toLatin1() const
+
+ Converts a Latin-1 character to an 8-bit ASCII representation of the character.
+*/
+
+/*!
+ \fn const ushort QLatin1Char::unicode() const
+
+ Converts a Latin-1 character to an 16-bit-encoded Unicode representation
+ of the character.
+*/
+
+/*!
+ \fn QLatin1Char::QLatin1Char(char c)
+
+ Constructs a Latin-1 character for \a c. This constructor should be
+ used when the encoding of the input character is known to be Latin-1.
+*/
+
+/*!
+ \class QChar
+ \inmodule QtCore
+ \brief The QChar class provides a 16-bit Unicode character.
+
+ \ingroup string-processing
+ \reentrant
+
+ In Qt, Unicode characters are 16-bit entities without any markup
+ or structure. This class represents such an entity. It is
+ lightweight, so it can be used everywhere. Most compilers treat
+ it like an \c{unsigned short}.
+
+ QChar provides a full complement of testing/classification
+ functions, converting to and from other formats, converting from
+ composed to decomposed Unicode, and trying to compare and
+ case-convert if you ask it to.
+
+ The classification functions include functions like those in the
+ standard C++ header \<cctype\> (formerly \<ctype.h\>), but
+ operating on the full range of Unicode characters, not just for the ASCII
+ range. They all return true if the character is a certain type of character;
+ otherwise they return false. These classification functions are
+ isNull() (returns \c true if the character is '\\0'), isPrint()
+ (true if the character is any sort of printable character,
+ including whitespace), isPunct() (any sort of punctation),
+ isMark() (Unicode Mark), isLetter() (a letter), isNumber() (any
+ sort of numeric character, not just 0-9), isLetterOrNumber(), and
+ isDigit() (decimal digits). All of these are wrappers around
+ category() which return the Unicode-defined category of each
+ character. Some of these also calculate the derived properties
+ (for example isSpace() returns \c true if the character is of category
+ Separator_* or an exceptional code point from Other_Control category).
+
+ QChar also provides direction(), which indicates the "natural"
+ writing direction of this character. The joiningType() function
+ indicates how the character joins with it's neighbors (needed
+ mostly for Arabic or Syriac) and finally hasMirrored(), which indicates
+ whether the character needs to be mirrored when it is printed in
+ it's "unnatural" writing direction.
+
+ Composed Unicode characters (like \a ring) can be converted to
+ decomposed Unicode ("a" followed by "ring above") by using decomposition().
+
+ In Unicode, comparison is not necessarily possible and case
+ conversion is very difficult at best. Unicode, covering the
+ "entire" world, also includes most of the world's case and
+ sorting problems. operator==() and friends will do comparison
+ based purely on the numeric Unicode value (code point) of the
+ characters, and toUpper() and toLower() will do case changes when
+ the character has a well-defined uppercase/lowercase equivalent.
+ For locale-dependent comparisons, use QString::localeAwareCompare().
+
+ The conversion functions include unicode() (to a scalar),
+ toLatin1() (to scalar, but converts all non-Latin-1 characters to
+ 0), row() (gives the Unicode row), cell() (gives the Unicode
+ cell), digitValue() (gives the integer value of any of the
+ numerous digit characters), and a host of constructors.
+
+ QChar provides constructors and cast operators that make it easy
+ to convert to and from traditional 8-bit \c{char}s. If you
+ defined \c QT_NO_CAST_FROM_ASCII and \c QT_NO_CAST_TO_ASCII, as
+ explained in the QString documentation, you will need to
+ explicitly call fromLatin1(), or use QLatin1Char,
+ to construct a QChar from an 8-bit \c char, and you will need to
+ call toLatin1() to get the 8-bit value back.
+
+ For more information see
+ \l{http://www.unicode.org/ucd/}{"About the Unicode Character Database"}.
+
+ \sa Unicode, QString, QLatin1Char
+*/
+
+/*!
+ \enum QChar::UnicodeVersion
+
+ Specifies which version of the \l{http://www.unicode.org/}{Unicode standard}
+ introduced a certain character.
+
+ \value Unicode_1_1 Version 1.1
+ \value Unicode_2_0 Version 2.0
+ \value Unicode_2_1_2 Version 2.1.2
+ \value Unicode_3_0 Version 3.0
+ \value Unicode_3_1 Version 3.1
+ \value Unicode_3_2 Version 3.2
+ \value Unicode_4_0 Version 4.0
+ \value Unicode_4_1 Version 4.1
+ \value Unicode_5_0 Version 5.0
+ \value Unicode_5_1 Version 5.1
+ \value Unicode_5_2 Version 5.2
+ \value Unicode_6_0 Version 6.0
+ \value Unicode_6_1 Version 6.1
+ \value Unicode_6_2 Version 6.2
+ \value Unicode_6_3 Version 6.3 Since Qt 5.3
+ \value Unicode_7_0 Version 7.0 Since Qt 5.5
+ \value Unicode_8_0 Version 8.0 Since Qt 5.6
+ \value Unicode_9_0 Version 9.0 Since Qt 5.11
+ \value Unicode_10_0 Version 10.0 Since Qt 5.11
+ \value Unicode_Unassigned The value is not assigned to any character
+ in version 8.0 of Unicode.
+
+ \sa unicodeVersion(), currentUnicodeVersion()
+*/
+
+/*!
+ \enum QChar::Category
+
+ This enum maps the Unicode character categories.
+
+ The following characters are normative in Unicode:
+
+ \value Mark_NonSpacing Unicode class name Mn
+
+ \value Mark_SpacingCombining Unicode class name Mc
+
+ \value Mark_Enclosing Unicode class name Me
+
+ \value Number_DecimalDigit Unicode class name Nd
+
+ \value Number_Letter Unicode class name Nl
+
+ \value Number_Other Unicode class name No
+
+ \value Separator_Space Unicode class name Zs
+
+ \value Separator_Line Unicode class name Zl
+
+ \value Separator_Paragraph Unicode class name Zp
+
+ \value Other_Control Unicode class name Cc
+
+ \value Other_Format Unicode class name Cf
+
+ \value Other_Surrogate Unicode class name Cs
+
+ \value Other_PrivateUse Unicode class name Co
+
+ \value Other_NotAssigned Unicode class name Cn
+
+
+ The following categories are informative in Unicode:
+
+ \value Letter_Uppercase Unicode class name Lu
+
+ \value Letter_Lowercase Unicode class name Ll
+
+ \value Letter_Titlecase Unicode class name Lt
+
+ \value Letter_Modifier Unicode class name Lm
+
+ \value Letter_Other Unicode class name Lo
+
+ \value Punctuation_Connector Unicode class name Pc
+
+ \value Punctuation_Dash Unicode class name Pd
+
+ \value Punctuation_Open Unicode class name Ps
+
+ \value Punctuation_Close Unicode class name Pe
+
+ \value Punctuation_InitialQuote Unicode class name Pi
+
+ \value Punctuation_FinalQuote Unicode class name Pf
+
+ \value Punctuation_Other Unicode class name Po
+
+ \value Symbol_Math Unicode class name Sm
+
+ \value Symbol_Currency Unicode class name Sc
+
+ \value Symbol_Modifier Unicode class name Sk
+
+ \value Symbol_Other Unicode class name So
+
+ \sa category()
+*/
+
+/*!
+ \enum QChar::Script
+ \since 5.1
+
+ This enum type defines the Unicode script property values.
+
+ For details about the Unicode script property values see
+ \l{http://www.unicode.org/reports/tr24/}{Unicode Standard Annex #24}.
+
+ In order to conform to C/C++ naming conventions "Script_" is prepended
+ to the codes used in the Unicode Standard.
+
+ \value Script_Unknown For unassigned, private-use, noncharacter, and surrogate code points.
+ \value Script_Inherited For characters that may be used with multiple scripts
+ and that inherit their script from the preceding characters.
+ These include nonspacing marks, enclosing marks,
+ and zero width joiner/non-joiner characters.
+ \value Script_Common For characters that may be used with multiple scripts
+ and that do not inherit their script from the preceding characters.
+
+ \value Script_Latin
+ \value Script_Greek
+ \value Script_Cyrillic
+ \value Script_Armenian
+ \value Script_Hebrew
+ \value Script_Arabic
+ \value Script_Syriac
+ \value Script_Thaana
+ \value Script_Devanagari
+ \value Script_Bengali
+ \value Script_Gurmukhi
+ \value Script_Gujarati
+ \value Script_Oriya
+ \value Script_Tamil
+ \value Script_Telugu
+ \value Script_Kannada
+ \value Script_Malayalam
+ \value Script_Sinhala
+ \value Script_Thai
+ \value Script_Lao
+ \value Script_Tibetan
+ \value Script_Myanmar
+ \value Script_Georgian
+ \value Script_Hangul
+ \value Script_Ethiopic
+ \value Script_Cherokee
+ \value Script_CanadianAboriginal
+ \value Script_Ogham
+ \value Script_Runic
+ \value Script_Khmer
+ \value Script_Mongolian
+ \value Script_Hiragana
+ \value Script_Katakana
+ \value Script_Bopomofo
+ \value Script_Han
+ \value Script_Yi
+ \value Script_OldItalic
+ \value Script_Gothic
+ \value Script_Deseret
+ \value Script_Tagalog
+ \value Script_Hanunoo
+ \value Script_Buhid
+ \value Script_Tagbanwa
+ \value Script_Coptic
+ \value Script_Limbu
+ \value Script_TaiLe
+ \value Script_LinearB
+ \value Script_Ugaritic
+ \value Script_Shavian
+ \value Script_Osmanya
+ \value Script_Cypriot
+ \value Script_Braille
+ \value Script_Buginese
+ \value Script_NewTaiLue
+ \value Script_Glagolitic
+ \value Script_Tifinagh
+ \value Script_SylotiNagri
+ \value Script_OldPersian
+ \value Script_Kharoshthi
+ \value Script_Balinese
+ \value Script_Cuneiform
+ \value Script_Phoenician
+ \value Script_PhagsPa
+ \value Script_Nko
+ \value Script_Sundanese
+ \value Script_Lepcha
+ \value Script_OlChiki
+ \value Script_Vai
+ \value Script_Saurashtra
+ \value Script_KayahLi
+ \value Script_Rejang
+ \value Script_Lycian
+ \value Script_Carian
+ \value Script_Lydian
+ \value Script_Cham
+ \value Script_TaiTham
+ \value Script_TaiViet
+ \value Script_Avestan
+ \value Script_EgyptianHieroglyphs
+ \value Script_Samaritan
+ \value Script_Lisu
+ \value Script_Bamum
+ \value Script_Javanese
+ \value Script_MeeteiMayek
+ \value Script_ImperialAramaic
+ \value Script_OldSouthArabian
+ \value Script_InscriptionalParthian
+ \value Script_InscriptionalPahlavi
+ \value Script_OldTurkic
+ \value Script_Kaithi
+ \value Script_Batak
+ \value Script_Brahmi
+ \value Script_Mandaic
+ \value Script_Chakma
+ \value Script_MeroiticCursive
+ \value Script_MeroiticHieroglyphs
+ \value Script_Miao
+ \value Script_Sharada
+ \value Script_SoraSompeng
+ \value Script_Takri
+ \value Script_CaucasianAlbanian
+ \value Script_BassaVah
+ \value Script_Duployan
+ \value Script_Elbasan
+ \value Script_Grantha
+ \value Script_PahawhHmong
+ \value Script_Khojki
+ \value Script_LinearA
+ \value Script_Mahajani
+ \value Script_Manichaean
+ \value Script_MendeKikakui
+ \value Script_Modi
+ \value Script_Mro
+ \value Script_OldNorthArabian
+ \value Script_Nabataean
+ \value Script_Palmyrene
+ \value Script_PauCinHau
+ \value Script_OldPermic
+ \value Script_PsalterPahlavi
+ \value Script_Siddham
+ \value Script_Khudawadi
+ \value Script_Tirhuta
+ \value Script_WarangCiti
+ \value Script_Ahom
+ \value Script_AnatolianHieroglyphs
+ \value Script_Hatran
+ \value Script_Multani
+ \value Script_OldHungarian
+ \value Script_SignWriting
+ \value Script_Adlam
+ \value Script_Bhaiksuki
+ \value Script_Marchen
+ \value Script_Newa
+ \value Script_Osage
+ \value Script_Tangut
+ \value Script_MasaramGondi
+ \value Script_Nushu
+ \value Script_Soyombo
+ \value Script_ZanabazarSquare
+
+ \omitvalue ScriptCount
+
+ \sa script()
+*/
+
+/*!
+ \enum QChar::Direction
+
+ This enum type defines the Unicode direction attributes. See the
+ \l{http://www.unicode.org/reports/tr9/tr9-35.html#Table_Bidirectional_Character_Types}{Unicode Standard} for a description
+ of the values.
+
+ In order to conform to C/C++ naming conventions "Dir" is prepended
+ to the codes used in the Unicode Standard.
+
+ \value DirAL
+ \value DirAN
+ \value DirB
+ \value DirBN
+ \value DirCS
+ \value DirEN
+ \value DirES
+ \value DirET
+ \value DirFSI Since Qt 5.3
+ \value DirL
+ \value DirLRE
+ \value DirLRI Since Qt 5.3
+ \value DirLRO
+ \value DirNSM
+ \value DirON
+ \value DirPDF
+ \value DirPDI Since Qt 5.3
+ \value DirR
+ \value DirRLE
+ \value DirRLI Since Qt 5.3
+ \value DirRLO
+ \value DirS
+ \value DirWS
+
+ \sa direction()
+*/
+
+/*!
+ \enum QChar::Decomposition
+
+ This enum type defines the Unicode decomposition attributes. See
+ the \l{http://www.unicode.org/}{Unicode Standard} for a
+ description of the values.
+
+ \value NoDecomposition
+ \value Canonical
+ \value Circle
+ \value Compat
+ \value Final
+ \value Font
+ \value Fraction
+ \value Initial
+ \value Isolated
+ \value Medial
+ \value Narrow
+ \value NoBreak
+ \value Small
+ \value Square
+ \value Sub
+ \value Super
+ \value Vertical
+ \value Wide
+
+ \sa decomposition()
+*/
+
+/*!
+ \enum QChar::JoiningType
+ since 5.3
+
+ This enum type defines the Unicode joining type attributes. See the
+ \l{http://www.unicode.org/}{Unicode Standard} for a description of the values.
+
+ In order to conform to C/C++ naming conventions "Joining_" is prepended
+ to the codes used in the Unicode Standard.
+
+ \value Joining_None
+ \value Joining_Causing
+ \value Joining_Dual
+ \value Joining_Right
+ \value Joining_Left
+ \value Joining_Transparent
+
+ \sa joiningType()
+*/
+
+#if QT_DEPRECATED_SINCE(5, 3)
+/*!
+ \enum QChar::Joining
+ \deprecated in 5.3, use JoiningType instead.
+
+ This enum type defines the Unicode joining attributes. See the
+ \l{http://www.unicode.org/}{Unicode Standard} for a description
+ of the values.
+
+ \value Center
+ \value Dual
+ \value OtherJoining
+ \value Right
+
+ \sa joining()
+*/
+#endif
+
+/*!
+ \enum QChar::CombiningClass
+
+ \internal
+
+ This enum type defines names for some of the Unicode combining
+ classes. See the \l{http://www.unicode.org/}{Unicode Standard}
+ for a description of the values.
+
+ \value Combining_Above
+ \value Combining_AboveAttached
+ \value Combining_AboveLeft
+ \value Combining_AboveLeftAttached
+ \value Combining_AboveRight
+ \value Combining_AboveRightAttached
+ \value Combining_Below
+ \value Combining_BelowAttached
+ \value Combining_BelowLeft
+ \value Combining_BelowLeftAttached
+ \value Combining_BelowRight
+ \value Combining_BelowRightAttached
+ \value Combining_DoubleAbove
+ \value Combining_DoubleBelow
+ \value Combining_IotaSubscript
+ \value Combining_Left
+ \value Combining_LeftAttached
+ \value Combining_Right
+ \value Combining_RightAttached
+*/
+
+/*!
+ \enum QChar::SpecialCharacter
+
+ \value Null A QChar with this value isNull().
+ \value Tabulation Character tabulation.
+ \value LineFeed
+ \value CarriageReturn
+ \value Space
+ \value Nbsp Non-breaking space.
+ \value SoftHyphen
+ \value ReplacementCharacter The character shown when a font has no glyph
+ for a certain codepoint. A special question mark character is often
+ used. Codecs use this codepoint when input data cannot be
+ represented in Unicode.
+ \value ObjectReplacementCharacter Used to represent an object such as an
+ image when such objects cannot be presented.
+ \value ByteOrderMark
+ \value ByteOrderSwapped
+ \value ParagraphSeparator
+ \value LineSeparator
+ \value LastValidCodePoint
+*/
+
+/*!
+ \fn void QChar::setCell(uchar cell)
+ \internal
+*/
+
+/*!
+ \fn void QChar::setRow(uchar row)
+ \internal
+*/
+
+/*!
+ \fn QChar::QChar()
+
+ Constructs a null QChar ('\\0').
+
+ \sa isNull()
+*/
+
+/*!
+ \fn QChar::QChar(QLatin1Char ch)
+
+ Constructs a QChar corresponding to ASCII/Latin-1 character \a ch.
+*/
+
+/*!
+ \fn QChar::QChar(SpecialCharacter ch)
+
+ Constructs a QChar for the predefined character value \a ch.
+*/
+
+/*!
+ \fn QChar::QChar(char16_t ch)
+ \since 5.10
+
+ Constructs a QChar corresponding to the UTF-16 character \a ch.
+*/
+
+/*!
+ \fn QChar::QChar(wchar_t ch)
+ \since 5.10
+
+ Constructs a QChar corresponding to the wide character \a ch.
+
+ \note This constructor is only available on Windows.
+*/
+
+/*!
+ \fn QChar::QChar(char ch)
+
+ Constructs a QChar corresponding to ASCII/Latin-1 character \a ch.
+
+ \note This constructor is not available when \c QT_NO_CAST_FROM_ASCII
+ is defined.
+
+ \sa QT_NO_CAST_FROM_ASCII
+*/
+
+/*!
+ \fn QChar::QChar(uchar ch)
+
+ Constructs a QChar corresponding to ASCII/Latin-1 character \a ch.
+
+ \note This constructor is not available when \c QT_NO_CAST_FROM_ASCII
+ or \c QT_RESTRICTED_CAST_FROM_ASCII is defined.
+
+ \sa QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII
+*/
+
+/*!
+ \fn QChar::QChar(uchar cell, uchar row)
+
+ Constructs a QChar for Unicode cell \a cell in row \a row.
+
+ \sa cell(), row()
+*/
+
+/*!
+ \fn QChar::QChar(ushort code)
+
+ Constructs a QChar for the character with Unicode code point \a code.
+*/
+
+/*!
+ \fn QChar::QChar(short code)
+
+ Constructs a QChar for the character with Unicode code point \a code.
+*/
+
+/*!
+ \fn QChar::QChar(uint code)
+
+ Constructs a QChar for the character with Unicode code point \a code.
+*/
+
+/*!
+ \fn QChar::QChar(int code)
+
+ Constructs a QChar for the character with Unicode code point \a code.
+*/
+
+/*!
+ \fn bool QChar::isNull() const
+
+ Returns \c true if the character is the Unicode character 0x0000
+ ('\\0'); otherwise returns \c false.
+*/
+
+/*!
+ \fn uchar QChar::cell() const
+
+ Returns the cell (least significant byte) of the Unicode character.
+
+ \sa row()
+*/
+
+/*!
+ \fn uchar QChar::row() const
+
+ Returns the row (most significant byte) of the Unicode character.
+
+ \sa cell()
+*/
+
+/*!
+ \fn bool QChar::isPrint() const
+
+ Returns \c true if the character is a printable character; otherwise
+ returns \c false. This is any character not of category Other_*.
+
+ Note that this gives no indication of whether the character is
+ available in a particular font.
+*/
+
+/*!
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
+ a printable character; otherwise returns \c false.
+ This is any character not of category Other_*.
+
+ Note that this gives no indication of whether the character is
+ available in a particular font.
+*/
+bool QChar::isPrint(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return false;
+ const int test = FLAG(Other_Control) |
+ FLAG(Other_Format) |
+ FLAG(Other_Surrogate) |
+ FLAG(Other_PrivateUse) |
+ FLAG(Other_NotAssigned);
+ return !(FLAG(qGetProp(ucs4)->category) & test);
+}
+
+/*!
+ \fn bool QChar::isSpace() const
+
+ Returns \c true if the character is a separator character
+ (Separator_* categories or certain code points from Other_Control category);
+ otherwise returns \c false.
+*/
+
+/*!
+ \fn bool QChar::isSpace(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
+ a separator character (Separator_* categories or certain code points
+ from Other_Control category); otherwise returns \c false.
+*/
+
+/*!
+ \internal
+*/
+bool QT_FASTCALL QChar::isSpace_helper(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return false;
+ const int test = FLAG(Separator_Space) |
+ FLAG(Separator_Line) |
+ FLAG(Separator_Paragraph);
+ return FLAG(qGetProp(ucs4)->category) & test;
+}
+
+/*!
+ \fn bool QChar::isMark() const
+
+ Returns \c true if the character is a mark (Mark_* categories);
+ otherwise returns \c false.
+
+ See QChar::Category for more information regarding marks.
+*/
+
+/*!
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
+ a mark (Mark_* categories); otherwise returns \c false.
+*/
+bool QChar::isMark(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return false;
+ const int test = FLAG(Mark_NonSpacing) |
+ FLAG(Mark_SpacingCombining) |
+ FLAG(Mark_Enclosing);
+ return FLAG(qGetProp(ucs4)->category) & test;
+}
+
+/*!
+ \fn bool QChar::isPunct() const
+
+ Returns \c true if the character is a punctuation mark (Punctuation_*
+ categories); otherwise returns \c false.
+*/
+
+/*!
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
+ a punctuation mark (Punctuation_* categories); otherwise returns \c false.
+*/
+bool QChar::isPunct(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return false;
+ const int test = FLAG(Punctuation_Connector) |
+ FLAG(Punctuation_Dash) |
+ FLAG(Punctuation_Open) |
+ FLAG(Punctuation_Close) |
+ FLAG(Punctuation_InitialQuote) |
+ FLAG(Punctuation_FinalQuote) |
+ FLAG(Punctuation_Other);
+ return FLAG(qGetProp(ucs4)->category) & test;
+}
+
+/*!
+ \fn bool QChar::isSymbol() const
+
+ Returns \c true if the character is a symbol (Symbol_* categories);
+ otherwise returns \c false.
+*/
+
+/*!
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
+ a symbol (Symbol_* categories); otherwise returns \c false.
+*/
+bool QChar::isSymbol(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return false;
+ const int test = FLAG(Symbol_Math) |
+ FLAG(Symbol_Currency) |
+ FLAG(Symbol_Modifier) |
+ FLAG(Symbol_Other);
+ return FLAG(qGetProp(ucs4)->category) & test;
+}
+
+/*!
+ \fn bool QChar::isLetter() const
+
+ Returns \c true if the character is a letter (Letter_* categories);
+ otherwise returns \c false.
+*/
+
+/*!
+ \fn bool QChar::isLetter(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
+ a letter (Letter_* categories); otherwise returns \c false.
+*/
+
+/*!
+ \internal
+*/
+bool QT_FASTCALL QChar::isLetter_helper(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return false;
+ const int test = FLAG(Letter_Uppercase) |
+ FLAG(Letter_Lowercase) |
+ FLAG(Letter_Titlecase) |
+ FLAG(Letter_Modifier) |
+ FLAG(Letter_Other);
+ return FLAG(qGetProp(ucs4)->category) & test;
+}
+
+/*!
+ \fn bool QChar::isNumber() const
+
+ Returns \c true if the character is a number (Number_* categories,
+ not just 0-9); otherwise returns \c false.
+
+ \sa isDigit()
+*/
+
+/*!
+ \fn bool QChar::isNumber(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
+ a number (Number_* categories, not just 0-9); otherwise returns \c false.
+
+ \sa isDigit()
+*/
+
+/*!
+ \internal
+*/
+bool QT_FASTCALL QChar::isNumber_helper(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return false;
+ const int test = FLAG(Number_DecimalDigit) |
+ FLAG(Number_Letter) |
+ FLAG(Number_Other);
+ return FLAG(qGetProp(ucs4)->category) & test;
+}
+
+/*!
+ \fn bool QChar::isLetterOrNumber() const
+
+ Returns \c true if the character is a letter or number (Letter_* or
+ Number_* categories); otherwise returns \c false.
+*/
+
+/*!
+ \fn bool QChar::isLetterOrNumber(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
+ a letter or number (Letter_* or Number_* categories); otherwise returns \c false.
+*/
+
+/*!
+ \internal
+*/
+bool QT_FASTCALL QChar::isLetterOrNumber_helper(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return false;
+ const int test = FLAG(Letter_Uppercase) |
+ FLAG(Letter_Lowercase) |
+ FLAG(Letter_Titlecase) |
+ FLAG(Letter_Modifier) |
+ FLAG(Letter_Other) |
+ FLAG(Number_DecimalDigit) |
+ FLAG(Number_Letter) |
+ FLAG(Number_Other);
+ return FLAG(qGetProp(ucs4)->category) & test;
+}
+
+/*!
+ \fn bool QChar::isDigit() const
+
+ Returns \c true if the character is a decimal digit
+ (Number_DecimalDigit); otherwise returns \c false.
+
+ \sa isNumber()
+*/
+
+/*!
+ \fn bool QChar::isDigit(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4 is
+ a decimal digit (Number_DecimalDigit); otherwise returns \c false.
+
+ \sa isNumber()
+*/
+
+/*!
+ \fn bool QChar::isNonCharacter() const
+ \since 5.0
+
+ Returns \c true if the QChar is a non-character; false otherwise.
+
+ Unicode has a certain number of code points that are classified
+ as "non-characters:" that is, they can be used for internal purposes
+ in applications but cannot be used for text interchange.
+ Those are the last two entries each Unicode Plane ([0xfffe..0xffff],
+ [0x1fffe..0x1ffff], etc.) as well as the entries in range [0xfdd0..0xfdef].
+*/
+
+/*!
+ \fn bool QChar::isHighSurrogate() const
+
+ Returns \c true if the QChar is the high part of a UTF16 surrogate
+ (for example if its code point is in range [0xd800..0xdbff]); false otherwise.
+*/
+
+/*!
+ \fn bool QChar::isLowSurrogate() const
+
+ Returns \c true if the QChar is the low part of a UTF16 surrogate
+ (for example if its code point is in range [0xdc00..0xdfff]); false otherwise.
+*/
+
+/*!
+ \fn bool QChar::isSurrogate() const
+ \since 5.0
+
+ Returns \c true if the QChar contains a code point that is in either
+ the high or the low part of the UTF-16 surrogate range
+ (for example if its code point is in range [0xd800..0xdfff]); false otherwise.
+*/
+
+/*!
+ \fn static bool QChar::isNonCharacter(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4
+ is a non-character; false otherwise.
+
+ Unicode has a certain number of code points that are classified
+ as "non-characters:" that is, they can be used for internal purposes
+ in applications but cannot be used for text interchange.
+ Those are the last two entries each Unicode Plane ([0xfffe..0xffff],
+ [0x1fffe..0x1ffff], etc.) as well as the entries in range [0xfdd0..0xfdef].
+*/
+
+/*!
+ \fn static bool QChar::isHighSurrogate(uint ucs4)
+ \overload
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4
+ is the high part of a UTF16 surrogate
+ (for example if its code point is in range [0xd800..0xdbff]); false otherwise.
+*/
+
+/*!
+ \fn static bool QChar::isLowSurrogate(uint ucs4)
+ \overload
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4
+ is the low part of a UTF16 surrogate
+ (for example if its code point is in range [0xdc00..0xdfff]); false otherwise.
+*/
+
+/*!
+ \fn static bool QChar::isSurrogate(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4
+ contains a code point that is in either the high or the low part of the
+ UTF-16 surrogate range (for example if its code point is in range [0xd800..0xdfff]);
+ false otherwise.
+*/
+
+/*!
+ \fn static bool QChar::requiresSurrogates(uint ucs4)
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4
+ can be split into the high and low parts of a UTF16 surrogate
+ (for example if its code point is greater than or equals to 0x10000);
+ false otherwise.
+*/
+
+/*!
+ \fn static uint QChar::surrogateToUcs4(ushort high, ushort low)
+
+ Converts a UTF16 surrogate pair with the given \a high and \a low values
+ to it's UCS-4-encoded code point.
+*/
+
+/*!
+ \fn static uint QChar::surrogateToUcs4(QChar high, QChar low)
+ \overload
+
+ Converts a UTF16 surrogate pair (\a high, \a low) to it's UCS-4-encoded code point.
+*/
+
+/*!
+ \fn static ushort QChar::highSurrogate(uint ucs4)
+
+ Returns the high surrogate part of a UCS-4-encoded code point.
+ The returned result is undefined if \a ucs4 is smaller than 0x10000.
+*/
+
+/*!
+ \fn static ushort QChar::lowSurrogate(uint ucs4)
+
+ Returns the low surrogate part of a UCS-4-encoded code point.
+ The returned result is undefined if \a ucs4 is smaller than 0x10000.
+*/
+
+/*!
+ \fn int QChar::digitValue() const
+
+ Returns the numeric value of the digit, or -1 if the character is not a digit.
+*/
+
+/*!
+ \overload
+ Returns the numeric value of the digit specified by the UCS-4-encoded
+ character, \a ucs4, or -1 if the character is not a digit.
+*/
+int QChar::digitValue(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return -1;
+ return qGetProp(ucs4)->digitValue;
+}
+
+/*!
+ \fn QChar::Category QChar::category() const
+
+ Returns the character's category.
+*/
+
+/*!
+ \overload
+ Returns the category of the UCS-4-encoded character specified by \a ucs4.
+*/
+QChar::Category QChar::category(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return QChar::Other_NotAssigned;
+ return (QChar::Category) qGetProp(ucs4)->category;
+}
+
+/*!
+ \fn QChar::Direction QChar::direction() const
+
+ Returns the character's direction.
+*/
+
+/*!
+ \overload
+ Returns the direction of the UCS-4-encoded character specified by \a ucs4.
+*/
+QChar::Direction QChar::direction(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return QChar::DirL;
+ return (QChar::Direction) qGetProp(ucs4)->direction;
+}
+
+/*!
+ \fn QChar::JoiningType QChar::joiningType() const
+ \since 5.3
+
+ Returns information about the joining type attributes of the character
+ (needed for certain languages such as Arabic or Syriac).
+*/
+
+/*!
+ \overload
+ \since 5.3
+
+ Returns information about the joining type attributes of the UCS-4-encoded
+ character specified by \a ucs4
+ (needed for certain languages such as Arabic or Syriac).
+*/
+QChar::JoiningType QChar::joiningType(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return QChar::Joining_None;
+ return QChar::JoiningType(qGetProp(ucs4)->joining);
+}
+
+#if QT_DEPRECATED_SINCE(5, 3)
+/*!
+ \fn QChar::Joining QChar::joining() const
+ \deprecated in 5.3, use joiningType() instead.
+
+ Returns information about the joining properties of the character
+ (needed for certain languages such as Arabic).
+*/
+
+/*!
+ \overload
+ \deprecated in 5.3, use joiningType() instead.
+
+ Returns information about the joining properties of the UCS-4-encoded
+ character specified by \a ucs4 (needed for certain languages such as Arabic).
+*/
+QChar::Joining QChar::joining(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return QChar::OtherJoining;
+ switch (qGetProp(ucs4)->joining) {
+ case QChar::Joining_Causing: return QChar::Center;
+ case QChar::Joining_Dual: return QChar::Dual;
+ case QChar::Joining_Right: return QChar::Right;
+ default: break;
+ }
+ return QChar::OtherJoining;
+}
+#endif
+
+/*!
+ \fn bool QChar::hasMirrored() const
+
+ Returns \c true if the character should be reversed if the text
+ direction is reversed; otherwise returns \c false.
+
+ A bit faster equivalent of (ch.mirroredChar() != ch).
+
+ \sa mirroredChar()
+*/
+
+/*!
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4
+ should be reversed if the text direction is reversed; otherwise returns \c false.
+
+ A bit faster equivalent of (QChar::mirroredChar(ucs4) != ucs4).
+
+ \sa mirroredChar()
+*/
+bool QChar::hasMirrored(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return false;
+ return qGetProp(ucs4)->mirrorDiff != 0;
+}
+
+/*!
+ \fn bool QChar::isLower() const
+
+ Returns \c true if the character is a lowercase letter, for example
+ category() is Letter_Lowercase.
+
+ \sa isUpper(), toLower(), toUpper()
+*/
+
+/*!
+ \fn static bool QChar::isLower(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4
+ is a lowercase letter, for example category() is Letter_Lowercase.
+
+ \sa isUpper(), toLower(), toUpper()
+*/
+
+/*!
+ \fn bool QChar::isUpper() const
+
+ Returns \c true if the character is an uppercase letter, for example
+ category() is Letter_Uppercase.
+
+ \sa isLower(), toUpper(), toLower()
+*/
+
+/*!
+ \fn static bool QChar::isUpper(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4
+ is an uppercase letter, for example category() is Letter_Uppercase.
+
+ \sa isLower(), toUpper(), toLower()
+*/
+
+/*!
+ \fn bool QChar::isTitleCase() const
+
+ Returns \c true if the character is a titlecase letter, for example
+ category() is Letter_Titlecase.
+
+ \sa isLower(), toUpper(), toLower(), toTitleCase()
+*/
+
+/*!
+ \fn static bool QChar::isTitleCase(uint ucs4)
+ \overload
+ \since 5.0
+
+ Returns \c true if the UCS-4-encoded character specified by \a ucs4
+ is a titlecase letter, for example category() is Letter_Titlecase.
+
+ \sa isLower(), toUpper(), toLower(), toTitleCase()
+*/
+/*!
+ \fn QChar QChar::mirroredChar() const
+
+ Returns the mirrored character if this character is a mirrored
+ character; otherwise returns the character itself.
+
+ \sa hasMirrored()
+*/
+
+/*!
+ \overload
+ Returns the mirrored character if the UCS-4-encoded character specified
+ by \a ucs4 is a mirrored character; otherwise returns the character itself.
+
+ \sa hasMirrored()
+*/
+uint QChar::mirroredChar(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return ucs4;
+ return ucs4 + qGetProp(ucs4)->mirrorDiff;
+}
+
+
+// constants for Hangul (de)composition, see UAX #15
+enum {
+ Hangul_SBase = 0xac00,
+ Hangul_LBase = 0x1100,
+ Hangul_VBase = 0x1161,
+ Hangul_TBase = 0x11a7,
+ Hangul_LCount = 19,
+ Hangul_VCount = 21,
+ Hangul_TCount = 28,
+ Hangul_NCount = Hangul_VCount * Hangul_TCount,
+ Hangul_SCount = Hangul_LCount * Hangul_NCount
+};
+
+// buffer has to have a length of 3. It's needed for Hangul decomposition
+static const unsigned short * QT_FASTCALL decompositionHelper
+ (uint ucs4, int *length, int *tag, unsigned short *buffer)
+{
+ if (ucs4 >= Hangul_SBase && ucs4 < Hangul_SBase + Hangul_SCount) {
+ // compute Hangul syllable decomposition as per UAX #15
+ const uint SIndex = ucs4 - Hangul_SBase;
+ buffer[0] = Hangul_LBase + SIndex / Hangul_NCount; // L
+ buffer[1] = Hangul_VBase + (SIndex % Hangul_NCount) / Hangul_TCount; // V
+ buffer[2] = Hangul_TBase + SIndex % Hangul_TCount; // T
+ *length = buffer[2] == Hangul_TBase ? 2 : 3;
+ *tag = QChar::Canonical;
+ return buffer;
+ }
+
+ const unsigned short index = GET_DECOMPOSITION_INDEX(ucs4);
+ if (index == 0xffff) {
+ *length = 0;
+ *tag = QChar::NoDecomposition;
+ return nullptr;
+ }
+
+ const unsigned short *decomposition = uc_decomposition_map+index;
+ *tag = (*decomposition) & 0xff;
+ *length = (*decomposition) >> 8;
+ return decomposition+1;
+}
+
+/*!
+ Decomposes a character into it's constituent parts. Returns an empty string
+ if no decomposition exists.
+*/
+QString QChar::decomposition() const
+{
+ return QChar::decomposition(ucs);
+}
+
+/*!
+ \overload
+ Decomposes the UCS-4-encoded character specified by \a ucs4 into it's
+ constituent parts. Returns an empty string if no decomposition exists.
+*/
+QString QChar::decomposition(uint ucs4)
+{
+ unsigned short buffer[3];
+ int length;
+ int tag;
+ const unsigned short *d = decompositionHelper(ucs4, &length, &tag, buffer);
+ return QString(reinterpret_cast<const QChar *>(d), length);
+}
+
+/*!
+ \fn QChar::Decomposition QChar::decompositionTag() const
+
+ Returns the tag defining the composition of the character. Returns
+ QChar::NoDecomposition if no decomposition exists.
+*/
+
+/*!
+ \overload
+ Returns the tag defining the composition of the UCS-4-encoded character
+ specified by \a ucs4. Returns QChar::NoDecomposition if no decomposition exists.
+*/
+QChar::Decomposition QChar::decompositionTag(uint ucs4) noexcept
+{
+ if (ucs4 >= Hangul_SBase && ucs4 < Hangul_SBase + Hangul_SCount)
+ return QChar::Canonical;
+ const unsigned short index = GET_DECOMPOSITION_INDEX(ucs4);
+ if (index == 0xffff)
+ return QChar::NoDecomposition;
+ return (QChar::Decomposition)(uc_decomposition_map[index] & 0xff);
+}
+
+/*!
+ \fn unsigned char QChar::combiningClass() const
+
+ Returns the combining class for the character as defined in the
+ Unicode standard. This is mainly useful as a positioning hint for
+ marks attached to a base character.
+
+ The Qt text rendering engine uses this information to correctly
+ position non-spacing marks around a base character.
+*/
+
+/*!
+ \overload
+ Returns the combining class for the UCS-4-encoded character specified by
+ \a ucs4, as defined in the Unicode standard.
+*/
+unsigned char QChar::combiningClass(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return 0;
+ return (unsigned char) qGetProp(ucs4)->combiningClass;
+}
+
+/*!
+ \fn QChar::Script QChar::script() const
+ \since 5.1
+
+ Returns the Unicode script property value for this character.
+*/
+
+/*!
+ \overload
+ \since 5.1
+
+ Returns the Unicode script property value for the character specified in
+ its UCS-4-encoded form as \a ucs4.
+*/
+QChar::Script QChar::script(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return QChar::Script_Unknown;
+ return (QChar::Script) qGetProp(ucs4)->script;
+}
+
+/*!
+ \fn QChar::UnicodeVersion QChar::unicodeVersion() const
+
+ Returns the Unicode version that introduced this character.
+*/
+
+/*!
+ \overload
+ Returns the Unicode version that introduced the character specified in
+ its UCS-4-encoded form as \a ucs4.
+*/
+QChar::UnicodeVersion QChar::unicodeVersion(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return QChar::Unicode_Unassigned;
+ return (QChar::UnicodeVersion) qGetProp(ucs4)->unicodeVersion;
+}
+
+/*!
+ Returns the most recent supported Unicode version.
+*/
+QChar::UnicodeVersion QChar::currentUnicodeVersion() noexcept
+{
+ return UNICODE_DATA_VERSION;
+}
+
+
+template <typename Traits, typename T>
+Q_DECL_CONST_FUNCTION static inline T convertCase_helper(T uc) noexcept
+{
+ const QUnicodeTables::Properties *prop = qGetProp(uc);
+
+ if (Q_UNLIKELY(Traits::caseSpecial(prop))) {
+ const ushort *specialCase = specialCaseMap + Traits::caseDiff(prop);
+ // so far, there are no special cases beyond BMP (guaranteed by the qunicodetables generator)
+ return *specialCase == 1 ? specialCase[1] : uc;
+ }
+
+ return uc + Traits::caseDiff(prop);
+}
+
+/*!
+ \fn QChar QChar::toLower() const
+
+ Returns the lowercase equivalent if the character is uppercase or titlecase;
+ otherwise returns the character itself.
+*/
+
+/*!
+ \overload
+ Returns the lowercase equivalent of the UCS-4-encoded character specified
+ by \a ucs4 if the character is uppercase or titlecase; otherwise returns
+ the character itself.
+*/
+uint QChar::toLower(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return ucs4;
+ return convertCase_helper<QUnicodeTables::LowercaseTraits>(ucs4);
+}
+
+/*!
+ \fn QChar QChar::toUpper() const
+
+ Returns the uppercase equivalent if the character is lowercase or titlecase;
+ otherwise returns the character itself.
+*/
+
+/*!
+ \overload
+ Returns the uppercase equivalent of the UCS-4-encoded character specified
+ by \a ucs4 if the character is lowercase or titlecase; otherwise returns
+ the character itself.
+*/
+uint QChar::toUpper(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return ucs4;
+ return convertCase_helper<QUnicodeTables::UppercaseTraits>(ucs4);
+}
+
+/*!
+ \fn QChar QChar::toTitleCase() const
+
+ Returns the title case equivalent if the character is lowercase or uppercase;
+ otherwise returns the character itself.
+*/
+
+/*!
+ \overload
+ Returns the title case equivalent of the UCS-4-encoded character specified
+ by \a ucs4 if the character is lowercase or uppercase; otherwise returns
+ the character itself.
+*/
+uint QChar::toTitleCase(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return ucs4;
+ return convertCase_helper<QUnicodeTables::TitlecaseTraits>(ucs4);
+}
+
+static inline uint foldCase(const ushort *ch, const ushort *start)
+{
+ uint ucs4 = *ch;
+ if (QChar::isLowSurrogate(ucs4) && ch > start && QChar::isHighSurrogate(*(ch - 1)))
+ ucs4 = QChar::surrogateToUcs4(*(ch - 1), ucs4);
+ return convertCase_helper<QUnicodeTables::CasefoldTraits>(ucs4);
+}
+
+static inline uint foldCase(uint ch, uint &last) noexcept
+{
+ uint ucs4 = ch;
+ if (QChar::isLowSurrogate(ucs4) && QChar::isHighSurrogate(last))
+ ucs4 = QChar::surrogateToUcs4(last, ucs4);
+ last = ch;
+ return convertCase_helper<QUnicodeTables::CasefoldTraits>(ucs4);
+}
+
+static inline ushort foldCase(ushort ch) noexcept
+{
+ return convertCase_helper<QUnicodeTables::CasefoldTraits>(ch);
+}
+
+static inline QChar foldCase(QChar ch) noexcept
+{
+ return QChar(foldCase(ch.unicode()));
+}
+
+/*!
+ \fn QChar QChar::toCaseFolded() const
+
+ Returns the case folded equivalent of the character.
+ For most Unicode characters this is the same as toLower().
+*/
+
+/*!
+ \overload
+ Returns the case folded equivalent of the UCS-4-encoded character specified
+ by \a ucs4. For most Unicode characters this is the same as toLower().
+*/
+uint QChar::toCaseFolded(uint ucs4) noexcept
+{
+ if (ucs4 > LastValidCodePoint)
+ return ucs4;
+ return convertCase_helper<QUnicodeTables::CasefoldTraits>(ucs4);
+}
+
+/*!
+ \fn char QChar::toLatin1() const
+
+ Returns the Latin-1 character equivalent to the QChar, or 0. This
+ is mainly useful for non-internationalized software.
+
+ \note It is not possible to distinguish a non-Latin-1 character from a Latin-1 0
+ (NUL) character. Prefer to use unicode(), which does not have this ambiguity.
+
+ \sa unicode()
+*/
+
+/*!
+ \fn QChar QChar::fromLatin1(char)
+
+ Converts the Latin-1 character \a c to its equivalent QChar. This
+ is mainly useful for non-internationalized software.
+
+ An alternative is to use QLatin1Char.
+
+ \sa toLatin1(), unicode()
+*/
+
+/*!
+ \fn char QChar::toAscii() const
+ \deprecated
+
+ Returns the Latin-1 character value of the QChar, or 0 if the character is not
+ representable.
+
+ The main purpose of this function is to preserve ASCII characters used
+ in C strings. This is mainly useful for developers of non-internationalized
+ software.
+
+ \note It is not possible to distinguish a non-Latin 1 character from an ASCII 0
+ (NUL) character. Prefer to use unicode(), which does not have this ambiguity.
+
+ \note This function does not check whether the character value is inside
+ the valid range of US-ASCII.
+
+ \sa toLatin1(), unicode()
+*/
+
+/*!
+ \fn QChar QChar::fromAscii(char)
+ \deprecated
+
+ Converts the ASCII character \a c to it's equivalent QChar. This
+ is mainly useful for non-internationalized software.
+
+ An alternative is to use QLatin1Char.
+
+ \sa fromLatin1(), unicode()
+*/
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \relates QChar
+
+ Writes the char \a chr to the stream \a out.
+
+ \sa {Serializing Qt Data Types}
+*/
+QDataStream &operator<<(QDataStream &out, QChar chr)
+{
+ out << quint16(chr.unicode());
+ return out;
+}
+
+/*!
+ \relates QChar
+
+ Reads a char from the stream \a in into char \a chr.
+
+ \sa {Serializing Qt Data Types}
+*/
+QDataStream &operator>>(QDataStream &in, QChar &chr)
+{
+ quint16 u;
+ in >> u;
+ chr.unicode() = ushort(u);
+ return in;
+}
+#endif // QT_NO_DATASTREAM
+
+/*!
+ \fn ushort & QChar::unicode()
+
+ Returns a reference to the numeric Unicode value of the QChar.
+*/
+
+/*!
+ \fn ushort QChar::unicode() const
+
+ Returns the numeric Unicode value of the QChar.
+*/
+
+/*****************************************************************************
+ Documentation of QChar related functions
+ *****************************************************************************/
+
+/*!
+ \fn bool operator==(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns \c true if \a c1 and \a c2 are the same Unicode character;
+ otherwise returns \c false.
+*/
+
+/*!
+ \fn int operator!=(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns \c true if \a c1 and \a c2 are not the same Unicode
+ character; otherwise returns \c false.
+*/
+
+/*!
+ \fn int operator<=(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns \c true if the numeric Unicode value of \a c1 is less than
+ or equal to that of \a c2; otherwise returns \c false.
+*/
+
+/*!
+ \fn int operator>=(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns \c true if the numeric Unicode value of \a c1 is greater than
+ or equal to that of \a c2; otherwise returns \c false.
+*/
+
+/*!
+ \fn int operator<(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns \c true if the numeric Unicode value of \a c1 is less than
+ that of \a c2; otherwise returns \c false.
+*/
+
+/*!
+ \fn int operator>(QChar c1, QChar c2)
+
+ \relates QChar
+
+ Returns \c true if the numeric Unicode value of \a c1 is greater than
+ that of \a c2; otherwise returns \c false.
+*/
+
+
+// ---------------------------------------------------------------------------
+
+
+static void decomposeHelper(QString *str, bool canonical, QChar::UnicodeVersion version, int from)
+{
+ int length;
+ int tag;
+ unsigned short buffer[3];
+
+ QString &s = *str;
+
+ const unsigned short *utf16 = reinterpret_cast<unsigned short *>(s.data());
+ const unsigned short *uc = utf16 + s.length();
+ while (uc != utf16 + from) {
+ uint ucs4 = *(--uc);
+ if (QChar(ucs4).isLowSurrogate() && uc != utf16) {
+ ushort high = *(uc - 1);
+ if (QChar(high).isHighSurrogate()) {
+ --uc;
+ ucs4 = QChar::surrogateToUcs4(high, ucs4);
+ }
+ }
+
+ if (QChar::unicodeVersion(ucs4) > version)
+ continue;
+
+ const unsigned short *d = decompositionHelper(ucs4, &length, &tag, buffer);
+ if (!d || (canonical && tag != QChar::Canonical))
+ continue;
+
+ int pos = uc - utf16;
+ s.replace(pos, QChar::requiresSurrogates(ucs4) ? 2 : 1, reinterpret_cast<const QChar *>(d), length);
+ // since the replace invalidates the pointers and we do decomposition recursive
+ utf16 = reinterpret_cast<unsigned short *>(s.data());
+ uc = utf16 + pos + length;
+ }
+}
+
+
+struct UCS2Pair {
+ ushort u1;
+ ushort u2;
+};
+
+inline bool operator<(const UCS2Pair &ligature1, const UCS2Pair &ligature2)
+{ return ligature1.u1 < ligature2.u1; }
+inline bool operator<(ushort u1, const UCS2Pair &ligature)
+{ return u1 < ligature.u1; }
+inline bool operator<(const UCS2Pair &ligature, ushort u1)
+{ return ligature.u1 < u1; }
+
+struct UCS2SurrogatePair {
+ UCS2Pair p1;
+ UCS2Pair p2;
+};
+
+inline bool operator<(const UCS2SurrogatePair &ligature1, const UCS2SurrogatePair &ligature2)
+{ return QChar::surrogateToUcs4(ligature1.p1.u1, ligature1.p1.u2) < QChar::surrogateToUcs4(ligature2.p1.u1, ligature2.p1.u2); }
+inline bool operator<(uint u1, const UCS2SurrogatePair &ligature)
+{ return u1 < QChar::surrogateToUcs4(ligature.p1.u1, ligature.p1.u2); }
+inline bool operator<(const UCS2SurrogatePair &ligature, uint u1)
+{ return QChar::surrogateToUcs4(ligature.p1.u1, ligature.p1.u2) < u1; }
+
+static uint inline ligatureHelper(uint u1, uint u2)
+{
+ if (u1 >= Hangul_LBase && u1 <= Hangul_SBase + Hangul_SCount) {
+ // compute Hangul syllable composition as per UAX #15
+ // hangul L-V pair
+ const uint LIndex = u1 - Hangul_LBase;
+ if (LIndex < Hangul_LCount) {
+ const uint VIndex = u2 - Hangul_VBase;
+ if (VIndex < Hangul_VCount)
+ return Hangul_SBase + (LIndex * Hangul_VCount + VIndex) * Hangul_TCount;
+ }
+ // hangul LV-T pair
+ const uint SIndex = u1 - Hangul_SBase;
+ if (SIndex < Hangul_SCount && (SIndex % Hangul_TCount) == 0) {
+ const uint TIndex = u2 - Hangul_TBase;
+ if (TIndex <= Hangul_TCount)
+ return u1 + TIndex;
+ }
+ }
+
+ const unsigned short index = GET_LIGATURE_INDEX(u2);
+ if (index == 0xffff)
+ return 0;
+ const unsigned short *ligatures = uc_ligature_map+index;
+ ushort length = *ligatures++;
+ if (QChar::requiresSurrogates(u1)) {
+ const UCS2SurrogatePair *data = reinterpret_cast<const UCS2SurrogatePair *>(ligatures);
+ const UCS2SurrogatePair *r = std::lower_bound(data, data + length, u1);
+ if (r != data + length && QChar::surrogateToUcs4(r->p1.u1, r->p1.u2) == u1)
+ return QChar::surrogateToUcs4(r->p2.u1, r->p2.u2);
+ } else {
+ const UCS2Pair *data = reinterpret_cast<const UCS2Pair *>(ligatures);
+ const UCS2Pair *r = std::lower_bound(data, data + length, ushort(u1));
+ if (r != data + length && r->u1 == ushort(u1))
+ return r->u2;
+ }
+
+ return 0;
+}
+
+static void composeHelper(QString *str, QChar::UnicodeVersion version, int from)
+{
+ QString &s = *str;
+
+ if (from < 0 || s.length() - from < 2)
+ return;
+
+ uint stcode = 0; // starter code point
+ int starter = -1; // starter position
+ int next = -1; // to prevent i == next
+ int lastCombining = 255; // to prevent combining > lastCombining
+
+ int pos = from;
+ while (pos < s.length()) {
+ int i = pos;
+ uint uc = s.at(pos).unicode();
+ if (QChar(uc).isHighSurrogate() && pos < s.length()-1) {
+ ushort low = s.at(pos+1).unicode();
+ if (QChar(low).isLowSurrogate()) {
+ uc = QChar::surrogateToUcs4(uc, low);
+ ++pos;
+ }
+ }
+
+ const QUnicodeTables::Properties *p = qGetProp(uc);
+ if (p->unicodeVersion > version) {
+ starter = -1;
+ next = -1; // to prevent i == next
+ lastCombining = 255; // to prevent combining > lastCombining
+ ++pos;
+ continue;
+ }
+
+ int combining = p->combiningClass;
+ if ((i == next || combining > lastCombining) && starter >= from) {
+ // allowed to form ligature with S
+ uint ligature = ligatureHelper(stcode, uc);
+ if (ligature) {
+ stcode = ligature;
+ QChar *d = s.data();
+ // ligatureHelper() never changes planes
+ if (QChar::requiresSurrogates(ligature)) {
+ d[starter] = QChar(QChar::highSurrogate(ligature));
+ d[starter + 1] = QChar(QChar::lowSurrogate(ligature));
+ s.remove(i, 2);
+ } else {
+ d[starter] = QChar(ligature);
+ s.remove(i, 1);
+ }
+ continue;
+ }
+ }
+ if (combining == 0) {
+ starter = i;
+ stcode = uc;
+ next = pos + 1;
+ }
+ lastCombining = combining;
+
+ ++pos;
+ }
+}
+
+
+static void canonicalOrderHelper(QString *str, QChar::UnicodeVersion version, int from)
+{
+ QString &s = *str;
+ const int l = s.length()-1;
+
+ uint u1, u2;
+ ushort c1, c2;
+
+ int pos = from;
+ while (pos < l) {
+ int p2 = pos+1;
+ u1 = s.at(pos).unicode();
+ if (QChar(u1).isHighSurrogate()) {
+ ushort low = s.at(p2).unicode();
+ if (QChar(low).isLowSurrogate()) {
+ u1 = QChar::surrogateToUcs4(u1, low);
+ if (p2 >= l)
+ break;
+ ++p2;
+ }
+ }
+ c1 = 0;
+
+ advance:
+ u2 = s.at(p2).unicode();
+ if (QChar(u2).isHighSurrogate() && p2 < l) {
+ ushort low = s.at(p2+1).unicode();
+ if (QChar(low).isLowSurrogate()) {
+ u2 = QChar::surrogateToUcs4(u2, low);
+ ++p2;
+ }
+ }
+
+ c2 = 0;
+ {
+ const QUnicodeTables::Properties *p = qGetProp(u2);
+ if (p->unicodeVersion <= version)
+ c2 = p->combiningClass;
+ }
+ if (c2 == 0) {
+ pos = p2+1;
+ continue;
+ }
+
+ if (c1 == 0) {
+ const QUnicodeTables::Properties *p = qGetProp(u1);
+ if (p->unicodeVersion <= version)
+ c1 = p->combiningClass;
+ }
+
+ if (c1 > c2) {
+ QChar *uc = s.data();
+ int p = pos;
+ // exchange characters
+ if (!QChar::requiresSurrogates(u2)) {
+ uc[p++] = QChar(u2);
+ } else {
+ uc[p++] = QChar(QChar::highSurrogate(u2));
+ uc[p++] = QChar(QChar::lowSurrogate(u2));
+ }
+ if (!QChar::requiresSurrogates(u1)) {
+ uc[p++] = QChar(u1);
+ } else {
+ uc[p++] = QChar(QChar::highSurrogate(u1));
+ uc[p++] = QChar(QChar::lowSurrogate(u1));
+ }
+ if (pos > 0)
+ --pos;
+ if (pos > 0 && s.at(pos).isLowSurrogate())
+ --pos;
+ } else {
+ ++pos;
+ if (QChar::requiresSurrogates(u1))
+ ++pos;
+
+ u1 = u2;
+ c1 = c2; // != 0
+ p2 = pos + 1;
+ if (QChar::requiresSurrogates(u1))
+ ++p2;
+ if (p2 > l)
+ break;
+
+ goto advance;
+ }
+ }
+}
+
+// returns true if the text is in a desired Normalization Form already; false otherwise.
+// sets lastStable to the position of the last stable code point
+static bool normalizationQuickCheckHelper(QString *str, QString::NormalizationForm mode, int from, int *lastStable)
+{
+ Q_STATIC_ASSERT(QString::NormalizationForm_D == 0);
+ Q_STATIC_ASSERT(QString::NormalizationForm_C == 1);
+ Q_STATIC_ASSERT(QString::NormalizationForm_KD == 2);
+ Q_STATIC_ASSERT(QString::NormalizationForm_KC == 3);
+
+ enum { NFQC_YES = 0, NFQC_NO = 1, NFQC_MAYBE = 3 };
+
+ const ushort *string = reinterpret_cast<const ushort *>(str->constData());
+ int length = str->length();
+
+ // this avoids one out of bounds check in the loop
+ while (length > from && QChar::isHighSurrogate(string[length - 1]))
+ --length;
+
+ uchar lastCombining = 0;
+ for (int i = from; i < length; ++i) {
+ int pos = i;
+ uint uc = string[i];
+ if (uc < 0x80) {
+ // ASCII characters are stable code points
+ lastCombining = 0;
+ *lastStable = pos;
+ continue;
+ }
+
+ if (QChar::isHighSurrogate(uc)) {
+ ushort low = string[i + 1];
+ if (!QChar::isLowSurrogate(low)) {
+ // treat surrogate like stable code point
+ lastCombining = 0;
+ *lastStable = pos;
+ continue;
+ }
+ ++i;
+ uc = QChar::surrogateToUcs4(uc, low);
+ }
+
+ const QUnicodeTables::Properties *p = qGetProp(uc);
+
+ if (p->combiningClass < lastCombining && p->combiningClass > 0)
+ return false;
+
+ const uchar check = (p->nfQuickCheck >> (mode << 1)) & 0x03;
+ if (check != NFQC_YES)
+ return false; // ### can we quick check NFQC_MAYBE ?
+
+ lastCombining = p->combiningClass;
+ if (lastCombining == 0)
+ *lastStable = pos;
+ }
+
+ if (length != str->length()) // low surrogate parts at the end of text
+ *lastStable = str->length() - 1;
+
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qchar.h b/src/corelib/text/qchar.h
new file mode 100644
index 0000000000..e028a24c24
--- /dev/null
+++ b/src/corelib/text/qchar.h
@@ -0,0 +1,644 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCHAR_H
+#define QCHAR_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+
+class QString;
+
+struct QLatin1Char
+{
+public:
+ Q_DECL_CONSTEXPR inline explicit QLatin1Char(char c) noexcept : ch(c) {}
+ Q_DECL_CONSTEXPR inline char toLatin1() const noexcept { return ch; }
+ Q_DECL_CONSTEXPR inline ushort unicode() const noexcept { return ushort(uchar(ch)); }
+
+private:
+ char ch;
+};
+
+Q_DECL_CONSTEXPR inline bool operator==(char lhs, QLatin1Char rhs) noexcept { return lhs == rhs.toLatin1(); }
+Q_DECL_CONSTEXPR inline bool operator!=(char lhs, QLatin1Char rhs) noexcept { return lhs != rhs.toLatin1(); }
+Q_DECL_CONSTEXPR inline bool operator<=(char lhs, QLatin1Char rhs) noexcept { return lhs <= rhs.toLatin1(); }
+Q_DECL_CONSTEXPR inline bool operator>=(char lhs, QLatin1Char rhs) noexcept { return lhs >= rhs.toLatin1(); }
+Q_DECL_CONSTEXPR inline bool operator< (char lhs, QLatin1Char rhs) noexcept { return lhs < rhs.toLatin1(); }
+Q_DECL_CONSTEXPR inline bool operator> (char lhs, QLatin1Char rhs) noexcept { return lhs > rhs.toLatin1(); }
+
+Q_DECL_CONSTEXPR inline bool operator==(QLatin1Char lhs, char rhs) noexcept { return lhs.toLatin1() == rhs; }
+Q_DECL_CONSTEXPR inline bool operator!=(QLatin1Char lhs, char rhs) noexcept { return lhs.toLatin1() != rhs; }
+Q_DECL_CONSTEXPR inline bool operator<=(QLatin1Char lhs, char rhs) noexcept { return lhs.toLatin1() <= rhs; }
+Q_DECL_CONSTEXPR inline bool operator>=(QLatin1Char lhs, char rhs) noexcept { return lhs.toLatin1() >= rhs; }
+Q_DECL_CONSTEXPR inline bool operator< (QLatin1Char lhs, char rhs) noexcept { return lhs.toLatin1() < rhs; }
+Q_DECL_CONSTEXPR inline bool operator> (QLatin1Char lhs, char rhs) noexcept { return lhs.toLatin1() > rhs; }
+
+class Q_CORE_EXPORT QChar {
+public:
+ enum SpecialCharacter {
+ Null = 0x0000,
+ Tabulation = 0x0009,
+ LineFeed = 0x000a,
+ CarriageReturn = 0x000d,
+ Space = 0x0020,
+ Nbsp = 0x00a0,
+ SoftHyphen = 0x00ad,
+ ReplacementCharacter = 0xfffd,
+ ObjectReplacementCharacter = 0xfffc,
+ ByteOrderMark = 0xfeff,
+ ByteOrderSwapped = 0xfffe,
+ ParagraphSeparator = 0x2029,
+ LineSeparator = 0x2028,
+ LastValidCodePoint = 0x10ffff
+ };
+
+ Q_DECL_CONSTEXPR QChar() noexcept : ucs(0) {}
+ Q_DECL_CONSTEXPR QChar(ushort rc) noexcept : ucs(rc) {} // implicit
+ Q_DECL_CONSTEXPR QChar(uchar c, uchar r) noexcept : ucs(ushort((r << 8) | c)) {}
+ Q_DECL_CONSTEXPR QChar(short rc) noexcept : ucs(ushort(rc)) {} // implicit
+ Q_DECL_CONSTEXPR QChar(uint rc) noexcept : ucs(ushort(rc & 0xffff)) {}
+ Q_DECL_CONSTEXPR QChar(int rc) noexcept : ucs(ushort(rc & 0xffff)) {}
+ Q_DECL_CONSTEXPR QChar(SpecialCharacter s) noexcept : ucs(ushort(s)) {} // implicit
+ Q_DECL_CONSTEXPR QChar(QLatin1Char ch) noexcept : ucs(ch.unicode()) {} // implicit
+#if defined(Q_COMPILER_UNICODE_STRINGS)
+ Q_DECL_CONSTEXPR QChar(char16_t ch) noexcept : ucs(ushort(ch)) {} // implicit
+#endif
+#if defined(Q_OS_WIN)
+ Q_STATIC_ASSERT(sizeof(wchar_t) == sizeof(ushort));
+#endif
+#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
+# if !defined(_WCHAR_T_DEFINED) || defined(_NATIVE_WCHAR_T_DEFINED)
+ Q_DECL_CONSTEXPR QChar(wchar_t ch) noexcept : ucs(ushort(ch)) {} // implicit
+# endif
+#endif
+
+#ifndef QT_NO_CAST_FROM_ASCII
+ QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(char c) noexcept : ucs(uchar(c)) { }
+#ifndef QT_RESTRICTED_CAST_FROM_ASCII
+ QT_ASCII_CAST_WARN Q_DECL_CONSTEXPR explicit QChar(uchar c) noexcept : ucs(c) { }
+#endif
+#endif
+ // Unicode information
+
+ enum Category
+ {
+ Mark_NonSpacing, // Mn
+ Mark_SpacingCombining, // Mc
+ Mark_Enclosing, // Me
+
+ Number_DecimalDigit, // Nd
+ Number_Letter, // Nl
+ Number_Other, // No
+
+ Separator_Space, // Zs
+ Separator_Line, // Zl
+ Separator_Paragraph, // Zp
+
+ Other_Control, // Cc
+ Other_Format, // Cf
+ Other_Surrogate, // Cs
+ Other_PrivateUse, // Co
+ Other_NotAssigned, // Cn
+
+ Letter_Uppercase, // Lu
+ Letter_Lowercase, // Ll
+ Letter_Titlecase, // Lt
+ Letter_Modifier, // Lm
+ Letter_Other, // Lo
+
+ Punctuation_Connector, // Pc
+ Punctuation_Dash, // Pd
+ Punctuation_Open, // Ps
+ Punctuation_Close, // Pe
+ Punctuation_InitialQuote, // Pi
+ Punctuation_FinalQuote, // Pf
+ Punctuation_Other, // Po
+
+ Symbol_Math, // Sm
+ Symbol_Currency, // Sc
+ Symbol_Modifier, // Sk
+ Symbol_Other // So
+ };
+
+ enum Script
+ {
+ Script_Unknown,
+ Script_Inherited,
+ Script_Common,
+
+ Script_Latin,
+ Script_Greek,
+ Script_Cyrillic,
+ Script_Armenian,
+ Script_Hebrew,
+ Script_Arabic,
+ Script_Syriac,
+ Script_Thaana,
+ Script_Devanagari,
+ Script_Bengali,
+ Script_Gurmukhi,
+ Script_Gujarati,
+ Script_Oriya,
+ Script_Tamil,
+ Script_Telugu,
+ Script_Kannada,
+ Script_Malayalam,
+ Script_Sinhala,
+ Script_Thai,
+ Script_Lao,
+ Script_Tibetan,
+ Script_Myanmar,
+ Script_Georgian,
+ Script_Hangul,
+ Script_Ethiopic,
+ Script_Cherokee,
+ Script_CanadianAboriginal,
+ Script_Ogham,
+ Script_Runic,
+ Script_Khmer,
+ Script_Mongolian,
+ Script_Hiragana,
+ Script_Katakana,
+ Script_Bopomofo,
+ Script_Han,
+ Script_Yi,
+ Script_OldItalic,
+ Script_Gothic,
+ Script_Deseret,
+ Script_Tagalog,
+ Script_Hanunoo,
+ Script_Buhid,
+ Script_Tagbanwa,
+ Script_Coptic,
+
+ // Unicode 4.0 additions
+ Script_Limbu,
+ Script_TaiLe,
+ Script_LinearB,
+ Script_Ugaritic,
+ Script_Shavian,
+ Script_Osmanya,
+ Script_Cypriot,
+ Script_Braille,
+
+ // Unicode 4.1 additions
+ Script_Buginese,
+ Script_NewTaiLue,
+ Script_Glagolitic,
+ Script_Tifinagh,
+ Script_SylotiNagri,
+ Script_OldPersian,
+ Script_Kharoshthi,
+
+ // Unicode 5.0 additions
+ Script_Balinese,
+ Script_Cuneiform,
+ Script_Phoenician,
+ Script_PhagsPa,
+ Script_Nko,
+
+ // Unicode 5.1 additions
+ Script_Sundanese,
+ Script_Lepcha,
+ Script_OlChiki,
+ Script_Vai,
+ Script_Saurashtra,
+ Script_KayahLi,
+ Script_Rejang,
+ Script_Lycian,
+ Script_Carian,
+ Script_Lydian,
+ Script_Cham,
+
+ // Unicode 5.2 additions
+ Script_TaiTham,
+ Script_TaiViet,
+ Script_Avestan,
+ Script_EgyptianHieroglyphs,
+ Script_Samaritan,
+ Script_Lisu,
+ Script_Bamum,
+ Script_Javanese,
+ Script_MeeteiMayek,
+ Script_ImperialAramaic,
+ Script_OldSouthArabian,
+ Script_InscriptionalParthian,
+ Script_InscriptionalPahlavi,
+ Script_OldTurkic,
+ Script_Kaithi,
+
+ // Unicode 6.0 additions
+ Script_Batak,
+ Script_Brahmi,
+ Script_Mandaic,
+
+ // Unicode 6.1 additions
+ Script_Chakma,
+ Script_MeroiticCursive,
+ Script_MeroiticHieroglyphs,
+ Script_Miao,
+ Script_Sharada,
+ Script_SoraSompeng,
+ Script_Takri,
+
+ // Unicode 7.0 additions
+ Script_CaucasianAlbanian,
+ Script_BassaVah,
+ Script_Duployan,
+ Script_Elbasan,
+ Script_Grantha,
+ Script_PahawhHmong,
+ Script_Khojki,
+ Script_LinearA,
+ Script_Mahajani,
+ Script_Manichaean,
+ Script_MendeKikakui,
+ Script_Modi,
+ Script_Mro,
+ Script_OldNorthArabian,
+ Script_Nabataean,
+ Script_Palmyrene,
+ Script_PauCinHau,
+ Script_OldPermic,
+ Script_PsalterPahlavi,
+ Script_Siddham,
+ Script_Khudawadi,
+ Script_Tirhuta,
+ Script_WarangCiti,
+
+ // Unicode 8.0 additions
+ Script_Ahom,
+ Script_AnatolianHieroglyphs,
+ Script_Hatran,
+ Script_Multani,
+ Script_OldHungarian,
+ Script_SignWriting,
+
+ // Unicode 9.0 additions
+ Script_Adlam,
+ Script_Bhaiksuki,
+ Script_Marchen,
+ Script_Newa,
+ Script_Osage,
+ Script_Tangut,
+
+ // Unicode 10.0 additions
+ Script_MasaramGondi,
+ Script_Nushu,
+ Script_Soyombo,
+ Script_ZanabazarSquare,
+
+ ScriptCount
+ };
+
+ enum Direction
+ {
+ DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
+ DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN,
+ DirLRI, DirRLI, DirFSI, DirPDI
+ };
+
+ enum Decomposition
+ {
+ NoDecomposition,
+ Canonical,
+ Font,
+ NoBreak,
+ Initial,
+ Medial,
+ Final,
+ Isolated,
+ Circle,
+ Super,
+ Sub,
+ Vertical,
+ Wide,
+ Narrow,
+ Small,
+ Square,
+ Compat,
+ Fraction
+ };
+
+ enum JoiningType {
+ Joining_None,
+ Joining_Causing,
+ Joining_Dual,
+ Joining_Right,
+ Joining_Left,
+ Joining_Transparent
+ };
+
+#if QT_DEPRECATED_SINCE(5, 3)
+ enum Joining
+ {
+ OtherJoining, Dual, Right, Center
+ };
+#endif
+
+ enum CombiningClass
+ {
+ Combining_BelowLeftAttached = 200,
+ Combining_BelowAttached = 202,
+ Combining_BelowRightAttached = 204,
+ Combining_LeftAttached = 208,
+ Combining_RightAttached = 210,
+ Combining_AboveLeftAttached = 212,
+ Combining_AboveAttached = 214,
+ Combining_AboveRightAttached = 216,
+
+ Combining_BelowLeft = 218,
+ Combining_Below = 220,
+ Combining_BelowRight = 222,
+ Combining_Left = 224,
+ Combining_Right = 226,
+ Combining_AboveLeft = 228,
+ Combining_Above = 230,
+ Combining_AboveRight = 232,
+
+ Combining_DoubleBelow = 233,
+ Combining_DoubleAbove = 234,
+ Combining_IotaSubscript = 240
+ };
+
+ enum UnicodeVersion {
+ Unicode_Unassigned,
+ Unicode_1_1,
+ Unicode_2_0,
+ Unicode_2_1_2,
+ Unicode_3_0,
+ Unicode_3_1,
+ Unicode_3_2,
+ Unicode_4_0,
+ Unicode_4_1,
+ Unicode_5_0,
+ Unicode_5_1,
+ Unicode_5_2,
+ Unicode_6_0,
+ Unicode_6_1,
+ Unicode_6_2,
+ Unicode_6_3,
+ Unicode_7_0,
+ Unicode_8_0,
+ Unicode_9_0,
+ Unicode_10_0
+ };
+ // ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO QCharRef TOO
+
+ inline Category category() const noexcept { return QChar::category(ucs); }
+ inline Direction direction() const noexcept { return QChar::direction(ucs); }
+ inline JoiningType joiningType() const noexcept { return QChar::joiningType(ucs); }
+#if QT_DEPRECATED_SINCE(5, 3)
+ QT_DEPRECATED inline Joining joining() const noexcept
+ {
+ switch (QChar::joiningType(ucs)) {
+ case QChar::Joining_Causing: return QChar::Center;
+ case QChar::Joining_Dual: return QChar::Dual;
+ case QChar::Joining_Right: return QChar::Right;
+ case QChar::Joining_None:
+ case QChar::Joining_Left:
+ case QChar::Joining_Transparent:
+ default: return QChar::OtherJoining;
+ }
+ }
+#endif
+ inline unsigned char combiningClass() const noexcept { return QChar::combiningClass(ucs); }
+
+ inline QChar mirroredChar() const noexcept { return QChar(QChar::mirroredChar(ucs)); }
+ inline bool hasMirrored() const noexcept { return QChar::hasMirrored(ucs); }
+
+ QString decomposition() const;
+ inline Decomposition decompositionTag() const noexcept { return QChar::decompositionTag(ucs); }
+
+ inline int digitValue() const noexcept { return QChar::digitValue(ucs); }
+ inline QChar toLower() const noexcept { return QChar(QChar::toLower(ucs)); }
+ inline QChar toUpper() const noexcept { return QChar(QChar::toUpper(ucs)); }
+ inline QChar toTitleCase() const noexcept { return QChar(QChar::toTitleCase(ucs)); }
+ inline QChar toCaseFolded() const noexcept { return QChar(QChar::toCaseFolded(ucs)); }
+
+ inline Script script() const noexcept { return QChar::script(ucs); }
+
+ inline UnicodeVersion unicodeVersion() const noexcept { return QChar::unicodeVersion(ucs); }
+
+#if QT_DEPRECATED_SINCE(5, 0)
+ QT_DEPRECATED Q_DECL_CONSTEXPR inline char toAscii() const noexcept { return toLatin1(); }
+#endif
+ Q_DECL_CONSTEXPR inline char toLatin1() const noexcept { return ucs > 0xff ? '\0' : char(ucs); }
+ Q_DECL_CONSTEXPR inline ushort unicode() const noexcept { return ucs; }
+ Q_DECL_RELAXED_CONSTEXPR inline ushort &unicode() noexcept { return ucs; }
+
+#if QT_DEPRECATED_SINCE(5, 0)
+ QT_DEPRECATED static Q_DECL_CONSTEXPR inline QChar fromAscii(char c) noexcept
+ { return fromLatin1(c); }
+#endif
+ static Q_DECL_CONSTEXPR inline QChar fromLatin1(char c) noexcept { return QChar(ushort(uchar(c))); }
+
+ Q_DECL_CONSTEXPR inline bool isNull() const noexcept { return ucs == 0; }
+
+ inline bool isPrint() const noexcept { return QChar::isPrint(ucs); }
+ Q_DECL_CONSTEXPR inline bool isSpace() const noexcept { return QChar::isSpace(ucs); }
+ inline bool isMark() const noexcept { return QChar::isMark(ucs); }
+ inline bool isPunct() const noexcept { return QChar::isPunct(ucs); }
+ inline bool isSymbol() const noexcept { return QChar::isSymbol(ucs); }
+ Q_DECL_CONSTEXPR inline bool isLetter() const noexcept { return QChar::isLetter(ucs); }
+ Q_DECL_CONSTEXPR inline bool isNumber() const noexcept { return QChar::isNumber(ucs); }
+ Q_DECL_CONSTEXPR inline bool isLetterOrNumber() const noexcept { return QChar::isLetterOrNumber(ucs); }
+ Q_DECL_CONSTEXPR inline bool isDigit() const noexcept { return QChar::isDigit(ucs); }
+ Q_DECL_CONSTEXPR inline bool isLower() const noexcept { return QChar::isLower(ucs); }
+ Q_DECL_CONSTEXPR inline bool isUpper() const noexcept { return QChar::isUpper(ucs); }
+ Q_DECL_CONSTEXPR inline bool isTitleCase() const noexcept { return QChar::isTitleCase(ucs); }
+
+ Q_DECL_CONSTEXPR inline bool isNonCharacter() const noexcept { return QChar::isNonCharacter(ucs); }
+ Q_DECL_CONSTEXPR inline bool isHighSurrogate() const noexcept { return QChar::isHighSurrogate(ucs); }
+ Q_DECL_CONSTEXPR inline bool isLowSurrogate() const noexcept { return QChar::isLowSurrogate(ucs); }
+ Q_DECL_CONSTEXPR inline bool isSurrogate() const noexcept { return QChar::isSurrogate(ucs); }
+
+ Q_DECL_CONSTEXPR inline uchar cell() const noexcept { return uchar(ucs & 0xff); }
+ Q_DECL_CONSTEXPR inline uchar row() const noexcept { return uchar((ucs>>8)&0xff); }
+ Q_DECL_RELAXED_CONSTEXPR inline void setCell(uchar acell) noexcept { ucs = ushort((ucs & 0xff00) + acell); }
+ Q_DECL_RELAXED_CONSTEXPR inline void setRow(uchar arow) noexcept { ucs = ushort((ushort(arow)<<8) + (ucs&0xff)); }
+
+ static Q_DECL_CONSTEXPR inline bool isNonCharacter(uint ucs4) noexcept
+ {
+ return ucs4 >= 0xfdd0 && (ucs4 <= 0xfdef || (ucs4 & 0xfffe) == 0xfffe);
+ }
+ static Q_DECL_CONSTEXPR inline bool isHighSurrogate(uint ucs4) noexcept
+ {
+ return ((ucs4 & 0xfffffc00) == 0xd800);
+ }
+ static Q_DECL_CONSTEXPR inline bool isLowSurrogate(uint ucs4) noexcept
+ {
+ return ((ucs4 & 0xfffffc00) == 0xdc00);
+ }
+ static Q_DECL_CONSTEXPR inline bool isSurrogate(uint ucs4) noexcept
+ {
+ return (ucs4 - 0xd800u < 2048u);
+ }
+ static Q_DECL_CONSTEXPR inline bool requiresSurrogates(uint ucs4) noexcept
+ {
+ return (ucs4 >= 0x10000);
+ }
+ static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(ushort high, ushort low) noexcept
+ {
+ return (uint(high)<<10) + low - 0x35fdc00;
+ }
+ static Q_DECL_CONSTEXPR inline uint surrogateToUcs4(QChar high, QChar low) noexcept
+ {
+ return surrogateToUcs4(high.ucs, low.ucs);
+ }
+ static Q_DECL_CONSTEXPR inline ushort highSurrogate(uint ucs4) noexcept
+ {
+ return ushort((ucs4>>10) + 0xd7c0);
+ }
+ static Q_DECL_CONSTEXPR inline ushort lowSurrogate(uint ucs4) noexcept
+ {
+ return ushort(ucs4%0x400 + 0xdc00);
+ }
+
+ static Category QT_FASTCALL category(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static Direction QT_FASTCALL direction(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static JoiningType QT_FASTCALL joiningType(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+#if QT_DEPRECATED_SINCE(5, 3)
+ QT_DEPRECATED static Joining QT_FASTCALL joining(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+#endif
+ static unsigned char QT_FASTCALL combiningClass(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+
+ static uint QT_FASTCALL mirroredChar(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL hasMirrored(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+
+ static QString QT_FASTCALL decomposition(uint ucs4);
+ static Decomposition QT_FASTCALL decompositionTag(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+
+ static int QT_FASTCALL digitValue(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static uint QT_FASTCALL toLower(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static uint QT_FASTCALL toUpper(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static uint QT_FASTCALL toTitleCase(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static uint QT_FASTCALL toCaseFolded(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+
+ static Script QT_FASTCALL script(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+
+ static UnicodeVersion QT_FASTCALL unicodeVersion(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+
+ static UnicodeVersion QT_FASTCALL currentUnicodeVersion() noexcept Q_DECL_CONST_FUNCTION;
+
+ static bool QT_FASTCALL isPrint(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static Q_DECL_CONSTEXPR inline bool isSpace(uint ucs4) noexcept Q_DECL_CONST_FUNCTION
+ {
+ // note that [0x09..0x0d] + 0x85 are exceptional Cc-s and must be handled explicitly
+ return ucs4 == 0x20 || (ucs4 <= 0x0d && ucs4 >= 0x09)
+ || (ucs4 > 127 && (ucs4 == 0x85 || ucs4 == 0xa0 || QChar::isSpace_helper(ucs4)));
+ }
+ static bool QT_FASTCALL isMark(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isPunct(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isSymbol(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static Q_DECL_CONSTEXPR inline bool isLetter(uint ucs4) noexcept Q_DECL_CONST_FUNCTION
+ {
+ return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
+ || (ucs4 > 127 && QChar::isLetter_helper(ucs4));
+ }
+ static Q_DECL_CONSTEXPR inline bool isNumber(uint ucs4) noexcept Q_DECL_CONST_FUNCTION
+ { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::isNumber_helper(ucs4)); }
+ static Q_DECL_CONSTEXPR inline bool isLetterOrNumber(uint ucs4) noexcept Q_DECL_CONST_FUNCTION
+ {
+ return (ucs4 >= 'A' && ucs4 <= 'z' && (ucs4 >= 'a' || ucs4 <= 'Z'))
+ || (ucs4 >= '0' && ucs4 <= '9')
+ || (ucs4 > 127 && QChar::isLetterOrNumber_helper(ucs4));
+ }
+ static Q_DECL_CONSTEXPR inline bool isDigit(uint ucs4) noexcept Q_DECL_CONST_FUNCTION
+ { return (ucs4 <= '9' && ucs4 >= '0') || (ucs4 > 127 && QChar::category(ucs4) == Number_DecimalDigit); }
+ static Q_DECL_CONSTEXPR inline bool isLower(uint ucs4) noexcept Q_DECL_CONST_FUNCTION
+ { return (ucs4 <= 'z' && ucs4 >= 'a') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Lowercase); }
+ static Q_DECL_CONSTEXPR inline bool isUpper(uint ucs4) noexcept Q_DECL_CONST_FUNCTION
+ { return (ucs4 <= 'Z' && ucs4 >= 'A') || (ucs4 > 127 && QChar::category(ucs4) == Letter_Uppercase); }
+ static Q_DECL_CONSTEXPR inline bool isTitleCase(uint ucs4) noexcept Q_DECL_CONST_FUNCTION
+ { return ucs4 > 127 && QChar::category(ucs4) == Letter_Titlecase; }
+
+private:
+ static bool QT_FASTCALL isSpace_helper(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isLetter_helper(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isNumber_helper(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+ static bool QT_FASTCALL isLetterOrNumber_helper(uint ucs4) noexcept Q_DECL_CONST_FUNCTION;
+
+#ifdef QT_NO_CAST_FROM_ASCII
+ QChar(char c) noexcept;
+ QChar(uchar c) noexcept;
+#endif
+
+ friend Q_DECL_CONSTEXPR bool operator==(QChar, QChar) noexcept;
+ friend Q_DECL_CONSTEXPR bool operator< (QChar, QChar) noexcept;
+ ushort ucs;
+};
+
+Q_DECLARE_TYPEINFO(QChar, Q_MOVABLE_TYPE);
+
+Q_DECL_CONSTEXPR inline bool operator==(QChar c1, QChar c2) noexcept { return c1.ucs == c2.ucs; }
+Q_DECL_CONSTEXPR inline bool operator< (QChar c1, QChar c2) noexcept { return c1.ucs < c2.ucs; }
+
+Q_DECL_CONSTEXPR inline bool operator!=(QChar c1, QChar c2) noexcept { return !operator==(c1, c2); }
+Q_DECL_CONSTEXPR inline bool operator>=(QChar c1, QChar c2) noexcept { return !operator< (c1, c2); }
+Q_DECL_CONSTEXPR inline bool operator> (QChar c1, QChar c2) noexcept { return operator< (c2, c1); }
+Q_DECL_CONSTEXPR inline bool operator<=(QChar c1, QChar c2) noexcept { return !operator< (c2, c1); }
+
+
+Q_DECL_CONSTEXPR inline bool operator==(QChar lhs, std::nullptr_t) noexcept { return lhs.isNull(); }
+Q_DECL_CONSTEXPR inline bool operator< (QChar, std::nullptr_t) noexcept { return false; }
+Q_DECL_CONSTEXPR inline bool operator==(std::nullptr_t, QChar rhs) noexcept { return rhs.isNull(); }
+Q_DECL_CONSTEXPR inline bool operator< (std::nullptr_t, QChar rhs) noexcept { return !rhs.isNull(); }
+
+Q_DECL_CONSTEXPR inline bool operator!=(QChar lhs, std::nullptr_t) noexcept { return !operator==(lhs, nullptr); }
+Q_DECL_CONSTEXPR inline bool operator>=(QChar lhs, std::nullptr_t) noexcept { return !operator< (lhs, nullptr); }
+Q_DECL_CONSTEXPR inline bool operator> (QChar lhs, std::nullptr_t) noexcept { return operator< (nullptr, lhs); }
+Q_DECL_CONSTEXPR inline bool operator<=(QChar lhs, std::nullptr_t) noexcept { return !operator< (nullptr, lhs); }
+
+Q_DECL_CONSTEXPR inline bool operator!=(std::nullptr_t, QChar rhs) noexcept { return !operator==(nullptr, rhs); }
+Q_DECL_CONSTEXPR inline bool operator>=(std::nullptr_t, QChar rhs) noexcept { return !operator< (nullptr, rhs); }
+Q_DECL_CONSTEXPR inline bool operator> (std::nullptr_t, QChar rhs) noexcept { return operator< (rhs, nullptr); }
+Q_DECL_CONSTEXPR inline bool operator<=(std::nullptr_t, QChar rhs) noexcept { return !operator< (rhs, nullptr); }
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QChar);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QChar &);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QCHAR_H
diff --git a/src/corelib/text/qcollator.cpp b/src/corelib/text/qcollator.cpp
new file mode 100644
index 0000000000..958216bde8
--- /dev/null
+++ b/src/corelib/text/qcollator.cpp
@@ -0,0 +1,456 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcollator_p.h"
+#include "qstringlist.h"
+#include "qstring.h"
+
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCollator
+ \inmodule QtCore
+ \brief The QCollator class compares strings according to a localized collation algorithm.
+
+ \since 5.2
+
+ \reentrant
+ \ingroup i18n
+ \ingroup string-processing
+ \ingroup shared
+
+ QCollator is initialized with a QLocale and an optional collation strategy.
+ It tries to initialize the collator with the specified values. The collator
+ can then be used to compare and sort strings in a locale dependent fashion.
+
+ A QCollator object can be used together with template based sorting
+ algorithms such as std::sort to sort a list of QStrings.
+
+ In addition to the locale and collation strategy, several optional flags can
+ be set that influence the result of the collation.
+*/
+
+/*!
+ \since 5.13
+
+ Constructs a QCollator using the system's default collation locale.
+
+ \sa setLocale(), QLocale::collation()
+*/
+QCollator::QCollator()
+ : d(new QCollatorPrivate(QLocale::system().collation()))
+{
+ d->init();
+}
+
+/*!
+ Constructs a QCollator from \a locale.
+
+ \sa setLocale()
+ */
+QCollator::QCollator(const QLocale &locale)
+ : d(new QCollatorPrivate(locale))
+{
+}
+
+/*!
+ Creates a copy of \a other.
+ */
+QCollator::QCollator(const QCollator &other)
+ : d(other.d)
+{
+ if (d) {
+ // Ensure clean, lest both copies try to init() at the same time:
+ if (d->dirty)
+ d->init();
+ d->ref.ref();
+ }
+}
+
+/*!
+ Destroys the collator.
+ */
+QCollator::~QCollator()
+{
+ if (d && !d->ref.deref())
+ delete d;
+}
+
+/*!
+ Assigns \a other to this collator.
+ */
+QCollator &QCollator::operator=(const QCollator &other)
+{
+ if (this != &other) {
+ if (d && !d->ref.deref())
+ delete d;
+ d = other.d;
+ if (d) {
+ // Ensure clean, lest both copies try to init() at the same time:
+ if (d->dirty)
+ d->init();
+ d->ref.ref();
+ }
+ }
+ return *this;
+}
+
+/*!
+ \fn QCollator::QCollator(QCollator &&other)
+
+ Move constructor. Moves from \a other into this collator.
+
+ Note that a moved-from QCollator can only be destroyed or assigned to.
+ The effect of calling other functions than the destructor or one of the
+ assignment operators is undefined.
+*/
+
+/*!
+ \fn QCollator & QCollator::operator=(QCollator && other)
+
+ Move-assigns from \a other to this collator.
+
+ Note that a moved-from QCollator can only be destroyed or assigned to.
+ The effect of calling other functions than the destructor or one of the
+ assignment operators is undefined.
+*/
+
+/*!
+ \fn void QCollator::swap(QCollator &other)
+
+ Swaps this collator with \a other. This function is very fast and
+ never fails.
+*/
+
+/*!
+ \internal
+ */
+void QCollator::detach()
+{
+ if (d->ref.loadRelaxed() != 1) {
+ QCollatorPrivate *x = new QCollatorPrivate(d->locale);
+ if (!d->ref.deref())
+ delete d;
+ d = x;
+ }
+ // All callers need this, because about to modify the object:
+ d->dirty = true;
+}
+
+/*!
+ Sets the locale of the collator to \a locale.
+ */
+void QCollator::setLocale(const QLocale &locale)
+{
+ if (locale == d->locale)
+ return;
+
+ detach();
+ d->locale = locale;
+}
+
+/*!
+ Returns the locale of the collator.
+ */
+QLocale QCollator::locale() const
+{
+ return d->locale;
+}
+
+/*!
+ \fn void QCollator::setCaseSensitivity(Qt::CaseSensitivity sensitivity)
+
+ Sets the case \a sensitivity of the collator.
+
+ \sa caseSensitivity()
+ */
+void QCollator::setCaseSensitivity(Qt::CaseSensitivity cs)
+{
+ if (d->caseSensitivity == cs)
+ return;
+
+ detach();
+ d->caseSensitivity = cs;
+}
+
+/*!
+ \fn Qt::CaseSensitivity QCollator::caseSensitivity() const
+
+ Returns case sensitivity of the collator.
+
+ \sa setCaseSensitivity()
+ */
+Qt::CaseSensitivity QCollator::caseSensitivity() const
+{
+ return d->caseSensitivity;
+}
+
+/*!
+ \fn void QCollator::setNumericMode(bool on)
+
+ Enables numeric sorting mode when \a on is set to true.
+
+ This will enable proper sorting of numeric digits, so that e.g. 100 sorts
+ after 99.
+
+ By default this mode is off.
+
+ \sa numericMode()
+ */
+void QCollator::setNumericMode(bool on)
+{
+ if (d->numericMode == on)
+ return;
+
+ detach();
+ d->numericMode = on;
+}
+
+/*!
+ \fn bool QCollator::numericMode() const
+
+ Returns \c true if numeric sorting is enabled, false otherwise.
+
+ \sa setNumericMode()
+ */
+bool QCollator::numericMode() const
+{
+ return d->numericMode;
+}
+
+/*!
+ \fn void QCollator::setIgnorePunctuation(bool on)
+
+ If \a on is set to true, punctuation characters and symbols are ignored when
+ determining sort order.
+
+ The default is locale dependent.
+
+ \note This method is not currently supported if Qt is configured to not use
+ ICU on Linux.
+
+ \sa ignorePunctuation()
+ */
+void QCollator::setIgnorePunctuation(bool on)
+{
+ if (d->ignorePunctuation == on)
+ return;
+
+ detach();
+ d->ignorePunctuation = on;
+}
+
+/*!
+ \fn bool QCollator::ignorePunctuation() const
+
+ Returns \c true if punctuation characters and symbols are ignored when
+ determining sort order.
+
+ \sa setIgnorePunctuation()
+ */
+bool QCollator::ignorePunctuation() const
+{
+ return d->ignorePunctuation;
+}
+
+/*!
+ \since 5.13
+ \fn bool QCollator::operator()(QStringView s1, QStringView s2) const
+ \internal
+*/
+
+/*!
+ \since 5.13
+ \fn int QCollator::compare(QStringView s1, QStringView s2) const
+
+ Compares \a s1 with \a s2.
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
+*/
+#if QT_STRINGVIEW_LEVEL < 2
+/*!
+ \fn bool QCollator::operator()(const QString &s1, const QString &s2) const
+ \internal
+*/
+
+/*!
+ \overload
+
+ Compares \a s1 with \a s2.
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
+*/
+int QCollator::compare(const QString &s1, const QString &s2) const
+{
+ return compare(QStringView(s1), QStringView(s2));
+}
+
+/*!
+ \overload
+
+ Compares \a s1 with \a s2.
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
+ */
+int QCollator::compare(const QStringRef &s1, const QStringRef &s2) const
+{
+ return compare(QStringView(s1), QStringView(s2));
+}
+
+/*!
+ \overload
+
+ Compares \a s1 with \a s2. \a len1 and \a len2 specify the lengths of the
+ QChar arrays pointed to by \a s1 and \a s2.
+
+ Returns an integer less than, equal to, or greater than zero depending on
+ whether \a s1 sorts before, with or after \a s2.
+*/
+int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
+{
+ return compare(QStringView(s1, len1), QStringView(s2, len2));
+}
+#endif // QT_STRINGVIEW_LEVEL < 2
+
+/*!
+ \fn QCollatorSortKey QCollator::sortKey(const QString &string) const
+
+ Returns a sortKey for \a string.
+
+ Creating the sort key is usually somewhat slower, than using the compare()
+ methods directly. But if the string is compared repeatedly (e.g. when
+ sorting a whole list of strings), it's usually faster to create the sort
+ keys for each string and then sort using the keys.
+
+ \note Not supported with the C (a.k.a. POSIX) locale on Darwin.
+ */
+
+/*!
+ \class QCollatorSortKey
+ \inmodule QtCore
+ \brief The QCollatorSortKey class can be used to speed up string collation.
+
+ \since 5.2
+
+ The QCollatorSortKey class is always created by QCollator::sortKey() and is
+ used for fast strings collation, for example when collating many strings.
+
+ \reentrant
+ \ingroup i18n
+ \ingroup string-processing
+ \ingroup shared
+
+ \sa QCollator, QCollator::sortKey()
+*/
+
+/*!
+ \internal
+ */
+QCollatorSortKey::QCollatorSortKey(QCollatorSortKeyPrivate *d)
+ : d(d)
+{
+}
+
+/*!
+ Constructs a copy of the \a other collator key.
+*/
+QCollatorSortKey::QCollatorSortKey(const QCollatorSortKey &other)
+ : d(other.d)
+{
+}
+
+/*!
+ Destroys the collator key.
+ */
+QCollatorSortKey::~QCollatorSortKey()
+{
+}
+
+/*!
+ Assigns \a other to this collator key.
+ */
+QCollatorSortKey& QCollatorSortKey::operator=(const QCollatorSortKey &other)
+{
+ if (this != &other) {
+ d = other.d;
+ }
+ return *this;
+}
+
+/*!
+ \fn QCollatorSortKey &QCollatorSortKey::operator=(QCollatorSortKey && other)
+
+ Move-assigns \a other to this collator key.
+*/
+
+/*!
+ \fn bool operator<(const QCollatorSortKey &lhs, const QCollatorSortKey &rhs)
+ \relates QCollatorSortKey
+
+ According to the QCollator that created the keys, returns \c true if \a lhs
+ should be sorted before \a rhs; otherwise returns \c false.
+
+ \sa QCollatorSortKey::compare()
+ */
+
+/*!
+ \fn void QCollatorSortKey::swap(QCollatorSortKey & other)
+
+ Swaps this collator key with \a other.
+*/
+
+/*!
+ \fn int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
+
+ Compares this key to \a otherKey.
+
+ Returns a negative value if the key is less than \a otherKey, 0 if the key
+ is equal to \a otherKey or a positive value if the key is greater than \a
+ otherKey.
+
+ \sa operator<()
+ */
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qcollator.h b/src/corelib/text/qcollator.h
new file mode 100644
index 0000000000..6bb5038371
--- /dev/null
+++ b/src/corelib/text/qcollator.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLLATOR_H
+#define QCOLLATOR_H
+
+#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
+#include <QtCore/qlocale.h>
+
+QT_BEGIN_NAMESPACE
+
+class QCollatorPrivate;
+class QCollatorSortKeyPrivate;
+
+class Q_CORE_EXPORT QCollatorSortKey
+{
+ friend class QCollator;
+public:
+ QCollatorSortKey(const QCollatorSortKey &other);
+ ~QCollatorSortKey();
+ QCollatorSortKey &operator=(const QCollatorSortKey &other);
+ inline QCollatorSortKey &operator=(QCollatorSortKey &&other) noexcept
+ { swap(other); return *this; }
+ void swap(QCollatorSortKey &other) noexcept
+ { d.swap(other.d); }
+
+ int compare(const QCollatorSortKey &key) const;
+
+protected:
+ QCollatorSortKey(QCollatorSortKeyPrivate*);
+
+ QExplicitlySharedDataPointer<QCollatorSortKeyPrivate> d;
+
+private:
+ QCollatorSortKey();
+};
+
+inline bool operator<(const QCollatorSortKey &lhs, const QCollatorSortKey &rhs)
+{
+ return lhs.compare(rhs) < 0;
+}
+
+class Q_CORE_EXPORT QCollator
+{
+public:
+ QCollator();
+ explicit QCollator(const QLocale &locale);
+ QCollator(const QCollator &);
+ ~QCollator();
+ QCollator &operator=(const QCollator &);
+ QCollator(QCollator &&other) noexcept
+ : d(other.d) { other.d = nullptr; }
+ QCollator &operator=(QCollator &&other) noexcept
+ { swap(other); return *this; }
+
+ void swap(QCollator &other) noexcept
+ { qSwap(d, other.d); }
+
+ void setLocale(const QLocale &locale);
+ QLocale locale() const;
+
+ Qt::CaseSensitivity caseSensitivity() const;
+ void setCaseSensitivity(Qt::CaseSensitivity cs);
+
+ void setNumericMode(bool on);
+ bool numericMode() const;
+
+ void setIgnorePunctuation(bool on);
+ bool ignorePunctuation() const;
+
+#if QT_STRINGVIEW_LEVEL < 2
+ int compare(const QString &s1, const QString &s2) const;
+ int compare(const QStringRef &s1, const QStringRef &s2) const;
+ int compare(const QChar *s1, int len1, const QChar *s2, int len2) const;
+
+ bool operator()(const QString &s1, const QString &s2) const
+ { return compare(s1, s2) < 0; }
+#endif
+ int compare(QStringView s1, QStringView s2) const;
+
+ bool operator()(QStringView s1, QStringView s2) const
+ { return compare(s1, s2) < 0; }
+
+ QCollatorSortKey sortKey(const QString &string) const;
+
+private:
+ QCollatorPrivate *d;
+
+ void detach();
+};
+
+Q_DECLARE_SHARED(QCollatorSortKey)
+Q_DECLARE_SHARED(QCollator)
+
+QT_END_NAMESPACE
+
+#endif // QCOLLATOR_P_H
diff --git a/src/corelib/text/qcollator_icu.cpp b/src/corelib/text/qcollator_icu.cpp
new file mode 100644
index 0000000000..8acda45070
--- /dev/null
+++ b/src/corelib/text/qcollator_icu.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcollator_p.h"
+#include "qlocale_p.h"
+#include "qstringlist.h"
+#include "qstring.h"
+
+#include <unicode/utypes.h>
+#include <unicode/ucol.h>
+#include <unicode/ustring.h>
+#include <unicode/ures.h>
+
+#include "qdebug.h"
+
+QT_BEGIN_NAMESPACE
+
+void QCollatorPrivate::init()
+{
+ cleanup();
+ if (isC())
+ return;
+
+ UErrorCode status = U_ZERO_ERROR;
+ QByteArray name = QLocalePrivate::get(locale)->bcp47Name('_');
+ collator = ucol_open(name.constData(), &status);
+ if (U_FAILURE(status)) {
+ qWarning("Could not create collator: %d", status);
+ collator = nullptr;
+ dirty = false;
+ return;
+ }
+
+ // enable normalization by default
+ ucol_setAttribute(collator, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
+
+ // The strength attribute in ICU is rather badly documented. Basically UCOL_PRIMARY
+ // ignores differences between base characters and accented characters as well as case.
+ // So A and A-umlaut would compare equal.
+ // UCOL_SECONDARY ignores case differences. UCOL_TERTIARY is the default in most languages
+ // and does case sensitive comparison.
+ // UCOL_QUATERNARY is used as default in a few languages such as Japanese to take care of some
+ // additional differences in those languages.
+ UColAttributeValue val = (caseSensitivity == Qt::CaseSensitive)
+ ? UCOL_DEFAULT_STRENGTH : UCOL_SECONDARY;
+
+ status = U_ZERO_ERROR;
+ ucol_setAttribute(collator, UCOL_STRENGTH, val, &status);
+ if (U_FAILURE(status))
+ qWarning("ucol_setAttribute: Case First failed: %d", status);
+
+ status = U_ZERO_ERROR;
+ ucol_setAttribute(collator, UCOL_NUMERIC_COLLATION, numericMode ? UCOL_ON : UCOL_OFF, &status);
+ if (U_FAILURE(status))
+ qWarning("ucol_setAttribute: numeric collation failed: %d", status);
+
+ status = U_ZERO_ERROR;
+ ucol_setAttribute(collator, UCOL_ALTERNATE_HANDLING,
+ ignorePunctuation ? UCOL_SHIFTED : UCOL_NON_IGNORABLE, &status);
+ if (U_FAILURE(status))
+ qWarning("ucol_setAttribute: Alternate handling failed: %d", status);
+
+ dirty = false;
+}
+
+void QCollatorPrivate::cleanup()
+{
+ if (collator)
+ ucol_close(collator);
+ collator = nullptr;
+}
+
+int QCollator::compare(QStringView s1, QStringView s2) const
+{
+ if (d->dirty)
+ d->init();
+
+ if (d->collator) {
+ return ucol_strcoll(d->collator,
+ reinterpret_cast<const UChar *>(s1.data()), s1.size(),
+ reinterpret_cast<const UChar *>(s2.data()), s2.size());
+ }
+
+ return QString::compare_helper(s1.data(), s1.size(),
+ s2.data(), s2.size(),
+ d->caseSensitivity);
+}
+
+QCollatorSortKey QCollator::sortKey(const QString &string) const
+{
+ if (d->dirty)
+ d->init();
+ if (d->isC())
+ return QCollatorSortKey(new QCollatorSortKeyPrivate(string.toUtf8()));
+
+ if (d->collator) {
+ QByteArray result(16 + string.size() + (string.size() >> 2), Qt::Uninitialized);
+ int size = ucol_getSortKey(d->collator, (const UChar *)string.constData(),
+ string.size(), (uint8_t *)result.data(), result.size());
+ if (size > result.size()) {
+ result.resize(size);
+ size = ucol_getSortKey(d->collator, (const UChar *)string.constData(),
+ string.size(), (uint8_t *)result.data(), result.size());
+ }
+ result.truncate(size);
+ return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(result)));
+ }
+
+ return QCollatorSortKey(new QCollatorSortKeyPrivate(QByteArray()));
+}
+
+int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
+{
+ return qstrcmp(d->m_key, otherKey.d->m_key);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qcollator_macx.cpp b/src/corelib/text/qcollator_macx.cpp
new file mode 100644
index 0000000000..071d7c048f
--- /dev/null
+++ b/src/corelib/text/qcollator_macx.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcollator_p.h"
+#include "qlocale_p.h"
+#include "qstringlist.h"
+#include "qstring.h"
+
+#include <QtCore/private/qcore_mac_p.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFLocale.h>
+
+#include <cstring>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+void QCollatorPrivate::init()
+{
+ cleanup();
+ /*
+ LocaleRefFromLocaleString() will accept "POSIX" as the locale name, but
+ the locale it produces (named "pos") doesn't implement the [A-Z] < [a-z]
+ behavior we expect of the C locale. We can use QStringView to get round
+ that for collation, but this leaves no way to do a sort key.
+ */
+ if (isC())
+ return;
+
+ LocaleRef localeRef;
+ OSStatus status =
+ LocaleRefFromLocaleString(QLocalePrivate::get(locale)->bcp47Name().constData(), &localeRef);
+ if (status != 0)
+ qWarning("Couldn't initialize the locale (%d)", int(status));
+
+ UInt32 options = 0;
+ if (caseSensitivity == Qt::CaseInsensitive)
+ options |= kUCCollateCaseInsensitiveMask;
+ if (numericMode)
+ options |= kUCCollateDigitsAsNumberMask | kUCCollateDigitsOverrideMask;
+ if (!ignorePunctuation)
+ options |= kUCCollatePunctuationSignificantMask;
+
+ status = UCCreateCollator(localeRef, 0, options, &collator);
+ if (status != 0)
+ qWarning("Couldn't initialize the collator (%d)", int(status));
+
+ dirty = false;
+}
+
+void QCollatorPrivate::cleanup()
+{
+ if (collator)
+ UCDisposeCollator(&collator);
+ collator = 0;
+}
+
+int QCollator::compare(QStringView s1, QStringView s2) const
+{
+ if (d->dirty)
+ d->init();
+ if (!d->collator)
+ return s1.compare(s2, caseSensitivity());
+
+ SInt32 result;
+ Boolean equivalent;
+ UCCompareText(d->collator,
+ reinterpret_cast<const UniChar *>(s1.data()), s1.size(),
+ reinterpret_cast<const UniChar *>(s2.data()), s2.size(),
+ &equivalent,
+ &result);
+ if (equivalent)
+ return 0;
+ return result < 0 ? -1 : 1;
+}
+
+QCollatorSortKey QCollator::sortKey(const QString &string) const
+{
+ if (d->dirty)
+ d->init();
+ if (!d->collator) {
+ // What should (or even *can*) we do here ? (See init()'s comment.)
+ qWarning("QCollator doesn't support sort keys for the C locale on Darwin");
+ return QCollatorSortKey(nullptr);
+ }
+
+ //Documentation recommends having it 5 times as big as the input
+ QVector<UCCollationValue> ret(string.size() * 5);
+ ItemCount actualSize;
+ int status = UCGetCollationKey(d->collator,
+ reinterpret_cast<const UniChar *>(string.constData()),
+ string.count(), ret.size(), &actualSize, ret.data());
+
+ ret.resize(actualSize + 1);
+ if (status == kUCOutputBufferTooSmall) {
+ UCGetCollationKey(d->collator, reinterpret_cast<const UniChar *>(string.constData()),
+ string.count(), ret.size(), &actualSize, ret.data());
+ }
+ ret[actualSize] = 0;
+ return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(ret)));
+}
+
+int QCollatorSortKey::compare(const QCollatorSortKey &key) const
+{
+ if (!d.data())
+ return 0;
+
+ SInt32 order;
+ UCCompareCollationKeys(d->m_key.data(), d->m_key.size(),
+ key.d->m_key.data(), key.d->m_key.size(),
+ 0, &order);
+ return order;
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qcollator_p.h b/src/corelib/text/qcollator_p.h
new file mode 100644
index 0000000000..fc2d434a8d
--- /dev/null
+++ b/src/corelib/text/qcollator_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QCOLLATOR_P_H
+#define QCOLLATOR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qglobal_p.h>
+#include "qcollator.h"
+#include <QVector>
+#if QT_CONFIG(icu)
+#include <unicode/ucol.h>
+#elif defined(Q_OS_OSX)
+#include <CoreServices/CoreServices.h>
+#elif defined(Q_OS_WIN)
+#include <qt_windows.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#if QT_CONFIG(icu)
+typedef UCollator *CollatorType;
+typedef QByteArray CollatorKeyType;
+const CollatorType NoCollator = nullptr;
+
+#elif defined(Q_OS_OSX)
+typedef CollatorRef CollatorType;
+typedef QVector<UCCollationValue> CollatorKeyType;
+const CollatorType NoCollator = 0;
+
+#elif defined(Q_OS_WIN)
+typedef QString CollatorKeyType;
+typedef int CollatorType;
+const CollatorType NoCollator = 0;
+# ifdef Q_OS_WINRT
+# define USE_COMPARESTRINGEX
+# endif
+
+#else // posix - ignores CollatorType collator, only handles system locale
+typedef QVector<wchar_t> CollatorKeyType;
+typedef bool CollatorType;
+const CollatorType NoCollator = false;
+#endif
+
+class QCollatorPrivate
+{
+public:
+ QAtomicInt ref = 1;
+ QLocale locale;
+#if defined(Q_OS_WIN) && !QT_CONFIG(icu)
+#ifdef USE_COMPARESTRINGEX
+ QString localeName;
+#else
+ LCID localeID;
+#endif
+#endif
+ Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive;
+ bool numericMode = false;
+ bool ignorePunctuation = false;
+ bool dirty = true;
+
+ CollatorType collator = NoCollator;
+
+ QCollatorPrivate(const QLocale &locale) : locale(locale) {}
+ ~QCollatorPrivate() { cleanup(); }
+ bool isC() { return locale.language() == QLocale::C; }
+
+ void clear() {
+ cleanup();
+ collator = NoCollator;
+ }
+
+ // Implemented by each back-end, in its own way:
+ void init();
+ void cleanup();
+
+private:
+ Q_DISABLE_COPY_MOVE(QCollatorPrivate)
+};
+
+class QCollatorSortKeyPrivate : public QSharedData
+{
+ friend class QCollator;
+public:
+ template <typename...T>
+ explicit QCollatorSortKeyPrivate(T &&...args)
+ : QSharedData()
+ , m_key(std::forward<T>(args)...)
+ {
+ }
+
+ CollatorKeyType m_key;
+
+private:
+ Q_DISABLE_COPY_MOVE(QCollatorSortKeyPrivate)
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QCOLLATOR_P_H
diff --git a/src/corelib/text/qcollator_posix.cpp b/src/corelib/text/qcollator_posix.cpp
new file mode 100644
index 0000000000..9cbc539ebe
--- /dev/null
+++ b/src/corelib/text/qcollator_posix.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcollator_p.h"
+#include "qstringlist.h"
+#include "qstring.h"
+
+#include <cstring>
+#include <cwchar>
+
+QT_BEGIN_NAMESPACE
+
+void QCollatorPrivate::init()
+{
+ if (!isC()) {
+ if (locale != QLocale())
+ qWarning("Only C and default locale supported with the posix collation implementation");
+ if (caseSensitivity != Qt::CaseSensitive)
+ qWarning("Case insensitive sorting unsupported in the posix collation implementation");
+ }
+ if (numericMode)
+ qWarning("Numeric mode unsupported in the posix collation implementation");
+ if (ignorePunctuation)
+ qWarning("Ignoring punctuation unsupported in the posix collation implementation");
+ dirty = false;
+}
+
+void QCollatorPrivate::cleanup()
+{
+}
+
+static void stringToWCharArray(QVarLengthArray<wchar_t> &ret, QStringView string)
+{
+ ret.resize(string.length());
+ int len = string.toWCharArray(ret.data());
+ ret.resize(len+1);
+ ret[len] = 0;
+}
+
+int QCollator::compare(QStringView s1, QStringView s2) const
+{
+ if (d->isC())
+ return s1.compare(s2, caseSensitivity());
+ if (d->dirty)
+ d->init();
+
+ QVarLengthArray<wchar_t> array1, array2;
+ stringToWCharArray(array1, s1);
+ stringToWCharArray(array2, s2);
+ return std::wcscoll(array1.constData(), array2.constData());
+}
+
+QCollatorSortKey QCollator::sortKey(const QString &string) const
+{
+ if (d->dirty)
+ d->init();
+
+ QVarLengthArray<wchar_t> original;
+ stringToWCharArray(original, string);
+ QVector<wchar_t> result(original.size());
+ if (d->isC()) {
+ std::copy(original.cbegin(), original.cend(), result.begin());
+ } else {
+ size_t size = std::wcsxfrm(result.data(), original.constData(), string.size());
+ if (size > uint(result.size())) {
+ result.resize(size+1);
+ size = std::wcsxfrm(result.data(), original.constData(), string.size());
+ }
+ result.resize(size+1);
+ result[size] = 0;
+ }
+ return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(result)));
+}
+
+int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
+{
+ return std::wcscmp(d->m_key.constData(), otherKey.d->m_key.constData());
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qcollator_win.cpp b/src/corelib/text/qcollator_win.cpp
new file mode 100644
index 0000000000..9d81de882f
--- /dev/null
+++ b/src/corelib/text/qcollator_win.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcollator_p.h"
+#include "qlocale_p.h"
+#include "qstringlist.h"
+#include "qstring.h"
+
+#include <QDebug>
+
+#include <qt_windows.h>
+#include <qsysinfo.h>
+
+QT_BEGIN_NAMESPACE
+
+//NOTE: SORT_DIGITSASNUMBERS is available since win7
+#ifndef SORT_DIGITSASNUMBERS
+#define SORT_DIGITSASNUMBERS 8
+#endif
+
+// implemented in qlocale_win.cpp
+extern LCID qt_inIsoNametoLCID(const char *name);
+
+void QCollatorPrivate::init()
+{
+ collator = 0;
+ if (isC())
+ return;
+
+#ifndef USE_COMPARESTRINGEX
+ localeID = qt_inIsoNametoLCID(QLocalePrivate::get(locale)->bcp47Name().constData());
+#else
+ localeName = locale.bcp47Name();
+#endif
+
+ if (caseSensitivity == Qt::CaseInsensitive)
+ collator |= NORM_IGNORECASE;
+
+ // WINE does not support SORT_DIGITSASNUMBERS :-(
+ // (and its std::sort() crashes on bad comparisons, QTBUG-74209)
+ if (numericMode)
+ collator |= SORT_DIGITSASNUMBERS;
+
+ if (ignorePunctuation)
+ collator |= NORM_IGNORESYMBOLS;
+
+ dirty = false;
+}
+
+void QCollatorPrivate::cleanup()
+{
+}
+
+int QCollator::compare(QStringView s1, QStringView s2) const
+{
+ if (d->isC())
+ return s1.compare(s2, d->caseSensitivity);
+
+ if (d->dirty)
+ d->init();
+
+ //* from Windows documentation *
+ // Returns one of the following values if successful. To maintain the C
+ // runtime convention of comparing strings, the value 2 can be subtracted
+ // from a nonzero return value. Then, the meaning of <0, ==0, and >0 is
+ // consistent with the C runtime.
+ // [...] The function returns 0 if it does not succeed.
+ // https://docs.microsoft.com/en-us/windows/desktop/api/stringapiset/nf-stringapiset-comparestringex#return-value
+
+#ifndef USE_COMPARESTRINGEX
+ const int ret = CompareString(d->localeID, d->collator,
+ reinterpret_cast<const wchar_t *>(s1.data()), s1.size(),
+ reinterpret_cast<const wchar_t *>(s2.data()), s2.size());
+#else
+ const int ret = CompareStringEx(LPCWSTR(d->localeName.utf16()), d->collator,
+ reinterpret_cast<LPCWSTR>(s1.data()), s1.size(),
+ reinterpret_cast<LPCWSTR>(s2.data()), s2.size(),
+ nullptr, nullptr, 0);
+#endif
+ if (Q_LIKELY(ret))
+ return ret - 2;
+
+ switch (DWORD error = GetLastError()) {
+ case ERROR_INVALID_FLAGS:
+ qWarning("Unsupported flags (%d) used in QCollator", int(d->collator));
+ break;
+ case ERROR_INVALID_PARAMETER:
+ qWarning("Invalid parameter for QCollator::compare()");
+ break;
+ default:
+ qWarning("Failed (%ld) comparison in QCollator::compare()", long(error));
+ break;
+ }
+ // We have no idea what to return, so pretend we think they're equal.
+ // At least that way we'll be consistent if we get the same values swapped ...
+ return 0;
+}
+
+QCollatorSortKey QCollator::sortKey(const QString &string) const
+{
+ if (d->dirty)
+ d->init();
+ if (d->isC())
+ return QCollatorSortKey(new QCollatorSortKeyPrivate(string));
+
+#ifndef USE_COMPARESTRINGEX
+ int size = LCMapStringW(d->localeID, LCMAP_SORTKEY | d->collator,
+ reinterpret_cast<const wchar_t*>(string.constData()), string.size(),
+ 0, 0);
+#else
+ int size = LCMapStringEx(LPCWSTR(d->localeName.utf16()), LCMAP_SORTKEY | d->collator,
+ reinterpret_cast<LPCWSTR>(string.constData()), string.size(),
+ 0, 0, NULL, NULL, 0);
+#endif
+ QString ret(size, Qt::Uninitialized);
+#ifndef USE_COMPARESTRINGEX
+ int finalSize = LCMapStringW(d->localeID, LCMAP_SORTKEY | d->collator,
+ reinterpret_cast<const wchar_t*>(string.constData()), string.size(),
+ reinterpret_cast<wchar_t*>(ret.data()), ret.size());
+#else
+ int finalSize = LCMapStringEx(LPCWSTR(d->localeName.utf16()), LCMAP_SORTKEY | d->collator,
+ reinterpret_cast<LPCWSTR>(string.constData()), string.size(),
+ reinterpret_cast<LPWSTR>(ret.data()), ret.size(),
+ NULL, NULL, 0);
+#endif
+ if (finalSize == 0) {
+ qWarning()
+ << "there were problems when generating the ::sortKey by LCMapStringW with error:"
+ << GetLastError();
+ }
+ return QCollatorSortKey(new QCollatorSortKeyPrivate(std::move(ret)));
+}
+
+int QCollatorSortKey::compare(const QCollatorSortKey &otherKey) const
+{
+ return d->m_key.compare(otherKey.d->m_key);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qdoublescanprint_p.h b/src/corelib/text/qdoublescanprint_p.h
new file mode 100644
index 0000000000..3865c69a99
--- /dev/null
+++ b/src/corelib/text/qdoublescanprint_p.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDOUBLESCANPRINT_P_H
+#define QDOUBLESCANPRINT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qglobal.h>
+
+#if defined(Q_CC_MSVC) && (defined(QT_BOOTSTRAPPED) || defined(QT_NO_DOUBLECONVERSION))
+# include <stdio.h>
+# include <locale.h>
+
+QT_BEGIN_NAMESPACE
+
+// We can always use _sscanf_l and _snprintf_l on MSVC as those were introduced in 2005.
+
+// MSVC doesn't document what it will do with a NULL locale passed to _sscanf_l or _snprintf_l.
+// The documentation for _create_locale() does not formally document "C" to be valid, but an example
+// code snippet in the same documentation shows it.
+
+struct QCLocaleT {
+ QCLocaleT() : locale(_create_locale(LC_ALL, "C"))
+ {
+ }
+
+ ~QCLocaleT()
+ {
+ _free_locale(locale);
+ }
+
+ const _locale_t locale;
+};
+
+# define QT_CLOCALE_HOLDER Q_GLOBAL_STATIC(QCLocaleT, cLocaleT)
+# define QT_CLOCALE cLocaleT()->locale
+
+inline int qDoubleSscanf(const char *buf, _locale_t locale, const char *format, double *d,
+ int *processed)
+{
+ return _sscanf_l(buf, format, locale, d, processed);
+}
+
+inline int qDoubleSnprintf(char *buf, size_t buflen, _locale_t locale, const char *format, double d)
+{
+ return _snprintf_l(buf, buflen, format, locale, d);
+}
+
+QT_END_NAMESPACE
+
+#elif defined(QT_BOOTSTRAPPED)
+# include <stdio.h>
+
+QT_BEGIN_NAMESPACE
+
+// When bootstrapping we don't have libdouble-conversion available, yet. We can also not use locale
+// aware snprintf and sscanf variants in the general case because those are only available on select
+// platforms. We can use the regular snprintf and sscanf because we don't do setlocale(3) when
+// bootstrapping and the locale is always "C" then.
+
+# define QT_CLOCALE_HOLDER
+# define QT_CLOCALE 0
+
+inline int qDoubleSscanf(const char *buf, int, const char *format, double *d, int *processed)
+{
+ return sscanf(buf, format, d, processed);
+}
+inline int qDoubleSnprintf(char *buf, size_t buflen, int, const char *format, double d)
+{
+ return snprintf(buf, buflen, format, d);
+}
+
+QT_END_NAMESPACE
+
+#else // !QT_BOOTSTRAPPED && (!Q_CC_MSVC || !QT_NO_DOUBLECONVERSION)
+# ifdef QT_NO_DOUBLECONVERSION
+# include <stdio.h>
+# include <xlocale.h>
+
+QT_BEGIN_NAMESPACE
+
+// OS X and FreeBSD both treat NULL as the "C" locale for snprintf_l and sscanf_l.
+// When other implementations with different behavior show up, we'll have to do newlocale(3) and
+// freelocale(3) here. The arguments to those will depend on what the other implementations will
+// offer. OS X and FreeBSD again interpret a locale name of NULL as "C", but "C" itself is not
+// documented as valid locale name. Mind that the names of the LC_* constants differ between e.g.
+// BSD variants and linux.
+
+# define QT_CLOCALE_HOLDER
+# define QT_CLOCALE NULL
+
+inline int qDoubleSscanf(const char *buf, locale_t locale, const char *format, double *d,
+ int *processed)
+{
+ return sscanf_l(buf, locale, format, d, processed);
+}
+inline int qDoubleSnprintf(char *buf, size_t buflen, locale_t locale, const char *format, double d)
+{
+ return snprintf_l(buf, buflen, locale, format, d);
+}
+
+QT_END_NAMESPACE
+
+# else // !QT_NO_DOUBLECONVERSION
+# include <double-conversion/double-conversion.h>
+# define QT_CLOCALE_HOLDER
+# endif // QT_NO_DOUBLECONVERSION
+#endif // QT_BOOTSTRAPPED
+
+#endif // QDOUBLESCANPRINT_P_H
diff --git a/src/corelib/text/qharfbuzz.cpp b/src/corelib/text/qharfbuzz.cpp
new file mode 100644
index 0000000000..a3e266ccd2
--- /dev/null
+++ b/src/corelib/text/qharfbuzz.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qharfbuzz_p.h"
+
+#include "qunicodetables_p.h"
+#if QT_CONFIG(library)
+#include "qlibrary.h"
+#endif
+
+QT_USE_NAMESPACE
+
+extern "C" {
+
+void HB_GetUnicodeCharProperties(HB_UChar32 ch, HB_CharCategory *category, int *combiningClass)
+{
+ const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ch);
+ *category = (HB_CharCategory)prop->category;
+ *combiningClass = prop->combiningClass;
+}
+
+HB_CharCategory HB_GetUnicodeCharCategory(HB_UChar32 ch)
+{
+ return (HB_CharCategory)QChar::category(ch);
+}
+
+int HB_GetUnicodeCharCombiningClass(HB_UChar32 ch)
+{
+ return QChar::combiningClass(ch);
+}
+
+HB_UChar16 HB_GetMirroredChar(HB_UChar16 ch)
+{
+ return QChar::mirroredChar(ch);
+}
+
+void (*HB_Library_Resolve(const char *library, int version, const char *symbol))()
+{
+#if !QT_CONFIG(library)
+ Q_UNUSED(library);
+ Q_UNUSED(version);
+ Q_UNUSED(symbol);
+ return 0;
+#else
+ return QLibrary::resolve(QLatin1String(library), version, symbol);
+#endif
+}
+
+} // extern "C"
+
+QT_BEGIN_NAMESPACE
+
+HB_Bool qShapeItem(HB_ShaperItem *item)
+{
+ return HB_ShapeItem(item);
+}
+
+HB_Face qHBNewFace(void *font, HB_GetFontTableFunc tableFunc)
+{
+ return HB_AllocFace(font, tableFunc);
+}
+
+HB_Face qHBLoadFace(HB_Face face)
+{
+ return HB_LoadFace(face);
+}
+
+void qHBFreeFace(HB_Face face)
+{
+ HB_FreeFace(face);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/text/qharfbuzz_p.h b/src/corelib/text/qharfbuzz_p.h
new file mode 100644
index 0000000000..2a0307d35f
--- /dev/null
+++ b/src/corelib/text/qharfbuzz_p.h
@@ -0,0 +1,357 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qglobal_p.h>
+
+#ifndef QHARFBUZZ_P_H
+#define QHARFBUZZ_P_H
+
+#include <QtCore/qchar.h>
+
+#if defined(QT_BUILD_CORE_LIB)
+# include <harfbuzz-shaper.h>
+#else
+// a minimal set of HB types required for Qt libs other than Core
+extern "C" {
+
+typedef enum {
+ /* no error */
+ HB_Err_Ok = 0x0000,
+ HB_Err_Not_Covered = 0xFFFF,
+
+ /* _hb_err() is called whenever returning the following errors,
+ * and in a couple places for HB_Err_Not_Covered too. */
+
+ /* programmer error */
+ HB_Err_Invalid_Argument = 0x1A66,
+
+ /* font error */
+ HB_Err_Invalid_SubTable_Format = 0x157F,
+ HB_Err_Invalid_SubTable = 0x1570,
+ HB_Err_Read_Error = 0x6EAD,
+
+ /* system error */
+ HB_Err_Out_Of_Memory = 0xDEAD
+} HB_Error;
+
+typedef QT_PREPEND_NAMESPACE(qint8) hb_int8;
+typedef QT_PREPEND_NAMESPACE(quint8) hb_uint8;
+typedef QT_PREPEND_NAMESPACE(qint16) hb_int16;
+typedef QT_PREPEND_NAMESPACE(quint16) hb_uint16;
+typedef QT_PREPEND_NAMESPACE(qint32) hb_int32;
+typedef QT_PREPEND_NAMESPACE(quint32) hb_uint32;
+
+typedef hb_uint8 HB_Bool;
+typedef hb_uint8 HB_Byte;
+typedef hb_uint16 HB_UShort;
+typedef hb_uint32 HB_UInt;
+typedef hb_int8 HB_Char;
+typedef hb_int16 HB_Short;
+typedef hb_int32 HB_Int;
+typedef hb_uint16 HB_UChar16;
+typedef hb_uint32 HB_UChar32;
+typedef hb_uint32 HB_Glyph;
+typedef hb_int32 HB_Fixed; /* 26.6 */
+typedef hb_int32 HB_16Dot16; /* 16.16 */
+typedef hb_uint32 HB_Tag;
+
+typedef struct {
+ HB_Fixed x;
+ HB_Fixed y;
+} HB_FixedPoint;
+
+typedef enum {
+ HB_Script_Common,
+ HB_Script_Greek,
+ HB_Script_Cyrillic,
+ HB_Script_Armenian,
+ HB_Script_Hebrew,
+ HB_Script_Arabic,
+ HB_Script_Syriac,
+ HB_Script_Thaana,
+ HB_Script_Devanagari,
+ HB_Script_Bengali,
+ HB_Script_Gurmukhi,
+ HB_Script_Gujarati,
+ HB_Script_Oriya,
+ HB_Script_Tamil,
+ HB_Script_Telugu,
+ HB_Script_Kannada,
+ HB_Script_Malayalam,
+ HB_Script_Sinhala,
+ HB_Script_Thai,
+ HB_Script_Lao,
+ HB_Script_Tibetan,
+ HB_Script_Myanmar,
+ HB_Script_Georgian,
+ HB_Script_Hangul,
+ HB_Script_Ogham,
+ HB_Script_Runic,
+ HB_Script_Khmer,
+ HB_Script_Nko,
+ HB_Script_Inherited,
+ HB_ScriptCount = HB_Script_Inherited
+} HB_Script;
+
+#ifdef __xlC__
+typedef unsigned hb_bitfield;
+#else
+typedef hb_uint8 hb_bitfield;
+#endif
+
+typedef struct {
+ hb_bitfield justification :4; /* Justification class */
+ hb_bitfield clusterStart :1; /* First glyph of representation of cluster */
+ hb_bitfield mark :1; /* needs to be positioned around base char */
+ hb_bitfield zeroWidth :1; /* ZWJ, ZWNJ etc, with no width */
+ hb_bitfield dontPrint :1;
+ hb_bitfield combiningClass :8;
+} HB_GlyphAttributes;
+
+typedef void * HB_GDEF;
+typedef void * HB_GSUB;
+typedef void * HB_GPOS;
+typedef void * HB_Buffer;
+
+typedef HB_Error (*HB_GetFontTableFunc)(void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length);
+
+typedef struct HB_FaceRec_ {
+ HB_Bool isSymbolFont;
+
+ HB_GDEF gdef;
+ HB_GSUB gsub;
+ HB_GPOS gpos;
+ HB_Bool supported_scripts[HB_ScriptCount];
+ HB_Buffer buffer;
+ HB_Script current_script;
+ int current_flags; /* HB_ShaperFlags */
+ HB_Bool has_opentype_kerning;
+ HB_Bool glyphs_substituted;
+ HB_GlyphAttributes *tmpAttributes;
+ unsigned int *tmpLogClusters;
+ int length;
+ int orig_nglyphs;
+ void *font_for_init;
+ HB_GetFontTableFunc get_font_table_func;
+} HB_FaceRec;
+
+typedef struct {
+ HB_Fixed x, y;
+ HB_Fixed width, height;
+ HB_Fixed xOffset, yOffset;
+} HB_GlyphMetrics;
+
+typedef enum {
+ HB_FontAscent
+} HB_FontMetric;
+
+struct HB_Font_;
+typedef struct HB_Font_ *HB_Font;
+typedef struct HB_FaceRec_ *HB_Face;
+
+typedef struct {
+ HB_Bool (*convertStringToGlyphIndices)(HB_Font font, const HB_UChar16 *string, hb_uint32 length, HB_Glyph *glyphs, hb_uint32 *numGlyphs, HB_Bool rightToLeft);
+ void (*getGlyphAdvances)(HB_Font font, const HB_Glyph *glyphs, hb_uint32 numGlyphs, HB_Fixed *advances, int flags /*HB_ShaperFlag*/);
+ HB_Bool (*canRender)(HB_Font font, const HB_UChar16 *string, hb_uint32 length);
+ /* implementation needs to make sure to load a scaled glyph, so /no/ FT_LOAD_NO_SCALE */
+ HB_Error (*getPointInOutline)(HB_Font font, HB_Glyph glyph, int flags /*HB_ShaperFlag*/, hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, hb_uint32 *nPoints);
+ void (*getGlyphMetrics)(HB_Font font, HB_Glyph glyph, HB_GlyphMetrics *metrics);
+ HB_Fixed (*getFontMetric)(HB_Font font, HB_FontMetric metric);
+} HB_FontClass;
+
+typedef struct HB_Font_ {
+ const HB_FontClass *klass;
+
+ /* Metrics */
+ HB_UShort x_ppem, y_ppem;
+ HB_16Dot16 x_scale, y_scale;
+
+ void *userData;
+} HB_FontRec;
+
+typedef enum {
+ HB_LeftToRight = 0,
+ HB_RightToLeft = 1
+} HB_StringToGlyphsFlags;
+
+typedef enum {
+ HB_ShaperFlag_Default = 0,
+ HB_ShaperFlag_NoKerning = 1,
+ HB_ShaperFlag_UseDesignMetrics = 2
+} HB_ShaperFlag;
+
+typedef struct
+{
+ hb_uint32 pos;
+ hb_uint32 length;
+ HB_Script script;
+ hb_uint8 bidiLevel;
+} HB_ScriptItem;
+
+typedef struct HB_ShaperItem_ HB_ShaperItem;
+
+struct HB_ShaperItem_ {
+ const HB_UChar16 *string; /* input: the Unicode UTF16 text to be shaped */
+ hb_uint32 stringLength; /* input: the length of the input in 16-bit words */
+ HB_ScriptItem item; /* input: the current run to be shaped: a run of text all in the same script that is a substring of <string> */
+ HB_Font font; /* input: the font: scale, units and function pointers supplying glyph indices and metrics */
+ HB_Face face; /* input: the shaper state; current script, access to the OpenType tables , etc. */
+ int shaperFlags; /* input (unused) should be set to 0; intended to support flags defined in HB_ShaperFlag */
+ HB_Bool glyphIndicesPresent; /* input: true if the <glyphs> array contains glyph indices ready to be shaped */
+ hb_uint32 initialGlyphCount; /* input: if glyphIndicesPresent is true, the number of glyph indices in the <glyphs> array */
+
+ hb_uint32 num_glyphs; /* input: capacity of output arrays <glyphs>, <attributes>, <advances>, <offsets>, and <log_clusters>; */
+ /* output: required capacity (may be larger than actual capacity) */
+
+ HB_Glyph *glyphs; /* output: <num_glyphs> indices of shaped glyphs */
+ HB_GlyphAttributes *attributes; /* output: <num_glyphs> glyph attributes */
+ HB_Fixed *advances; /* output: <num_glyphs> advances */
+ HB_FixedPoint *offsets; /* output: <num_glyphs> offsets */
+ unsigned short *log_clusters; /* output: for each output glyph, the index in the input of the start of its logical cluster */
+
+ /* internal */
+ HB_Bool kerning_applied; /* output: true if kerning was applied by the shaper */
+};
+
+}
+
+#endif // QT_BUILD_CORE_LIB
+
+
+QT_BEGIN_NAMESPACE
+
+static inline HB_Script script_to_hbscript(uchar script)
+{
+ switch (script) {
+ case QChar::Script_Inherited: return HB_Script_Inherited;
+ case QChar::Script_Common: return HB_Script_Common;
+ case QChar::Script_Arabic: return HB_Script_Arabic;
+ case QChar::Script_Armenian: return HB_Script_Armenian;
+ case QChar::Script_Bengali: return HB_Script_Bengali;
+ case QChar::Script_Cyrillic: return HB_Script_Cyrillic;
+ case QChar::Script_Devanagari: return HB_Script_Devanagari;
+ case QChar::Script_Georgian: return HB_Script_Georgian;
+ case QChar::Script_Greek: return HB_Script_Greek;
+ case QChar::Script_Gujarati: return HB_Script_Gujarati;
+ case QChar::Script_Gurmukhi: return HB_Script_Gurmukhi;
+ case QChar::Script_Hangul: return HB_Script_Hangul;
+ case QChar::Script_Hebrew: return HB_Script_Hebrew;
+ case QChar::Script_Kannada: return HB_Script_Kannada;
+ case QChar::Script_Khmer: return HB_Script_Khmer;
+ case QChar::Script_Lao: return HB_Script_Lao;
+ case QChar::Script_Malayalam: return HB_Script_Malayalam;
+ case QChar::Script_Myanmar: return HB_Script_Myanmar;
+ case QChar::Script_Ogham: return HB_Script_Ogham;
+ case QChar::Script_Oriya: return HB_Script_Oriya;
+ case QChar::Script_Runic: return HB_Script_Runic;
+ case QChar::Script_Sinhala: return HB_Script_Sinhala;
+ case QChar::Script_Syriac: return HB_Script_Syriac;
+ case QChar::Script_Tamil: return HB_Script_Tamil;
+ case QChar::Script_Telugu: return HB_Script_Telugu;
+ case QChar::Script_Thaana: return HB_Script_Thaana;
+ case QChar::Script_Thai: return HB_Script_Thai;
+ case QChar::Script_Tibetan: return HB_Script_Tibetan;
+ case QChar::Script_Nko: return HB_Script_Nko;
+ default: break;
+ };
+ return HB_Script_Common;
+}
+
+static inline uchar hbscript_to_script(uchar script)
+{
+ switch (script) {
+ case HB_Script_Inherited: return QChar::Script_Inherited;
+ case HB_Script_Common: return QChar::Script_Common;
+ case HB_Script_Arabic: return QChar::Script_Arabic;
+ case HB_Script_Armenian: return QChar::Script_Armenian;
+ case HB_Script_Bengali: return QChar::Script_Bengali;
+ case HB_Script_Cyrillic: return QChar::Script_Cyrillic;
+ case HB_Script_Devanagari: return QChar::Script_Devanagari;
+ case HB_Script_Georgian: return QChar::Script_Georgian;
+ case HB_Script_Greek: return QChar::Script_Greek;
+ case HB_Script_Gujarati: return QChar::Script_Gujarati;
+ case HB_Script_Gurmukhi: return QChar::Script_Gurmukhi;
+ case HB_Script_Hangul: return QChar::Script_Hangul;
+ case HB_Script_Hebrew: return QChar::Script_Hebrew;
+ case HB_Script_Kannada: return QChar::Script_Kannada;
+ case HB_Script_Khmer: return QChar::Script_Khmer;
+ case HB_Script_Lao: return QChar::Script_Lao;
+ case HB_Script_Malayalam: return QChar::Script_Malayalam;
+ case HB_Script_Myanmar: return QChar::Script_Myanmar;
+ case HB_Script_Ogham: return QChar::Script_Ogham;
+ case HB_Script_Oriya: return QChar::Script_Oriya;
+ case HB_Script_Runic: return QChar::Script_Runic;
+ case HB_Script_Sinhala: return QChar::Script_Sinhala;
+ case HB_Script_Syriac: return QChar::Script_Syriac;
+ case HB_Script_Tamil: return QChar::Script_Tamil;
+ case HB_Script_Telugu: return QChar::Script_Telugu;
+ case HB_Script_Thaana: return QChar::Script_Thaana;
+ case HB_Script_Thai: return QChar::Script_Thai;
+ case HB_Script_Tibetan: return QChar::Script_Tibetan;
+ case HB_Script_Nko: return QChar::Script_Nko;
+ default: break;
+ };
+ return QChar::Script_Common;
+}
+
+Q_CORE_EXPORT HB_Bool qShapeItem(HB_ShaperItem *item);
+
+// ### temporary
+Q_CORE_EXPORT HB_Face qHBNewFace(void *font, HB_GetFontTableFunc tableFunc);
+Q_CORE_EXPORT void qHBFreeFace(HB_Face);
+Q_CORE_EXPORT HB_Face qHBLoadFace(HB_Face face);
+
+Q_DECLARE_TYPEINFO(HB_GlyphAttributes, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(HB_FixedPoint, Q_PRIMITIVE_TYPE);
+Q_DECLARE_TYPEINFO(HB_ScriptItem, Q_PRIMITIVE_TYPE);
+
+QT_END_NAMESPACE
+
+#endif // QHARFBUZZ_P_H
diff --git a/src/corelib/text/qlocale.cpp b/src/corelib/text/qlocale.cpp
new file mode 100644
index 0000000000..939f8eb34d
--- /dev/null
+++ b/src/corelib/text/qlocale.cpp
@@ -0,0 +1,4223 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2019 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglobal.h"
+
+#if !defined(QWS) && defined(Q_OS_MAC)
+# include "private/qcore_mac_p.h"
+# include <CoreFoundation/CoreFoundation.h>
+#endif
+
+#include "qplatformdefs.h"
+
+#include "qdatastream.h"
+#include "qdebug.h"
+#include "qhashfunctions.h"
+#include "qstring.h"
+#include "qlocale.h"
+#include "qlocale_p.h"
+#include "qlocale_tools_p.h"
+#if QT_CONFIG(datetimeparser)
+#include "private/qdatetimeparser_p.h"
+#endif
+#include "qnamespace.h"
+#include "qdatetime.h"
+#include "qstringlist.h"
+#include "qvariant.h"
+#include "qstringbuilder.h"
+#include "private/qnumeric_p.h"
+#include <cmath>
+#ifndef QT_NO_SYSTEMLOCALE
+# include "qmutex.h"
+#endif
+#ifdef Q_OS_WIN
+# include <qt_windows.h>
+# include <time.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_SYSTEMLOCALE
+static QSystemLocale *_systemLocale = 0;
+class QSystemLocaleSingleton: public QSystemLocale
+{
+public:
+ QSystemLocaleSingleton() : QSystemLocale(true) {}
+};
+
+Q_GLOBAL_STATIC(QSystemLocaleSingleton, QSystemLocale_globalSystemLocale)
+static QLocaleData globalLocaleData;
+#endif
+
+/******************************************************************************
+** Helpers for accessing Qt locale database
+*/
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "qlocale_data_p.h"
+QT_END_INCLUDE_NAMESPACE
+
+QLocale::Language QLocalePrivate::codeToLanguage(QStringView code) noexcept
+{
+ const auto len = code.size();
+ if (len != 2 && len != 3)
+ return QLocale::C;
+ ushort uc1 = code[0].toLower().unicode();
+ ushort uc2 = code[1].toLower().unicode();
+ ushort uc3 = len > 2 ? code[2].toLower().unicode() : 0;
+
+ const unsigned char *c = language_code_list;
+ for (; *c != 0; c += 3) {
+ if (uc1 == c[0] && uc2 == c[1] && uc3 == c[2])
+ return QLocale::Language((c - language_code_list)/3);
+ }
+
+ if (uc3 == 0) {
+ // legacy codes
+ if (uc1 == 'n' && uc2 == 'o') { // no -> nb
+ Q_STATIC_ASSERT(QLocale::Norwegian == QLocale::NorwegianBokmal);
+ return QLocale::Norwegian;
+ }
+ if (uc1 == 't' && uc2 == 'l') { // tl -> fil
+ Q_STATIC_ASSERT(QLocale::Tagalog == QLocale::Filipino);
+ return QLocale::Tagalog;
+ }
+ if (uc1 == 's' && uc2 == 'h') { // sh -> sr[_Latn]
+ Q_STATIC_ASSERT(QLocale::SerboCroatian == QLocale::Serbian);
+ return QLocale::SerboCroatian;
+ }
+ if (uc1 == 'm' && uc2 == 'o') { // mo -> ro
+ Q_STATIC_ASSERT(QLocale::Moldavian == QLocale::Romanian);
+ return QLocale::Moldavian;
+ }
+ // Android uses the following deprecated codes
+ if (uc1 == 'i' && uc2 == 'w') // iw -> he
+ return QLocale::Hebrew;
+ if (uc1 == 'i' && uc2 == 'n') // in -> id
+ return QLocale::Indonesian;
+ if (uc1 == 'j' && uc2 == 'i') // ji -> yi
+ return QLocale::Yiddish;
+ }
+ return QLocale::C;
+}
+
+QLocale::Script QLocalePrivate::codeToScript(QStringView code) noexcept
+{
+ const auto len = code.size();
+ if (len != 4)
+ return QLocale::AnyScript;
+
+ // script is titlecased in our data
+ unsigned char c0 = code[0].toUpper().toLatin1();
+ unsigned char c1 = code[1].toLower().toLatin1();
+ unsigned char c2 = code[2].toLower().toLatin1();
+ unsigned char c3 = code[3].toLower().toLatin1();
+
+ const unsigned char *c = script_code_list;
+ for (int i = 0; i < QLocale::LastScript; ++i, c += 4) {
+ if (c0 == c[0] && c1 == c[1] && c2 == c[2] && c3 == c[3])
+ return QLocale::Script(i);
+ }
+ return QLocale::AnyScript;
+}
+
+QLocale::Country QLocalePrivate::codeToCountry(QStringView code) noexcept
+{
+ const auto len = code.size();
+ if (len != 2 && len != 3)
+ return QLocale::AnyCountry;
+
+ ushort uc1 = code[0].toUpper().unicode();
+ ushort uc2 = code[1].toUpper().unicode();
+ ushort uc3 = len > 2 ? code[2].toUpper().unicode() : 0;
+
+ const unsigned char *c = country_code_list;
+ for (; *c != 0; c += 3) {
+ if (uc1 == c[0] && uc2 == c[1] && uc3 == c[2])
+ return QLocale::Country((c - country_code_list)/3);
+ }
+
+ return QLocale::AnyCountry;
+}
+
+QLatin1String QLocalePrivate::languageToCode(QLocale::Language language)
+{
+ if (language == QLocale::AnyLanguage)
+ return QLatin1String();
+ if (language == QLocale::C)
+ return QLatin1String("C");
+
+ const unsigned char *c = language_code_list + 3*(uint(language));
+
+ return QLatin1String(reinterpret_cast<const char*>(c), c[2] == 0 ? 2 : 3);
+
+}
+
+QLatin1String QLocalePrivate::scriptToCode(QLocale::Script script)
+{
+ if (script == QLocale::AnyScript || script > QLocale::LastScript)
+ return QLatin1String();
+ const unsigned char *c = script_code_list + 4*(uint(script));
+ return QLatin1String(reinterpret_cast<const char *>(c), 4);
+}
+
+QLatin1String QLocalePrivate::countryToCode(QLocale::Country country)
+{
+ if (country == QLocale::AnyCountry)
+ return QLatin1String();
+
+ const unsigned char *c = country_code_list + 3*(uint(country));
+
+ return QLatin1String(reinterpret_cast<const char*>(c), c[2] == 0 ? 2 : 3);
+}
+
+// http://www.unicode.org/reports/tr35/#Likely_Subtags
+static bool addLikelySubtags(QLocaleId &localeId)
+{
+ // ### optimize with bsearch
+ const int likely_subtags_count = sizeof(likely_subtags) / sizeof(likely_subtags[0]);
+ const QLocaleId *p = likely_subtags;
+ const QLocaleId *const e = p + likely_subtags_count;
+ for ( ; p < e; p += 2) {
+ if (localeId == p[0]) {
+ localeId = p[1];
+ return true;
+ }
+ }
+ return false;
+}
+
+QLocaleId QLocaleId::withLikelySubtagsAdded() const
+{
+ // language_script_region
+ if (language_id || script_id || country_id) {
+ QLocaleId id = QLocaleId::fromIds(language_id, script_id, country_id);
+ if (addLikelySubtags(id))
+ return id;
+ }
+ // language_region
+ if (script_id) {
+ QLocaleId id = QLocaleId::fromIds(language_id, 0, country_id);
+ if (addLikelySubtags(id)) {
+ id.script_id = script_id;
+ return id;
+ }
+ }
+ // language_script
+ if (country_id) {
+ QLocaleId id = QLocaleId::fromIds(language_id, script_id, 0);
+ if (addLikelySubtags(id)) {
+ id.country_id = country_id;
+ return id;
+ }
+ }
+ // language
+ if (script_id && country_id) {
+ QLocaleId id = QLocaleId::fromIds(language_id, 0, 0);
+ if (addLikelySubtags(id)) {
+ id.script_id = script_id;
+ id.country_id = country_id;
+ return id;
+ }
+ }
+ // und_script
+ if (language_id) {
+ QLocaleId id = QLocaleId::fromIds(0, script_id, 0);
+ if (addLikelySubtags(id)) {
+ id.language_id = language_id;
+ return id;
+ }
+ }
+ return *this;
+}
+
+QLocaleId QLocaleId::withLikelySubtagsRemoved() const
+{
+ QLocaleId max = withLikelySubtagsAdded();
+ // language
+ {
+ QLocaleId id = QLocaleId::fromIds(language_id, 0, 0);
+ if (id.withLikelySubtagsAdded() == max)
+ return id;
+ }
+ // language_region
+ if (country_id) {
+ QLocaleId id = QLocaleId::fromIds(language_id, 0, country_id);
+ if (id.withLikelySubtagsAdded() == max)
+ return id;
+ }
+ // language_script
+ if (script_id) {
+ QLocaleId id = QLocaleId::fromIds(language_id, script_id, 0);
+ if (id.withLikelySubtagsAdded() == max)
+ return id;
+ }
+ return max;
+}
+
+QByteArray QLocaleId::name(char separator) const
+{
+ if (language_id == QLocale::AnyLanguage)
+ return QByteArray();
+ if (language_id == QLocale::C)
+ return QByteArrayLiteral("C");
+
+ const unsigned char *lang = language_code_list + 3 * language_id;
+ const unsigned char *script =
+ (script_id != QLocale::AnyScript ? script_code_list + 4 * script_id : nullptr);
+ const unsigned char *country =
+ (country_id != QLocale::AnyCountry ? country_code_list + 3 * country_id : nullptr);
+ char len = (lang[2] != 0 ? 3 : 2) + (script ? 4+1 : 0) + (country ? (country[2] != 0 ? 3 : 2)+1 : 0);
+ QByteArray name(len, Qt::Uninitialized);
+ char *uc = name.data();
+ *uc++ = lang[0];
+ *uc++ = lang[1];
+ if (lang[2] != 0)
+ *uc++ = lang[2];
+ if (script) {
+ *uc++ = separator;
+ *uc++ = script[0];
+ *uc++ = script[1];
+ *uc++ = script[2];
+ *uc++ = script[3];
+ }
+ if (country) {
+ *uc++ = separator;
+ *uc++ = country[0];
+ *uc++ = country[1];
+ if (country[2] != 0)
+ *uc++ = country[2];
+ }
+ return name;
+}
+
+QByteArray QLocalePrivate::bcp47Name(char separator) const
+{
+ if (m_data->m_language_id == QLocale::AnyLanguage)
+ return QByteArray();
+ if (m_data->m_language_id == QLocale::C)
+ return QByteArrayLiteral("en");
+
+ QLocaleId localeId = QLocaleId::fromIds(m_data->m_language_id, m_data->m_script_id, m_data->m_country_id);
+ return localeId.withLikelySubtagsRemoved().name(separator);
+}
+
+static const QLocaleData *findLocaleDataById(const QLocaleId &localeId)
+{
+ const uint idx = locale_index[localeId.language_id];
+
+ const QLocaleData *data = locale_data + idx;
+
+ if (idx == 0) // default language has no associated script or country
+ return data;
+
+ Q_ASSERT(data->m_language_id == localeId.language_id);
+
+ if (localeId.script_id == QLocale::AnyScript && localeId.country_id == QLocale::AnyCountry)
+ return data;
+
+ if (localeId.script_id == QLocale::AnyScript) {
+ do {
+ if (data->m_country_id == localeId.country_id)
+ return data;
+ ++data;
+ } while (data->m_language_id && data->m_language_id == localeId.language_id);
+ } else if (localeId.country_id == QLocale::AnyCountry) {
+ do {
+ if (data->m_script_id == localeId.script_id)
+ return data;
+ ++data;
+ } while (data->m_language_id && data->m_language_id == localeId.language_id);
+ } else {
+ do {
+ if (data->m_script_id == localeId.script_id && data->m_country_id == localeId.country_id)
+ return data;
+ ++data;
+ } while (data->m_language_id && data->m_language_id == localeId.language_id);
+ }
+
+ return nullptr;
+}
+
+const QLocaleData *QLocaleData::findLocaleData(QLocale::Language language, QLocale::Script script, QLocale::Country country)
+{
+ QLocaleId localeId = QLocaleId::fromIds(language, script, country);
+ QLocaleId likelyId = localeId.withLikelySubtagsAdded();
+
+ const uint idx = locale_index[likelyId.language_id];
+
+ // Try a straight match with the likely data:
+ if (const QLocaleData *const data = findLocaleDataById(likelyId))
+ return data;
+ QList<QLocaleId> tried;
+ tried.push_back(likelyId);
+
+ // No match; try again with raw data:
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
+ }
+
+ // No match; try again with likely country
+ if (country != QLocale::AnyCountry
+ && (language != QLocale::AnyLanguage || script != QLocale::AnyScript)) {
+ localeId = QLocaleId::fromIds(language, script, QLocale::AnyCountry);
+ likelyId = localeId.withLikelySubtagsAdded();
+ if (!tried.contains(likelyId)) {
+ if (const QLocaleData *const data = findLocaleDataById(likelyId))
+ return data;
+ tried.push_back(likelyId);
+ }
+
+ // No match; try again with any country
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
+ }
+ }
+
+ // No match; try again with likely script
+ if (script != QLocale::AnyScript
+ && (language != QLocale::AnyLanguage || country != QLocale::AnyCountry)) {
+ localeId = QLocaleId::fromIds(language, QLocale::AnyScript, country);
+ likelyId = localeId.withLikelySubtagsAdded();
+ if (!tried.contains(likelyId)) {
+ if (const QLocaleData *const data = findLocaleDataById(likelyId))
+ return data;
+ tried.push_back(likelyId);
+ }
+
+ // No match; try again with any script
+ if (!tried.contains(localeId)) {
+ if (const QLocaleData *const data = findLocaleDataById(localeId))
+ return data;
+ tried.push_back(localeId);
+ }
+ }
+
+ // No match; return data at original index
+ return locale_data + idx;
+}
+
+static bool parse_locale_tag(const QString &input, int &i, QString *result, const QString &separators)
+{
+ *result = QString(8, Qt::Uninitialized); // worst case according to BCP47
+ QChar *pch = result->data();
+ const QChar *uc = input.data() + i;
+ const int l = input.length();
+ int size = 0;
+ for (; i < l && size < 8; ++i, ++size) {
+ if (separators.contains(*uc))
+ break;
+ if (! ((uc->unicode() >= 'a' && uc->unicode() <= 'z') ||
+ (uc->unicode() >= 'A' && uc->unicode() <= 'Z') ||
+ (uc->unicode() >= '0' && uc->unicode() <= '9')) ) // latin only
+ return false;
+ *pch++ = *uc++;
+ }
+ result->truncate(size);
+ return true;
+}
+
+bool qt_splitLocaleName(const QString &name, QString &lang, QString &script, QString &cntry)
+{
+ const int length = name.length();
+
+ lang = script = cntry = QString();
+
+ const QString separators = QStringLiteral("_-.@");
+ enum ParserState { NoState, LangState, ScriptState, CountryState };
+ ParserState state = LangState;
+ for (int i = 0; i < length && state != NoState; ) {
+ QString value;
+ if (!parse_locale_tag(name, i, &value, separators) ||value.isEmpty())
+ break;
+ QChar sep = i < length ? name.at(i) : QChar();
+ switch (state) {
+ case LangState:
+ if (!sep.isNull() && !separators.contains(sep)) {
+ state = NoState;
+ break;
+ }
+ lang = value;
+ if (i == length) {
+ // just language was specified
+ state = NoState;
+ break;
+ }
+ state = ScriptState;
+ break;
+ case ScriptState: {
+ QString scripts = QString::fromLatin1((const char *)script_code_list, sizeof(script_code_list) - 1);
+ if (value.length() == 4 && scripts.indexOf(value) % 4 == 0) {
+ // script name is always 4 characters
+ script = value;
+ state = CountryState;
+ } else {
+ // it wasn't a script, maybe it is a country then?
+ cntry = value;
+ state = NoState;
+ }
+ break;
+ }
+ case CountryState:
+ cntry = value;
+ state = NoState;
+ break;
+ case NoState:
+ // shouldn't happen
+ qWarning("QLocale: This should never happen");
+ break;
+ }
+ ++i;
+ }
+ return lang.length() == 2 || lang.length() == 3;
+}
+
+void QLocalePrivate::getLangAndCountry(const QString &name, QLocale::Language &lang,
+ QLocale::Script &script, QLocale::Country &cntry)
+{
+ lang = QLocale::C;
+ script = QLocale::AnyScript;
+ cntry = QLocale::AnyCountry;
+
+ QString lang_code;
+ QString script_code;
+ QString cntry_code;
+ if (!qt_splitLocaleName(name, lang_code, script_code, cntry_code))
+ return;
+
+ lang = QLocalePrivate::codeToLanguage(lang_code);
+ if (lang == QLocale::C)
+ return;
+ script = QLocalePrivate::codeToScript(script_code);
+ cntry = QLocalePrivate::codeToCountry(cntry_code);
+}
+
+static const QLocaleData *findLocaleData(const QString &name)
+{
+ QLocale::Language lang;
+ QLocale::Script script;
+ QLocale::Country cntry;
+ QLocalePrivate::getLangAndCountry(name, lang, script, cntry);
+
+ return QLocaleData::findLocaleData(lang, script, cntry);
+}
+
+QString qt_readEscapedFormatString(QStringView format, int *idx)
+{
+ int &i = *idx;
+
+ Q_ASSERT(format.at(i) == QLatin1Char('\''));
+ ++i;
+ if (i == format.size())
+ return QString();
+ if (format.at(i).unicode() == '\'') { // "''" outside of a quoted stirng
+ ++i;
+ return QLatin1String("'");
+ }
+
+ QString result;
+
+ while (i < format.size()) {
+ if (format.at(i).unicode() == '\'') {
+ if (i + 1 < format.size() && format.at(i + 1).unicode() == '\'') {
+ // "''" inside of a quoted string
+ result.append(QLatin1Char('\''));
+ i += 2;
+ } else {
+ break;
+ }
+ } else {
+ result.append(format.at(i++));
+ }
+ }
+ if (i < format.size())
+ ++i;
+
+ return result;
+}
+
+/*!
+ \internal
+
+ Counts the number of identical leading characters in \a s.
+
+ If \a s is empty, returns 0.
+
+ Otherwise, returns the number of consecutive \c{s.front()}
+ characters at the start of \a s.
+
+ \code
+ qt_repeatCount(u"a"); // == 1
+ qt_repeatCount(u"ab"); // == 1
+ qt_repeatCount(u"aab"); // == 2
+ \endcode
+*/
+int qt_repeatCount(QStringView s)
+{
+ if (s.isEmpty())
+ return 0;
+ const QChar c = s.front();
+ qsizetype j = 1;
+ while (j < s.size() && s.at(j) == c)
+ ++j;
+ return int(j);
+}
+
+static const QLocaleData *default_data = nullptr;
+static QLocale::NumberOptions default_number_options = QLocale::DefaultNumberOptions;
+
+static const QLocaleData *const c_data = locale_data;
+static QLocalePrivate *c_private()
+{
+ static QLocalePrivate c_locale = { c_data, Q_BASIC_ATOMIC_INITIALIZER(1), QLocale::OmitGroupSeparator };
+ return &c_locale;
+}
+
+#ifndef QT_NO_SYSTEMLOCALE
+/******************************************************************************
+** Default system locale behavior
+*/
+
+/*!
+ Constructs a QSystemLocale object.
+
+ The constructor will automatically install this object as the system locale,
+ if there's not one active. It also resets the flag that'll prompt
+ QLocale::system() to re-initialize its data, so that instantiating a
+ QSystemLocale transiently (doesn't install the transient as system locale if
+ there was one already and) triggers an update to the system locale's data.
+*/
+QSystemLocale::QSystemLocale()
+{
+ if (!_systemLocale)
+ _systemLocale = this;
+
+ globalLocaleData.m_language_id = 0;
+}
+
+/*!
+ \internal
+*/
+QSystemLocale::QSystemLocale(bool)
+{ }
+
+/*!
+ Deletes the object.
+*/
+QSystemLocale::~QSystemLocale()
+{
+ if (_systemLocale == this) {
+ _systemLocale = 0;
+
+ globalLocaleData.m_language_id = 0;
+ }
+}
+
+static const QSystemLocale *systemLocale()
+{
+ if (_systemLocale)
+ return _systemLocale;
+ return QSystemLocale_globalSystemLocale();
+}
+
+static void updateSystemPrivate()
+{
+ // This function is NOT thread-safe!
+ // It *should not* be called by anything but systemData()
+ const QSystemLocale *sys_locale = systemLocale();
+
+ // tell the object that the system locale has changed.
+ sys_locale->query(QSystemLocale::LocaleChanged, QVariant());
+
+ // Populate global with fallback as basis:
+ globalLocaleData = *sys_locale->fallbackUiLocaleData();
+
+ QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
+ if (!res.isNull()) {
+ globalLocaleData.m_language_id = res.toInt();
+ globalLocaleData.m_script_id = QLocale::AnyScript; // default for compatibility
+ }
+ res = sys_locale->query(QSystemLocale::CountryId, QVariant());
+ if (!res.isNull()) {
+ globalLocaleData.m_country_id = res.toInt();
+ globalLocaleData.m_script_id = QLocale::AnyScript; // default for compatibility
+ }
+ res = sys_locale->query(QSystemLocale::ScriptId, QVariant());
+ if (!res.isNull())
+ globalLocaleData.m_script_id = res.toInt();
+
+ res = sys_locale->query(QSystemLocale::DecimalPoint, QVariant());
+ if (!res.isNull())
+ globalLocaleData.m_decimal = res.toString().at(0).unicode();
+
+ res = sys_locale->query(QSystemLocale::GroupSeparator, QVariant());
+ if (!res.isNull())
+ globalLocaleData.m_group = res.toString().at(0).unicode();
+
+ res = sys_locale->query(QSystemLocale::ZeroDigit, QVariant());
+ if (!res.isNull())
+ globalLocaleData.m_zero = res.toString().at(0).unicode();
+
+ res = sys_locale->query(QSystemLocale::NegativeSign, QVariant());
+ if (!res.isNull())
+ globalLocaleData.m_minus = res.toString().at(0).unicode();
+
+ res = sys_locale->query(QSystemLocale::PositiveSign, QVariant());
+ if (!res.isNull())
+ globalLocaleData.m_plus = res.toString().at(0).unicode();
+}
+#endif // !QT_NO_SYSTEMLOCALE
+
+static const QLocaleData *systemData()
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ /*
+ Copy over the information from the fallback locale and modify.
+
+ This modifies (cross-thread) global state, so take care to only call it in
+ one thread.
+ */
+ {
+ static QBasicMutex systemDataMutex;
+ systemDataMutex.lock();
+ if (globalLocaleData.m_language_id == 0)
+ updateSystemPrivate();
+ systemDataMutex.unlock();
+ }
+
+ return &globalLocaleData;
+#else
+ return locale_data;
+#endif
+}
+
+static const QLocaleData *defaultData()
+{
+ if (!default_data)
+ default_data = systemData();
+ return default_data;
+}
+
+const QLocaleData *QLocaleData::c()
+{
+ Q_ASSERT(locale_index[QLocale::C] == 0);
+ return c_data;
+}
+
+static inline QString getLocaleData(const ushort *data, int size)
+{
+ return size > 0 ? QString::fromRawData(reinterpret_cast<const QChar *>(data), size) : QString();
+}
+
+static QString getLocaleListData(const ushort *data, int size, int index)
+{
+ static const ushort separator = ';';
+ while (index && size > 0) {
+ while (*data != separator)
+ ++data, --size;
+ --index;
+ ++data;
+ --size;
+ }
+ const ushort *end = data;
+ while (size > 0 && *end != separator)
+ ++end, --size;
+ return getLocaleData(data, end - data);
+}
+
+
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &ds, const QLocale &l)
+{
+ ds << l.name();
+ return ds;
+}
+
+QDataStream &operator>>(QDataStream &ds, QLocale &l)
+{
+ QString s;
+ ds >> s;
+ l = QLocale(s);
+ return ds;
+}
+#endif // QT_NO_DATASTREAM
+
+
+static const int locale_data_size = sizeof(locale_data)/sizeof(QLocaleData) - 1;
+
+Q_GLOBAL_STATIC_WITH_ARGS(QSharedDataPointer<QLocalePrivate>, defaultLocalePrivate,
+ (QLocalePrivate::create(defaultData(), default_number_options)))
+Q_GLOBAL_STATIC_WITH_ARGS(QExplicitlySharedDataPointer<QLocalePrivate>, systemLocalePrivate,
+ (QLocalePrivate::create(systemData())))
+
+static QLocalePrivate *localePrivateByName(const QString &name)
+{
+ if (name == QLatin1String("C"))
+ return c_private();
+ const QLocaleData *data = findLocaleData(name);
+ return QLocalePrivate::create(data, data->m_language_id == QLocale::C ?
+ QLocale::OmitGroupSeparator : QLocale::DefaultNumberOptions);
+}
+
+static QLocalePrivate *findLocalePrivate(QLocale::Language language, QLocale::Script script,
+ QLocale::Country country)
+{
+ if (language == QLocale::C)
+ return c_private();
+
+ const QLocaleData *data = QLocaleData::findLocaleData(language, script, country);
+
+ QLocale::NumberOptions numberOptions = QLocale::DefaultNumberOptions;
+
+ // If not found, should default to system
+ if (data->m_language_id == QLocale::C && language != QLocale::C) {
+ numberOptions = default_number_options;
+ data = defaultData();
+ }
+ return QLocalePrivate::create(data, numberOptions);
+}
+
+
+/*!
+ \internal
+*/
+QLocale::QLocale(QLocalePrivate &dd)
+ : d(&dd)
+{}
+
+
+/*!
+ Constructs a QLocale object with the specified \a name,
+ which has the format
+ "language[_script][_country][.codeset][@modifier]" or "C", where:
+
+ \list
+ \li language is a lowercase, two-letter, ISO 639 language code (also some three-letter codes),
+ \li script is a titlecase, four-letter, ISO 15924 script code,
+ \li country is an uppercase, two-letter, ISO 3166 country code (also "419" as defined by United Nations),
+ \li and codeset and modifier are ignored.
+ \endlist
+
+ The separator can be either underscore or a minus sign.
+
+ If the string violates the locale format, or language is not
+ a valid ISO 639 code, the "C" locale is used instead. If country
+ is not present, or is not a valid ISO 3166 code, the most
+ appropriate country is chosen for the specified language.
+
+ The language, script and country codes are converted to their respective
+ \c Language, \c Script and \c Country enums. After this conversion is
+ performed, the constructor behaves exactly like QLocale(Country, Script,
+ Language).
+
+ This constructor is much slower than QLocale(Country, Script, Language).
+
+ \sa bcp47Name()
+*/
+
+QLocale::QLocale(const QString &name)
+ : d(localePrivateByName(name))
+{
+}
+
+/*!
+ Constructs a QLocale object initialized with the default locale. If
+ no default locale was set using setDefault(), this locale will
+ be the same as the one returned by system().
+
+ \sa setDefault()
+*/
+
+QLocale::QLocale()
+ : d(*defaultLocalePrivate)
+{
+ // Make sure system data is up to date
+ systemData();
+}
+
+/*!
+ Constructs a QLocale object with the specified \a language and \a
+ country.
+
+ \list
+ \li If the language/country pair is found in the database, it is used.
+ \li If the language is found but the country is not, or if the country
+ is \c AnyCountry, the language is used with the most
+ appropriate available country (for example, Germany for German),
+ \li If neither the language nor the country are found, QLocale
+ defaults to the default locale (see setDefault()).
+ \endlist
+
+ The language and country that are actually used can be queried
+ using language() and country().
+
+ \sa setDefault(), language(), country()
+*/
+
+QLocale::QLocale(Language language, Country country)
+ : d(findLocalePrivate(language, QLocale::AnyScript, country))
+{
+}
+
+/*!
+ \since 4.8
+
+ Constructs a QLocale object with the specified \a language, \a script and
+ \a country.
+
+ \list
+ \li If the language/script/country is found in the database, it is used.
+ \li If both \a script is AnyScript and \a country is AnyCountry, the
+ language is used with the most appropriate available script and country
+ (for example, Germany for German),
+ \li If either \a script is AnyScript or \a country is AnyCountry, the
+ language is used with the first locale that matches the given \a script
+ and \a country.
+ \li If neither the language nor the country are found, QLocale
+ defaults to the default locale (see setDefault()).
+ \endlist
+
+ The language, script and country that are actually used can be queried
+ using language(), script() and country().
+
+ \sa setDefault(), language(), script(), country()
+*/
+
+QLocale::QLocale(Language language, Script script, Country country)
+ : d(findLocalePrivate(language, script, country))
+{
+}
+
+/*!
+ Constructs a QLocale object as a copy of \a other.
+*/
+
+QLocale::QLocale(const QLocale &other)
+{
+ d = other.d;
+}
+
+/*!
+ Destructor
+*/
+
+QLocale::~QLocale()
+{
+}
+
+/*!
+ Assigns \a other to this QLocale object and returns a reference
+ to this QLocale object.
+*/
+
+QLocale &QLocale::operator=(const QLocale &other)
+{
+ d = other.d;
+ return *this;
+}
+
+bool QLocale::operator==(const QLocale &other) const
+{
+ return d->m_data == other.d->m_data && d->m_numberOptions == other.d->m_numberOptions;
+}
+
+bool QLocale::operator!=(const QLocale &other) const
+{
+ return d->m_data != other.d->m_data || d->m_numberOptions != other.d->m_numberOptions;
+}
+
+/*!
+ \fn void QLocale::swap(QLocale &other)
+ \since 5.6
+
+ Swaps locale \a other with this locale. This operation is very fast and
+ never fails.
+*/
+
+/*!
+ \since 5.6
+ \relates QLocale
+
+ Returns the hash value for \a key, using
+ \a seed to seed the calculation.
+*/
+uint qHash(const QLocale &key, uint seed) noexcept
+{
+ QtPrivate::QHashCombine hash;
+ seed = hash(seed, key.d->m_data);
+ seed = hash(seed, key.d->m_numberOptions);
+ return seed;
+}
+
+/*!
+ \since 4.2
+
+ Sets the \a options related to number conversions for this
+ QLocale instance.
+*/
+void QLocale::setNumberOptions(NumberOptions options)
+{
+ d->m_numberOptions = options;
+}
+
+/*!
+ \since 4.2
+
+ Returns the options related to number conversions for this
+ QLocale instance.
+
+ By default, no options are set for the standard locales.
+*/
+QLocale::NumberOptions QLocale::numberOptions() const
+{
+ return static_cast<NumberOptions>(d->m_numberOptions);
+}
+
+/*!
+ \since 4.8
+
+ Returns \a str quoted according to the current locale using the given
+ quotation \a style.
+*/
+QString QLocale::quoteString(const QString &str, QuotationStyle style) const
+{
+ return quoteString(QStringRef(&str), style);
+}
+
+/*!
+ \since 4.8
+
+ \overload
+*/
+QString QLocale::quoteString(const QStringRef &str, QuotationStyle style) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res;
+ if (style == QLocale::AlternateQuotation)
+ res = systemLocale()->query(QSystemLocale::StringToAlternateQuotation, QVariant::fromValue(str));
+ if (res.isNull() || style == QLocale::StandardQuotation)
+ res = systemLocale()->query(QSystemLocale::StringToStandardQuotation, QVariant::fromValue(str));
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+
+ if (style == QLocale::StandardQuotation)
+ return QChar(d->m_data->m_quotation_start) % str % QChar(d->m_data->m_quotation_end);
+ else
+ return QChar(d->m_data->m_alternate_quotation_start) % str % QChar(d->m_data->m_alternate_quotation_end);
+}
+
+/*!
+ \since 4.8
+
+ Returns a string that represents a join of a given \a list of strings with
+ a separator defined by the locale.
+*/
+QString QLocale::createSeparatedList(const QStringList &list) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res;
+ res = systemLocale()->query(QSystemLocale::ListToSeparatedString, QVariant::fromValue(list));
+
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+
+ const int size = list.size();
+ if (size == 1) {
+ return list.at(0);
+ } else if (size == 2) {
+ QString format = getLocaleData(list_pattern_part_data + d->m_data->m_list_pattern_part_two_idx, d->m_data->m_list_pattern_part_two_size);
+ return format.arg(list.at(0), list.at(1));
+ } else if (size > 2) {
+ QString formatStart = getLocaleData(list_pattern_part_data + d->m_data->m_list_pattern_part_start_idx, d->m_data->m_list_pattern_part_start_size);
+ QString formatMid = getLocaleData(list_pattern_part_data + d->m_data->m_list_pattern_part_mid_idx, d->m_data->m_list_pattern_part_mid_size);
+ QString formatEnd = getLocaleData(list_pattern_part_data + d->m_data->m_list_pattern_part_end_idx, d->m_data->m_list_pattern_part_end_size);
+ QString result = formatStart.arg(list.at(0), list.at(1));
+ for (int i = 2; i < size - 1; ++i)
+ result = formatMid.arg(result, list.at(i));
+ result = formatEnd.arg(result, list.at(size - 1));
+ return result;
+ }
+
+ return QString();
+}
+
+/*!
+ \nonreentrant
+
+ Sets the global default locale to \a locale. These
+ values are used when a QLocale object is constructed with
+ no arguments. If this function is not called, the system's
+ locale is used.
+
+ \warning In a multithreaded application, the default locale
+ should be set at application startup, before any non-GUI threads
+ are created.
+
+ \sa system(), c()
+*/
+
+void QLocale::setDefault(const QLocale &locale)
+{
+ default_data = locale.d->m_data;
+ default_number_options = locale.numberOptions();
+
+ if (defaultLocalePrivate.exists()) {
+ // update the cached private
+ *defaultLocalePrivate = locale.d;
+ }
+}
+
+/*!
+ Returns the language of this locale.
+
+ \sa script(), country(), languageToString(), bcp47Name()
+*/
+QLocale::Language QLocale::language() const
+{
+ return Language(d->languageId());
+}
+
+/*!
+ \since 4.8
+
+ Returns the script of this locale.
+
+ \sa language(), country(), languageToString(), scriptToString(), bcp47Name()
+*/
+QLocale::Script QLocale::script() const
+{
+ return Script(d->m_data->m_script_id);
+}
+
+/*!
+ Returns the country of this locale.
+
+ \sa language(), script(), countryToString(), bcp47Name()
+*/
+QLocale::Country QLocale::country() const
+{
+ return Country(d->countryId());
+}
+
+/*!
+ Returns the language and country of this locale as a
+ string of the form "language_country", where
+ language is a lowercase, two-letter ISO 639 language code,
+ and country is an uppercase, two- or three-letter ISO 3166 country code.
+
+ Note that even if QLocale object was constructed with an explicit script,
+ name() will not contain it for compatibility reasons. Use bcp47Name() instead
+ if you need a full locale name.
+
+ \sa QLocale(), language(), script(), country(), bcp47Name()
+*/
+
+QString QLocale::name() const
+{
+ Language l = language();
+ if (l == C)
+ return d->languageCode();
+
+ Country c = country();
+ if (c == AnyCountry)
+ return d->languageCode();
+
+ return d->languageCode() + QLatin1Char('_') + d->countryCode();
+}
+
+static qlonglong toIntegral_helper(const QLocaleData *d, QStringView str, bool *ok,
+ QLocale::NumberOptions mode, qlonglong)
+{
+ return d->stringToLongLong(str, 10, ok, mode);
+}
+
+static qulonglong toIntegral_helper(const QLocaleData *d, QStringView str, bool *ok,
+ QLocale::NumberOptions mode, qulonglong)
+{
+ return d->stringToUnsLongLong(str, 10, ok, mode);
+}
+
+template <typename T> static inline
+T toIntegral_helper(const QLocalePrivate *d, QStringView str, bool *ok)
+{
+ using Int64 = typename std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type;
+
+ // we select the right overload by the last, unused parameter
+ Int64 val = toIntegral_helper(d->m_data, str, ok, d->m_numberOptions, Int64());
+ if (T(val) != val) {
+ if (ok != nullptr)
+ *ok = false;
+ val = 0;
+ }
+ return T(val);
+}
+
+
+/*!
+ \since 4.8
+
+ Returns the dash-separated language, script and country (and possibly other BCP47 fields)
+ of this locale as a string.
+
+ Unlike the uiLanguages() the returned value of the bcp47Name() represents
+ the locale name of the QLocale data but not the language the user-interface
+ should be in.
+
+ This function tries to conform the locale name to BCP47.
+
+ \sa language(), country(), script(), uiLanguages()
+*/
+QString QLocale::bcp47Name() const
+{
+ return QString::fromLatin1(d->bcp47Name());
+}
+
+/*!
+ Returns a QString containing the name of \a language.
+
+ \sa countryToString(), scriptToString(), bcp47Name()
+*/
+
+QString QLocale::languageToString(Language language)
+{
+ if (uint(language) > uint(QLocale::LastLanguage))
+ return QLatin1String("Unknown");
+ return QLatin1String(language_name_list + language_name_index[language]);
+}
+
+/*!
+ Returns a QString containing the name of \a country.
+
+ \sa languageToString(), scriptToString(), country(), bcp47Name()
+*/
+
+QString QLocale::countryToString(Country country)
+{
+ if (uint(country) > uint(QLocale::LastCountry))
+ return QLatin1String("Unknown");
+ return QLatin1String(country_name_list + country_name_index[country]);
+}
+
+/*!
+ \since 4.8
+
+ Returns a QString containing the name of \a script.
+
+ \sa languageToString(), countryToString(), script(), bcp47Name()
+*/
+QString QLocale::scriptToString(QLocale::Script script)
+{
+ if (uint(script) > uint(QLocale::LastScript))
+ return QLatin1String("Unknown");
+ return QLatin1String(script_name_list + script_name_index[script]);
+}
+
+#if QT_STRINGVIEW_LEVEL < 2
+/*!
+ Returns the short int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toUShort(), toString()
+*/
+
+short QLocale::toShort(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<short>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned short int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toShort(), toString()
+*/
+
+ushort QLocale::toUShort(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<ushort>(d, s, ok);
+}
+
+/*!
+ Returns the int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toUInt(), toString()
+*/
+
+int QLocale::toInt(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<int>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toString()
+*/
+
+uint QLocale::toUInt(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<uint>(d, s, ok);
+}
+
+/*!
+ Returns the long int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULong(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+
+long QLocale::toLong(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<long>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned long int represented by the localized
+ string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLong(), toInt(), toDouble(), toString()
+
+ \since 5.13
+*/
+
+ulong QLocale::toULong(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<ulong>(d, s, ok);
+}
+
+/*!
+ Returns the long long int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULongLong(), toDouble(), toString()
+*/
+
+
+qlonglong QLocale::toLongLong(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<qlonglong>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned long long int represented by the localized
+ string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLongLong(), toInt(), toDouble(), toString()
+*/
+
+qulonglong QLocale::toULongLong(const QString &s, bool *ok) const
+{
+ return toIntegral_helper<qulonglong>(d, s, ok);
+}
+
+/*!
+ Returns the float represented by the localized string \a s.
+
+ Returns an infinity if the conversion overflows or 0.0 if the
+ conversion fails for any other reason (e.g. underflow).
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function does not fall back to the 'C' locale if the string
+ cannot be interpreted in this locale.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toDouble(), toInt(), toString()
+*/
+
+float QLocale::toFloat(const QString &s, bool *ok) const
+{
+ return QLocaleData::convertDoubleToFloat(toDouble(s, ok), ok);
+}
+
+/*!
+ Returns the double represented by the localized string \a s.
+
+ Returns an infinity if the conversion overflows or 0.0 if the
+ conversion fails for any other reason (e.g. underflow).
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function does not fall back to the 'C' locale if the string
+ cannot be interpreted in this locale.
+
+ \snippet code/src_corelib_tools_qlocale.cpp 3
+
+ Notice that the last conversion returns 1234.0, because '.' is the
+ thousands group separator in the German locale.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toFloat(), toInt(), toString()
+*/
+
+double QLocale::toDouble(const QString &s, bool *ok) const
+{
+ return d->m_data->stringToDouble(s, ok, d->m_numberOptions);
+}
+
+/*!
+ Returns the short int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toUShort(), toString()
+
+ \since 5.1
+*/
+
+short QLocale::toShort(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<short>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned short int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toShort(), toString()
+
+ \since 5.1
+*/
+
+ushort QLocale::toUShort(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<ushort>(d, s, ok);
+}
+
+/*!
+ Returns the int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toUInt(), toString()
+
+ \since 5.1
+*/
+
+int QLocale::toInt(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<int>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toString()
+
+ \since 5.1
+*/
+
+uint QLocale::toUInt(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<uint>(d, s, ok);
+}
+
+/*!
+ Returns the long int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULong(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+
+long QLocale::toLong(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<long>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned long int represented by the localized
+ string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLong(), toInt(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+ulong QLocale::toULong(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<ulong>(d, s, ok);
+}
+
+/*!
+ Returns the long long int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULongLong(), toDouble(), toString()
+
+ \since 5.1
+*/
+
+
+qlonglong QLocale::toLongLong(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<qlonglong>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned long long int represented by the localized
+ string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLongLong(), toInt(), toDouble(), toString()
+
+ \since 5.1
+*/
+
+qulonglong QLocale::toULongLong(const QStringRef &s, bool *ok) const
+{
+ return toIntegral_helper<qulonglong>(d, s, ok);
+}
+
+/*!
+ Returns the float represented by the localized string \a s.
+
+ Returns an infinity if the conversion overflows or 0.0 if the
+ conversion fails for any other reason (e.g. underflow).
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function does not fall back to the 'C' locale if the string
+ cannot be interpreted in this locale.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toDouble(), toInt(), toString()
+
+ \since 5.1
+*/
+
+float QLocale::toFloat(const QStringRef &s, bool *ok) const
+{
+ return QLocaleData::convertDoubleToFloat(toDouble(s, ok), ok);
+}
+
+/*!
+ Returns the double represented by the localized string \a s.
+
+ Returns an infinity if the conversion overflows or 0.0 if the
+ conversion fails for any other reason (e.g. underflow).
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function does not fall back to the 'C' locale if the string
+ cannot be interpreted in this locale.
+
+ \snippet code/src_corelib_tools_qlocale.cpp 3
+
+ Notice that the last conversion returns 1234.0, because '.' is the
+ thousands group separator in the German locale.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toFloat(), toInt(), toString()
+
+ \since 5.1
+*/
+
+double QLocale::toDouble(const QStringRef &s, bool *ok) const
+{
+ return d->m_data->stringToDouble(s, ok, d->m_numberOptions);
+}
+#endif // QT_STRINGVIEW_LEVEL < 2
+
+/*!
+ Returns the short int represented by the localized string \a s.
+
+ If the conversion fails, the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toUShort(), toString()
+
+ \since 5.10
+*/
+
+short QLocale::toShort(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<short>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned short int represented by the localized string \a s.
+
+ If the conversion fails, the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toShort(), toString()
+
+ \since 5.10
+*/
+
+ushort QLocale::toUShort(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<ushort>(d, s, ok);
+}
+
+/*!
+ Returns the int represented by the localized string \a s.
+
+ If the conversion fails, the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toUInt(), toString()
+
+ \since 5.10
+*/
+
+int QLocale::toInt(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<int>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned int represented by the localized string \a s.
+
+ If the conversion fails, the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toString()
+
+ \since 5.10
+*/
+
+uint QLocale::toUInt(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<uint>(d, s, ok);
+}
+
+/*!
+ Returns the long int represented by the localized string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULong(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+
+long QLocale::toLong(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<long>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned long int represented by the localized
+ string \a s.
+
+ If the conversion fails the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLong(), toInt(), toDouble(), toString()
+
+ \since 5.13
+ */
+
+ulong QLocale::toULong(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<ulong>(d, s, ok);
+}
+
+/*!
+ Returns the long long int represented by the localized string \a s.
+
+ If the conversion fails, the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toInt(), toULongLong(), toDouble(), toString()
+
+ \since 5.10
+*/
+
+
+qlonglong QLocale::toLongLong(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<qlonglong>(d, s, ok);
+}
+
+/*!
+ Returns the unsigned long long int represented by the localized
+ string \a s.
+
+ If the conversion fails, the function returns 0.
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toLongLong(), toInt(), toDouble(), toString()
+
+ \since 5.10
+*/
+
+qulonglong QLocale::toULongLong(QStringView s, bool *ok) const
+{
+ return toIntegral_helper<qulonglong>(d, s, ok);
+}
+
+/*!
+ Returns the float represented by the localized string \a s.
+
+ Returns an infinity if the conversion overflows or 0.0 if the
+ conversion fails for any other reason (e.g. underflow).
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toDouble(), toInt(), toString()
+
+ \since 5.10
+*/
+
+float QLocale::toFloat(QStringView s, bool *ok) const
+{
+ return QLocaleData::convertDoubleToFloat(toDouble(s, ok), ok);
+}
+
+/*!
+ Returns the double represented by the localized string \a s.
+
+ Returns an infinity if the conversion overflows or 0.0 if the
+ conversion fails for any other reason (e.g. underflow).
+
+ If \a ok is not \nullptr, failure is reported by setting *\a{ok}
+ to \c false, and success by setting *\a{ok} to \c true.
+
+ Unlike QString::toDouble(), this function does not fall back to
+ the "C" locale if the string cannot be interpreted in this
+ locale.
+
+ \snippet code/src_corelib_tools_qlocale.cpp 3-qstringview
+
+ Notice that the last conversion returns 1234.0, because '.' is the
+ thousands group separator in the German locale.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toFloat(), toInt(), toString()
+
+ \since 5.10
+*/
+
+double QLocale::toDouble(QStringView s, bool *ok) const
+{
+ return d->m_data->stringToDouble(s, ok, d->m_numberOptions);
+}
+
+/*!
+ Returns a localized string representation of \a i.
+
+ \sa toLongLong()
+*/
+
+QString QLocale::toString(qlonglong i) const
+{
+ int flags = d->m_numberOptions & OmitGroupSeparator
+ ? 0
+ : QLocaleData::ThousandsGroup;
+
+ return d->m_data->longLongToString(i, -1, 10, -1, flags);
+}
+
+/*!
+ \overload
+
+ \sa toULongLong()
+*/
+
+QString QLocale::toString(qulonglong i) const
+{
+ int flags = d->m_numberOptions & OmitGroupSeparator
+ ? 0
+ : QLocaleData::ThousandsGroup;
+
+ return d->m_data->unsLongLongToString(i, -1, 10, -1, flags);
+}
+
+#if QT_STRINGVIEW_LEVEL < 2
+/*!
+ Returns a localized string representation of the given \a date in the
+ specified \a format.
+ If \a format is an empty string, an empty string is returned.
+
+ \sa QDate::toString()
+*/
+
+QString QLocale::toString(const QDate &date, const QString &format) const
+{
+ return d->dateTimeToString(format, QDateTime(), date, QTime(), this);
+}
+#endif
+
+/*!
+ \since 5.10
+
+ Returns a localized string representation of the given \a date in the
+ specified \a format.
+ If \a format is an empty string, an empty string is returned.
+
+ \sa QDate::toString()
+*/
+QString QLocale::toString(const QDate &date, QStringView format) const
+{
+ return d->dateTimeToString(format, QDateTime(), date, QTime(), this);
+}
+
+/*!
+ Returns a localized string representation of the given \a date according
+ to the specified \a format.
+*/
+
+QString QLocale::toString(const QDate &date, FormatType format) const
+{
+ if (!date.isValid())
+ return QString();
+
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(format == LongFormat
+ ? QSystemLocale::DateToStringLong : QSystemLocale::DateToStringShort,
+ date);
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+
+ QString format_str = dateFormat(format);
+ return toString(date, format_str);
+}
+
+static bool timeFormatContainsAP(QStringView format)
+{
+ int i = 0;
+ while (i < format.size()) {
+ if (format.at(i).unicode() == '\'') {
+ qt_readEscapedFormatString(format, &i);
+ continue;
+ }
+
+ if (format.at(i).toLower().unicode() == 'a')
+ return true;
+
+ ++i;
+ }
+ return false;
+}
+
+#if QT_STRINGVIEW_LEVEL < 2
+/*!
+ Returns a localized string representation of the given \a time according
+ to the specified \a format.
+ If \a format is an empty string, an empty string is returned.
+
+ \sa QTime::toString()
+*/
+QString QLocale::toString(const QTime &time, const QString &format) const
+{
+ return d->dateTimeToString(format, QDateTime(), QDate(), time, this);
+}
+#endif
+
+/*!
+ \since 5.10
+
+ Returns a localized string representation of the given \a time according
+ to the specified \a format.
+ If \a format is an empty string, an empty string is returned.
+
+ \sa QTime::toString()
+*/
+QString QLocale::toString(const QTime &time, QStringView format) const
+{
+ return d->dateTimeToString(format, QDateTime(), QDate(), time, this);
+}
+
+#if QT_STRINGVIEW_LEVEL < 2
+/*!
+ \since 4.4
+
+ Returns a localized string representation of the given \a dateTime according
+ to the specified \a format.
+ If \a format is an empty string, an empty string is returned.
+
+ \sa QDateTime::toString(), QDate::toString(), QTime::toString()
+*/
+
+QString QLocale::toString(const QDateTime &dateTime, const QString &format) const
+{
+ return d->dateTimeToString(format, dateTime, QDate(), QTime(), this);
+}
+#endif
+
+/*!
+ \since 5.10
+
+ Returns a localized string representation of the given \a dateTime according
+ to the specified \a format.
+ If \a format is an empty string, an empty string is returned.
+
+ \sa QDateTime::toString(), QDate::toString(), QTime::toString()
+*/
+QString QLocale::toString(const QDateTime &dateTime, QStringView format) const
+{
+ return d->dateTimeToString(format, dateTime, QDate(), QTime(), this);
+}
+
+/*!
+ \since 4.4
+
+ Returns a localized string representation of the given \a dateTime according
+ to the specified \a format.
+*/
+
+QString QLocale::toString(const QDateTime &dateTime, FormatType format) const
+{
+ if (!dateTime.isValid())
+ return QString();
+
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(format == LongFormat
+ ? QSystemLocale::DateTimeToStringLong
+ : QSystemLocale::DateTimeToStringShort,
+ dateTime);
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+
+ const QString format_str = dateTimeFormat(format);
+ return toString(dateTime, format_str);
+}
+
+
+/*!
+ Returns a localized string representation of the given \a time in the
+ specified \a format.
+*/
+
+QString QLocale::toString(const QTime &time, FormatType format) const
+{
+ if (!time.isValid())
+ return QString();
+
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(format == LongFormat
+ ? QSystemLocale::TimeToStringLong : QSystemLocale::TimeToStringShort,
+ time);
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+
+ QString format_str = timeFormat(format);
+ return toString(time, format_str);
+}
+
+/*!
+ \since 4.1
+
+ Returns the date format used for the current locale.
+
+ If \a format is LongFormat the format will be a long version.
+ Otherwise it uses a shorter version.
+
+ \sa QDate::toString(), QDate::fromString()
+*/
+
+QString QLocale::dateFormat(FormatType format) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(format == LongFormat
+ ? QSystemLocale::DateFormatLong : QSystemLocale::DateFormatShort,
+ QVariant());
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+
+ quint32 idx, size;
+ switch (format) {
+ case LongFormat:
+ idx = d->m_data->m_long_date_format_idx;
+ size = d->m_data->m_long_date_format_size;
+ break;
+ default:
+ idx = d->m_data->m_short_date_format_idx;
+ size = d->m_data->m_short_date_format_size;
+ break;
+ }
+ return getLocaleData(date_format_data + idx, size);
+}
+
+/*!
+ \since 4.1
+
+ Returns the time format used for the current locale.
+
+ If \a format is LongFormat the format will be a long version.
+ Otherwise it uses a shorter version.
+
+ \sa QTime::toString(), QTime::fromString()
+*/
+
+QString QLocale::timeFormat(FormatType format) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(format == LongFormat
+ ? QSystemLocale::TimeFormatLong : QSystemLocale::TimeFormatShort,
+ QVariant());
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+
+ quint32 idx, size;
+ switch (format) {
+ case LongFormat:
+ idx = d->m_data->m_long_time_format_idx;
+ size = d->m_data->m_long_time_format_size;
+ break;
+ default:
+ idx = d->m_data->m_short_time_format_idx;
+ size = d->m_data->m_short_time_format_size;
+ break;
+ }
+ return getLocaleData(time_format_data + idx, size);
+}
+
+/*!
+ \since 4.4
+
+ Returns the date time format used for the current locale.
+
+ If \a format is ShortFormat the format will be a short version.
+ Otherwise it uses a longer version.
+
+ \sa QDateTime::toString(), QDateTime::fromString()
+*/
+
+QString QLocale::dateTimeFormat(FormatType format) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(format == LongFormat
+ ? QSystemLocale::DateTimeFormatLong
+ : QSystemLocale::DateTimeFormatShort,
+ QVariant());
+ if (!res.isNull()) {
+ return res.toString();
+ }
+ }
+#endif
+ return dateFormat(format) + QLatin1Char(' ') + timeFormat(format);
+}
+
+/*!
+ \since 4.4
+
+ Parses the time string given in \a string and returns the
+ time. The format of the time string is chosen according to the
+ \a format parameter (see timeFormat()).
+
+ If the time could not be parsed, returns an invalid time.
+
+ \sa timeFormat(), toDate(), toDateTime(), QTime::fromString()
+*/
+#if QT_CONFIG(datestring)
+QTime QLocale::toTime(const QString &string, FormatType format) const
+{
+ return toTime(string, timeFormat(format));
+}
+#endif
+
+/*!
+ \since 4.4
+
+ Parses the date string given in \a string and returns the
+ date. The format of the date string is chosen according to the
+ \a format parameter (see dateFormat()).
+
+ If the date could not be parsed, returns an invalid date.
+
+ \sa dateFormat(), toTime(), toDateTime(), QDate::fromString()
+*/
+#if QT_CONFIG(datestring)
+QDate QLocale::toDate(const QString &string, FormatType format) const
+{
+ return toDate(string, dateFormat(format));
+}
+#endif
+
+/*!
+ \since 4.4
+
+ Parses the date/time string given in \a string and returns the
+ time. The format of the date/time string is chosen according to the
+ \a format parameter (see dateTimeFormat()).
+
+ If the string could not be parsed, returns an invalid QDateTime.
+
+ \sa dateTimeFormat(), toTime(), toDate(), QDateTime::fromString()
+*/
+
+#if QT_CONFIG(datestring)
+QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
+{
+ return toDateTime(string, dateTimeFormat(format));
+}
+#endif
+
+/*!
+ \since 4.4
+
+ Parses the time string given in \a string and returns the
+ time. See QTime::fromString() for information on what is a valid
+ format string.
+
+ If the time could not be parsed, returns an invalid time.
+
+ \sa timeFormat(), toDate(), toDateTime(), QTime::fromString()
+*/
+#if QT_CONFIG(datestring)
+QTime QLocale::toTime(const QString &string, const QString &format) const
+{
+ QTime time;
+#if QT_CONFIG(datetimeparser)
+ QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString);
+ dt.setDefaultLocale(*this);
+ if (dt.parseFormat(format))
+ dt.fromString(string, 0, &time);
+#else
+ Q_UNUSED(string);
+ Q_UNUSED(format);
+#endif
+ return time;
+}
+#endif
+
+/*!
+ \since 4.4
+
+ Parses the date string given in \a string and returns the
+ date. See QDate::fromString() for information on the expressions
+ that can be used with this function.
+
+ This function searches month names and the names of the days of
+ the week in the current locale.
+
+ If the date could not be parsed, returns an invalid date.
+
+ \sa dateFormat(), toTime(), toDateTime(), QDate::fromString()
+*/
+#if QT_CONFIG(datestring)
+QDate QLocale::toDate(const QString &string, const QString &format) const
+{
+ QDate date;
+#if QT_CONFIG(datetimeparser)
+ QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString);
+ dt.setDefaultLocale(*this);
+ if (dt.parseFormat(format))
+ dt.fromString(string, &date, 0);
+#else
+ Q_UNUSED(string);
+ Q_UNUSED(format);
+#endif
+ return date;
+}
+#endif
+
+/*!
+ \since 4.4
+
+ Parses the date/time string given in \a string and returns the
+ time. See QDateTime::fromString() for information on the expressions
+ that can be used with this function.
+
+ \note The month and day names used must be given in the user's local
+ language.
+
+ If the string could not be parsed, returns an invalid QDateTime.
+
+ \sa dateTimeFormat(), toTime(), toDate(), QDateTime::fromString()
+*/
+#if QT_CONFIG(datestring)
+QDateTime QLocale::toDateTime(const QString &string, const QString &format) const
+{
+#if QT_CONFIG(datetimeparser)
+ QTime time;
+ QDate date;
+
+ QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString);
+ dt.setDefaultLocale(*this);
+ if (dt.parseFormat(format) && dt.fromString(string, &date, &time))
+ return QDateTime(date, time);
+#else
+ Q_UNUSED(string);
+ Q_UNUSED(format);
+#endif
+ return QDateTime(QDate(), QTime(-1, -1, -1));
+}
+#endif
+
+
+/*!
+ \since 4.1
+
+ Returns the decimal point character of this locale.
+*/
+QChar QLocale::decimalPoint() const
+{
+ return d->decimal();
+}
+
+/*!
+ \since 4.1
+
+ Returns the group separator character of this locale.
+*/
+QChar QLocale::groupSeparator() const
+{
+ return d->group();
+}
+
+/*!
+ \since 4.1
+
+ Returns the percent character of this locale.
+*/
+QChar QLocale::percent() const
+{
+ return d->percent();
+}
+
+/*!
+ \since 4.1
+
+ Returns the zero digit character of this locale.
+*/
+QChar QLocale::zeroDigit() const
+{
+ return d->zero();
+}
+
+/*!
+ \since 4.1
+
+ Returns the negative sign character of this locale.
+*/
+QChar QLocale::negativeSign() const
+{
+ return d->minus();
+}
+
+/*!
+ \since 4.5
+
+ Returns the positive sign character of this locale.
+*/
+QChar QLocale::positiveSign() const
+{
+ return d->plus();
+}
+
+/*!
+ \since 4.1
+
+ Returns the exponential character of this locale.
+*/
+QChar QLocale::exponential() const
+{
+ return d->exponential();
+}
+
+static bool qIsUpper(char c)
+{
+ return c >= 'A' && c <= 'Z';
+}
+
+static char qToLower(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A' + 'a';
+ else
+ return c;
+}
+
+/*!
+ \overload
+
+ \a f and \a prec have the same meaning as in QString::number(double, char, int).
+
+ \sa toDouble()
+*/
+
+QString QLocale::toString(double i, char f, int prec) const
+{
+ QLocaleData::DoubleForm form = QLocaleData::DFDecimal;
+ uint flags = 0;
+
+ if (qIsUpper(f))
+ flags = QLocaleData::CapitalEorX;
+ f = qToLower(f);
+
+ switch (f) {
+ case 'f':
+ form = QLocaleData::DFDecimal;
+ break;
+ case 'e':
+ form = QLocaleData::DFExponent;
+ break;
+ case 'g':
+ form = QLocaleData::DFSignificantDigits;
+ break;
+ default:
+ break;
+ }
+
+ if (!(d->m_numberOptions & OmitGroupSeparator))
+ flags |= QLocaleData::ThousandsGroup;
+ if (!(d->m_numberOptions & OmitLeadingZeroInExponent))
+ flags |= QLocaleData::ZeroPadExponent;
+ if (d->m_numberOptions & IncludeTrailingZeroesAfterDot)
+ flags |= QLocaleData::AddTrailingZeroes;
+ return d->m_data->doubleToString(i, prec, form, -1, flags);
+}
+
+/*!
+ \fn QLocale QLocale::c()
+
+ Returns a QLocale object initialized to the "C" locale.
+
+ This locale is based on en_US but with various quirks of its own, such as
+ simplified number formatting and its own date formatting. It implements the
+ POSIX standards that describe the behavior of standard library functions of
+ the "C" programming language.
+
+ Among other things, this means its collation order is based on the ASCII
+ values of letters, so that (for case-sensitive sorting) all upper-case
+ letters sort before any lower-case one (rather than each letter's upper- and
+ lower-case forms sorting adjacent to one another, before the next letter's
+ two forms).
+
+ \sa system()
+*/
+
+/*!
+ Returns a QLocale object initialized to the system locale.
+
+ On Windows and Mac, this locale will use the decimal/grouping characters and date/time
+ formats specified in the system configuration panel.
+
+ \sa c()
+*/
+
+QLocale QLocale::system()
+{
+ QT_PREPEND_NAMESPACE(systemData)(); // trigger updating of the system data if necessary
+ if (systemLocalePrivate.isDestroyed())
+ return QLocale(QLocale::C);
+ return QLocale(*systemLocalePrivate->data());
+}
+
+
+/*!
+ \since 4.8
+
+ Returns a list of valid locale objects that match the given \a language, \a
+ script and \a country.
+
+ Getting a list of all locales:
+ QList<QLocale> allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::AnyCountry);
+
+ Getting a list of locales suitable for Russia:
+ QList<QLocale> locales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, QLocale::Russia);
+*/
+QList<QLocale> QLocale::matchingLocales(QLocale::Language language,
+ QLocale::Script script,
+ QLocale::Country country)
+{
+ if (uint(language) > QLocale::LastLanguage || uint(script) > QLocale::LastScript ||
+ uint(country) > QLocale::LastCountry)
+ return QList<QLocale>();
+
+ if (language == QLocale::C)
+ return QList<QLocale>() << QLocale(QLocale::C);
+
+ QList<QLocale> result;
+ if (language == QLocale::AnyLanguage && script == QLocale::AnyScript && country == QLocale::AnyCountry)
+ result.reserve(locale_data_size);
+ const QLocaleData *data = locale_data + locale_index[language];
+ while ( (data != locale_data + locale_data_size)
+ && (language == QLocale::AnyLanguage || data->m_language_id == uint(language))) {
+ if ((script == QLocale::AnyScript || data->m_script_id == uint(script))
+ && (country == QLocale::AnyCountry || data->m_country_id == uint(country))) {
+ result.append(QLocale(*(data->m_language_id == C ? c_private()
+ : QLocalePrivate::create(data))));
+ }
+ ++data;
+ }
+ return result;
+}
+
+/*!
+ \obsolete
+ \since 4.3
+
+ Returns the list of countries that have entries for \a language in Qt's locale
+ database. If the result is an empty list, then \a language is not represented in
+ Qt's locale database.
+
+ \sa matchingLocales()
+*/
+QList<QLocale::Country> QLocale::countriesForLanguage(Language language)
+{
+ QList<Country> result;
+ if (language == C) {
+ result << AnyCountry;
+ return result;
+ }
+
+ unsigned language_id = language;
+ const QLocaleData *data = locale_data + locale_index[language_id];
+ while (data->m_language_id == language_id) {
+ const QLocale::Country country = static_cast<Country>(data->m_country_id);
+ if (!result.contains(country))
+ result.append(country);
+ ++data;
+ }
+
+ return result;
+}
+
+/*!
+ \since 4.2
+
+ Returns the localized name of \a month, in the format specified
+ by \a type.
+
+ \sa dayName(), standaloneMonthName()
+*/
+QString QLocale::monthName(int month, FormatType type) const
+{
+ if (month < 1 || month > 12)
+ return QString();
+
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(type == LongFormat
+ ? QSystemLocale::MonthNameLong : QSystemLocale::MonthNameShort,
+ month);
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+
+ quint32 idx, size;
+ switch (type) {
+ case QLocale::LongFormat:
+ idx = d->m_data->m_long_month_names_idx;
+ size = d->m_data->m_long_month_names_size;
+ break;
+ case QLocale::ShortFormat:
+ idx = d->m_data->m_short_month_names_idx;
+ size = d->m_data->m_short_month_names_size;
+ break;
+ case QLocale::NarrowFormat:
+ idx = d->m_data->m_narrow_month_names_idx;
+ size = d->m_data->m_narrow_month_names_size;
+ break;
+ default:
+ return QString();
+ }
+ return getLocaleListData(months_data + idx, size, month - 1);
+}
+
+/*!
+ \since 4.5
+
+ Returns the localized name of \a month that is used as a
+ standalone text, in the format specified by \a type.
+
+ If the locale information doesn't specify the standalone month
+ name then return value is the same as in monthName().
+
+ \sa monthName(), standaloneDayName()
+*/
+QString QLocale::standaloneMonthName(int month, FormatType type) const
+{
+ if (month < 1 || month > 12)
+ return QString();
+
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(type == LongFormat
+ ? QSystemLocale::StandaloneMonthNameLong : QSystemLocale::StandaloneMonthNameShort,
+ month);
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+
+ quint32 idx, size;
+ switch (type) {
+ case QLocale::LongFormat:
+ idx = d->m_data->m_standalone_long_month_names_idx;
+ size = d->m_data->m_standalone_long_month_names_size;
+ break;
+ case QLocale::ShortFormat:
+ idx = d->m_data->m_standalone_short_month_names_idx;
+ size = d->m_data->m_standalone_short_month_names_size;
+ break;
+ case QLocale::NarrowFormat:
+ idx = d->m_data->m_standalone_narrow_month_names_idx;
+ size = d->m_data->m_standalone_narrow_month_names_size;
+ break;
+ default:
+ return QString();
+ }
+ QString name = getLocaleListData(months_data + idx, size, month - 1);
+ if (name.isEmpty())
+ return monthName(month, type);
+ return name;
+}
+
+/*!
+ \since 4.2
+
+ Returns the localized name of the \a day (where 1 represents
+ Monday, 2 represents Tuesday and so on), in the format specified
+ by \a type.
+
+ \sa monthName(), standaloneDayName()
+*/
+QString QLocale::dayName(int day, FormatType type) const
+{
+ if (day < 1 || day > 7)
+ return QString();
+
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(type == LongFormat
+ ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
+ day);
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ if (day == 7)
+ day = 0;
+
+ quint32 idx, size;
+ switch (type) {
+ case QLocale::LongFormat:
+ idx = d->m_data->m_long_day_names_idx;
+ size = d->m_data->m_long_day_names_size;
+ break;
+ case QLocale::ShortFormat:
+ idx = d->m_data->m_short_day_names_idx;
+ size = d->m_data->m_short_day_names_size;
+ break;
+ case QLocale::NarrowFormat:
+ idx = d->m_data->m_narrow_day_names_idx;
+ size = d->m_data->m_narrow_day_names_size;
+ break;
+ default:
+ return QString();
+ }
+ return getLocaleListData(days_data + idx, size, day);
+}
+
+/*!
+ \since 4.5
+
+ Returns the localized name of the \a day (where 1 represents
+ Monday, 2 represents Tuesday and so on) that is used as a
+ standalone text, in the format specified by \a type.
+
+ If the locale information does not specify the standalone day
+ name then return value is the same as in dayName().
+
+ \sa dayName(), standaloneMonthName()
+*/
+QString QLocale::standaloneDayName(int day, FormatType type) const
+{
+ if (day < 1 || day > 7)
+ return QString();
+
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(type == LongFormat
+ ? QSystemLocale::DayNameLong : QSystemLocale::DayNameShort,
+ day);
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ if (day == 7)
+ day = 0;
+
+ quint32 idx, size;
+ switch (type) {
+ case QLocale::LongFormat:
+ idx = d->m_data->m_standalone_long_day_names_idx;
+ size = d->m_data->m_standalone_long_day_names_size;
+ break;
+ case QLocale::ShortFormat:
+ idx = d->m_data->m_standalone_short_day_names_idx;
+ size = d->m_data->m_standalone_short_day_names_size;
+ break;
+ case QLocale::NarrowFormat:
+ idx = d->m_data->m_standalone_narrow_day_names_idx;
+ size = d->m_data->m_standalone_narrow_day_names_size;
+ break;
+ default:
+ return QString();
+ }
+ QString name = getLocaleListData(days_data + idx, size, day);
+ if (name.isEmpty())
+ return dayName(day == 0 ? 7 : day, type);
+ return name;
+}
+
+/*!
+ \since 4.8
+
+ Returns the first day of the week according to the current locale.
+*/
+Qt::DayOfWeek QLocale::firstDayOfWeek() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(QSystemLocale::FirstDayOfWeek, QVariant());
+ if (!res.isNull())
+ return static_cast<Qt::DayOfWeek>(res.toUInt());
+ }
+#endif
+ return static_cast<Qt::DayOfWeek>(d->m_data->m_first_day_of_week);
+}
+
+QLocale::MeasurementSystem QLocalePrivate::measurementSystem() const
+{
+ for (int i = 0; i < ImperialMeasurementSystemsCount; ++i) {
+ if (ImperialMeasurementSystems[i].languageId == m_data->m_language_id
+ && ImperialMeasurementSystems[i].countryId == m_data->m_country_id) {
+ return ImperialMeasurementSystems[i].system;
+ }
+ }
+ return QLocale::MetricSystem;
+}
+
+/*!
+ \since 4.8
+
+ Returns a list of days that are considered weekdays according to the current locale.
+*/
+QList<Qt::DayOfWeek> QLocale::weekdays() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(QSystemLocale::Weekdays, QVariant());
+ if (!res.isNull())
+ return static_cast<QList<Qt::DayOfWeek> >(res.value<QList<Qt::DayOfWeek> >());
+ }
+#endif
+ QList<Qt::DayOfWeek> weekdays;
+ quint16 weekendStart = d->m_data->m_weekend_start;
+ quint16 weekendEnd = d->m_data->m_weekend_end;
+ for (int day = Qt::Monday; day <= Qt::Sunday; day++) {
+ if ((weekendEnd >= weekendStart && (day < weekendStart || day > weekendEnd)) ||
+ (weekendEnd < weekendStart && (day > weekendEnd && day < weekendStart)))
+ weekdays << static_cast<Qt::DayOfWeek>(day);
+ }
+ return weekdays;
+}
+
+/*!
+ \since 4.4
+
+ Returns the measurement system for the locale.
+*/
+QLocale::MeasurementSystem QLocale::measurementSystem() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(QSystemLocale::MeasurementSystem, QVariant());
+ if (!res.isNull())
+ return MeasurementSystem(res.toInt());
+ }
+#endif
+
+ return d->measurementSystem();
+}
+
+/*!
+ \since 4.7
+
+ Returns the text direction of the language.
+*/
+Qt::LayoutDirection QLocale::textDirection() const
+{
+ switch (script()) {
+ case QLocale::AdlamScript:
+ case QLocale::ArabicScript:
+ case QLocale::AvestanScript:
+ case QLocale::CypriotScript:
+ case QLocale::HatranScript:
+ case QLocale::HebrewScript:
+ case QLocale::ImperialAramaicScript:
+ case QLocale::InscriptionalPahlaviScript:
+ case QLocale::InscriptionalParthianScript:
+ case QLocale::KharoshthiScript:
+ case QLocale::LydianScript:
+ case QLocale::MandaeanScript:
+ case QLocale::ManichaeanScript:
+ case QLocale::MendeKikakuiScript:
+ case QLocale::MeroiticCursiveScript:
+ case QLocale::MeroiticScript:
+ case QLocale::NabataeanScript:
+ case QLocale::NkoScript:
+ case QLocale::OldHungarianScript:
+ case QLocale::OldNorthArabianScript:
+ case QLocale::OldSouthArabianScript:
+ case QLocale::OrkhonScript:
+ case QLocale::PalmyreneScript:
+ case QLocale::PhoenicianScript:
+ case QLocale::PsalterPahlaviScript:
+ case QLocale::SamaritanScript:
+ case QLocale::SyriacScript:
+ case QLocale::ThaanaScript:
+ return Qt::RightToLeft;
+ default:
+ break;
+ }
+ return Qt::LeftToRight;
+}
+
+/*!
+ \since 4.8
+
+ Returns an uppercase copy of \a str.
+
+ If Qt Core is using the ICU libraries, they will be used to perform
+ the transformation according to the rules of the current locale.
+ Otherwise the conversion may be done in a platform-dependent manner,
+ with QString::toUpper() as a generic fallback.
+
+ \sa QString::toUpper()
+*/
+QString QLocale::toUpper(const QString &str) const
+{
+#if QT_CONFIG(icu)
+ bool ok = true;
+ QString result = QIcu::toUpper(d->bcp47Name('_'), str, &ok);
+ if (ok)
+ return result;
+ // else fall through and use Qt's toUpper
+#endif
+ return str.toUpper();
+}
+
+/*!
+ \since 4.8
+
+ Returns a lowercase copy of \a str.
+
+ If Qt Core is using the ICU libraries, they will be used to perform
+ the transformation according to the rules of the current locale.
+ Otherwise the conversion may be done in a platform-dependent manner,
+ with QString::toLower() as a generic fallback.
+
+ \sa QString::toLower()
+*/
+QString QLocale::toLower(const QString &str) const
+{
+#if QT_CONFIG(icu)
+ bool ok = true;
+ const QString result = QIcu::toLower(d->bcp47Name('_'), str, &ok);
+ if (ok)
+ return result;
+ // else fall through and use Qt's toUpper
+#endif
+ return str.toLower();
+}
+
+
+/*!
+ \since 4.5
+
+ Returns the localized name of the "AM" suffix for times specified using
+ the conventions of the 12-hour clock.
+
+ \sa pmText()
+*/
+QString QLocale::amText() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(QSystemLocale::AMText, QVariant());
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ return getLocaleData(am_data + d->m_data->m_am_idx, d->m_data->m_am_size);
+}
+
+/*!
+ \since 4.5
+
+ Returns the localized name of the "PM" suffix for times specified using
+ the conventions of the 12-hour clock.
+
+ \sa amText()
+*/
+QString QLocale::pmText() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(QSystemLocale::PMText, QVariant());
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ return getLocaleData(pm_data + d->m_data->m_pm_idx, d->m_data->m_pm_size);
+}
+
+
+QString QLocalePrivate::dateTimeToString(QStringView format, const QDateTime &datetime,
+ const QDate &dateOnly, const QTime &timeOnly,
+ const QLocale *q) const
+{
+ QDate date;
+ QTime time;
+ bool formatDate = false;
+ bool formatTime = false;
+ if (datetime.isValid()) {
+ date = datetime.date();
+ time = datetime.time();
+ formatDate = true;
+ formatTime = true;
+ } else if (dateOnly.isValid()) {
+ date = dateOnly;
+ formatDate = true;
+ } else if (timeOnly.isValid()) {
+ time = timeOnly;
+ formatTime = true;
+ } else {
+ return QString();
+ }
+
+ QString result;
+
+ int i = 0;
+ while (i < format.size()) {
+ if (format.at(i).unicode() == '\'') {
+ result.append(qt_readEscapedFormatString(format, &i));
+ continue;
+ }
+
+ const QChar c = format.at(i);
+ int repeat = qt_repeatCount(format.mid(i));
+ bool used = false;
+ if (formatDate) {
+ switch (c.unicode()) {
+ case 'y':
+ used = true;
+ if (repeat >= 4)
+ repeat = 4;
+ else if (repeat >= 2)
+ repeat = 2;
+
+ switch (repeat) {
+ case 4: {
+ const int yr = date.year();
+ const int len = (yr < 0) ? 5 : 4;
+ result.append(m_data->longLongToString(yr, -1, 10, len, QLocaleData::ZeroPadded));
+ break;
+ }
+ case 2:
+ result.append(m_data->longLongToString(date.year() % 100, -1, 10, 2,
+ QLocaleData::ZeroPadded));
+ break;
+ default:
+ repeat = 1;
+ result.append(c);
+ break;
+ }
+ break;
+
+ case 'M':
+ used = true;
+ repeat = qMin(repeat, 4);
+ switch (repeat) {
+ case 1:
+ result.append(m_data->longLongToString(date.month()));
+ break;
+ case 2:
+ result.append(m_data->longLongToString(date.month(), -1, 10, 2, QLocaleData::ZeroPadded));
+ break;
+ case 3:
+ result.append(q->monthName(date.month(), QLocale::ShortFormat));
+ break;
+ case 4:
+ result.append(q->monthName(date.month(), QLocale::LongFormat));
+ break;
+ }
+ break;
+
+ case 'd':
+ used = true;
+ repeat = qMin(repeat, 4);
+ switch (repeat) {
+ case 1:
+ result.append(m_data->longLongToString(date.day()));
+ break;
+ case 2:
+ result.append(m_data->longLongToString(date.day(), -1, 10, 2, QLocaleData::ZeroPadded));
+ break;
+ case 3:
+ result.append(q->dayName(date.dayOfWeek(), QLocale::ShortFormat));
+ break;
+ case 4:
+ result.append(q->dayName(date.dayOfWeek(), QLocale::LongFormat));
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (!used && formatTime) {
+ switch (c.unicode()) {
+ case 'h': {
+ used = true;
+ repeat = qMin(repeat, 2);
+ int hour = time.hour();
+ if (timeFormatContainsAP(format)) {
+ if (hour > 12)
+ hour -= 12;
+ else if (hour == 0)
+ hour = 12;
+ }
+
+ switch (repeat) {
+ case 1:
+ result.append(m_data->longLongToString(hour));
+ break;
+ case 2:
+ result.append(m_data->longLongToString(hour, -1, 10, 2, QLocaleData::ZeroPadded));
+ break;
+ }
+ break;
+ }
+ case 'H':
+ used = true;
+ repeat = qMin(repeat, 2);
+ switch (repeat) {
+ case 1:
+ result.append(m_data->longLongToString(time.hour()));
+ break;
+ case 2:
+ result.append(m_data->longLongToString(time.hour(), -1, 10, 2, QLocaleData::ZeroPadded));
+ break;
+ }
+ break;
+
+ case 'm':
+ used = true;
+ repeat = qMin(repeat, 2);
+ switch (repeat) {
+ case 1:
+ result.append(m_data->longLongToString(time.minute()));
+ break;
+ case 2:
+ result.append(m_data->longLongToString(time.minute(), -1, 10, 2, QLocaleData::ZeroPadded));
+ break;
+ }
+ break;
+
+ case 's':
+ used = true;
+ repeat = qMin(repeat, 2);
+ switch (repeat) {
+ case 1:
+ result.append(m_data->longLongToString(time.second()));
+ break;
+ case 2:
+ result.append(m_data->longLongToString(time.second(), -1, 10, 2, QLocaleData::ZeroPadded));
+ break;
+ }
+ break;
+
+ case 'a':
+ used = true;
+ if (i + 1 < format.size() && format.at(i + 1).unicode() == 'p') {
+ repeat = 2;
+ } else {
+ repeat = 1;
+ }
+ result.append(time.hour() < 12 ? q->amText().toLower() : q->pmText().toLower());
+ break;
+
+ case 'A':
+ used = true;
+ if (i + 1 < format.size() && format.at(i + 1).unicode() == 'P') {
+ repeat = 2;
+ } else {
+ repeat = 1;
+ }
+ result.append(time.hour() < 12 ? q->amText().toUpper() : q->pmText().toUpper());
+ break;
+
+ case 'z':
+ used = true;
+ if (repeat >= 3) {
+ repeat = 3;
+ } else {
+ repeat = 1;
+ }
+
+ // note: the millisecond component is treated like the decimal part of the seconds
+ // so ms == 2 is always printed as "002", but ms == 200 can be either "2" or "200"
+ result.append(m_data->longLongToString(time.msec(), -1, 10, 3, QLocaleData::ZeroPadded));
+ if (repeat == 1) {
+ if (result.endsWith(zero()))
+ result.chop(1);
+ if (result.endsWith(zero()))
+ result.chop(1);
+ }
+
+ break;
+
+ case 't':
+ used = true;
+ repeat = 1;
+ // If we have a QDateTime use the time spec otherwise use the current system tzname
+ if (formatDate) {
+ result.append(datetime.timeZoneAbbreviation());
+ } else {
+ result.append(QDateTime::currentDateTime().timeZoneAbbreviation());
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (!used) {
+ result.append(QString(repeat, c));
+ }
+ i += repeat;
+ }
+
+ return result;
+}
+
+QString QLocaleData::doubleToString(double d, int precision, DoubleForm form,
+ int width, unsigned flags) const
+{
+ return doubleToString(m_zero, m_plus, m_minus, m_exponential, m_group, m_decimal,
+ d, precision, form, width, flags);
+}
+
+QString QLocaleData::doubleToString(const QChar _zero, const QChar plus, const QChar minus,
+ const QChar exponential, const QChar group, const QChar decimal,
+ double d, int precision, DoubleForm form, int width, unsigned flags)
+{
+ if (precision != QLocale::FloatingPointShortest && precision < 0)
+ precision = 6;
+ if (width < 0)
+ width = 0;
+
+ bool negative = false;
+ QString num_str;
+
+ int decpt;
+ int bufSize = 1;
+ if (precision == QLocale::FloatingPointShortest)
+ bufSize += DoubleMaxSignificant;
+ else if (form == DFDecimal) // optimize for numbers between -512k and 512k
+ bufSize += ((d > (1 << 19) || d < -(1 << 19)) ? DoubleMaxDigitsBeforeDecimal : 6) +
+ precision;
+ else // Add extra digit due to different interpretations of precision. Also, "nan" has to fit.
+ bufSize += qMax(2, precision) + 1;
+
+ QVarLengthArray<char> buf(bufSize);
+ int length;
+
+ qt_doubleToAscii(d, form, precision, buf.data(), bufSize, negative, length, decpt);
+
+ if (qstrncmp(buf.data(), "inf", 3) == 0 || qstrncmp(buf.data(), "nan", 3) == 0) {
+ num_str = QString::fromLatin1(buf.data(), length);
+ } else { // Handle normal numbers
+ QString digits = QString::fromLatin1(buf.data(), length);
+
+ if (_zero.unicode() != '0') {
+ ushort z = _zero.unicode() - '0';
+ for (int i = 0; i < digits.length(); ++i)
+ reinterpret_cast<ushort *>(digits.data())[i] += z;
+ }
+
+ bool always_show_decpt = (flags & ForcePoint);
+ switch (form) {
+ case DFExponent: {
+ num_str = exponentForm(_zero, decimal, exponential, group, plus, minus,
+ digits, decpt, precision, PMDecimalDigits,
+ always_show_decpt, flags & ZeroPadExponent);
+ break;
+ }
+ case DFDecimal: {
+ num_str = decimalForm(_zero, decimal, group,
+ digits, decpt, precision, PMDecimalDigits,
+ always_show_decpt, flags & ThousandsGroup);
+ break;
+ }
+ case DFSignificantDigits: {
+ PrecisionMode mode = (flags & AddTrailingZeroes) ?
+ PMSignificantDigits : PMChopTrailingZeros;
+
+ int cutoff = precision < 0 ? 6 : precision;
+ // Find out which representation is shorter
+ if (precision == QLocale::FloatingPointShortest && decpt > 0) {
+ cutoff = digits.length() + 4; // 'e', '+'/'-', one digit exponent
+ if (decpt <= 10) {
+ ++cutoff;
+ } else {
+ cutoff += decpt > 100 ? 2 : 1;
+ }
+ if (!always_show_decpt && digits.length() > decpt)
+ ++cutoff; // decpt shown in exponent form, but not in decimal form
+ }
+
+ if (decpt != digits.length() && (decpt <= -4 || decpt > cutoff))
+ num_str = exponentForm(_zero, decimal, exponential, group, plus, minus,
+ digits, decpt, precision, mode,
+ always_show_decpt, flags & ZeroPadExponent);
+ else
+ num_str = decimalForm(_zero, decimal, group,
+ digits, decpt, precision, mode,
+ always_show_decpt, flags & ThousandsGroup);
+ break;
+ }
+ }
+
+ if (isZero(d))
+ negative = false;
+
+ // pad with zeros. LeftAdjusted overrides this flag). Also, we don't
+ // pad special numbers
+ if (flags & QLocaleData::ZeroPadded && !(flags & QLocaleData::LeftAdjusted)) {
+ int num_pad_chars = width - num_str.length();
+ // leave space for the sign
+ if (negative
+ || flags & QLocaleData::AlwaysShowSign
+ || flags & QLocaleData::BlankBeforePositive)
+ --num_pad_chars;
+
+ for (int i = 0; i < num_pad_chars; ++i)
+ num_str.prepend(_zero);
+ }
+ }
+
+ // add sign
+ if (negative)
+ num_str.prepend(minus);
+ else if (flags & QLocaleData::AlwaysShowSign)
+ num_str.prepend(plus);
+ else if (flags & QLocaleData::BlankBeforePositive)
+ num_str.prepend(QLatin1Char(' '));
+
+ if (flags & QLocaleData::CapitalEorX)
+ num_str = std::move(num_str).toUpper();
+
+ return num_str;
+}
+
+QString QLocaleData::longLongToString(qlonglong l, int precision,
+ int base, int width,
+ unsigned flags) const
+{
+ return longLongToString(m_zero, m_group, m_plus, m_minus,
+ l, precision, base, width, flags);
+}
+
+QString QLocaleData::longLongToString(const QChar zero, const QChar group,
+ const QChar plus, const QChar minus,
+ qlonglong l, int precision,
+ int base, int width,
+ unsigned flags)
+{
+ bool precision_not_specified = false;
+ if (precision == -1) {
+ precision_not_specified = true;
+ precision = 1;
+ }
+
+ bool negative = l < 0;
+ if (base != 10) {
+ // these are not supported by sprintf for octal and hex
+ flags &= ~AlwaysShowSign;
+ flags &= ~BlankBeforePositive;
+ negative = false; // neither are negative numbers
+ }
+
+QT_WARNING_PUSH
+ /* "unary minus operator applied to unsigned type, result still unsigned" */
+QT_WARNING_DISABLE_MSVC(4146)
+ /*
+ Negating std::numeric_limits<qlonglong>::min() hits undefined behavior, so
+ taking an absolute value has to cast to unsigned to change sign.
+ */
+ QString num_str = qulltoa(negative ? -qulonglong(l) : qulonglong(l), base, zero);
+QT_WARNING_POP
+
+ uint cnt_thousand_sep = 0;
+ if (flags & ThousandsGroup && base == 10) {
+ for (int i = num_str.length() - 3; i > 0; i -= 3) {
+ num_str.insert(i, group);
+ ++cnt_thousand_sep;
+ }
+ }
+
+ for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
+ num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));
+
+ if ((flags & ShowBase)
+ && base == 8
+ && (num_str.isEmpty() || num_str[0].unicode() != QLatin1Char('0')))
+ num_str.prepend(QLatin1Char('0'));
+
+ // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
+ // when precision is not specified in the format string
+ bool zero_padded = flags & ZeroPadded
+ && !(flags & LeftAdjusted)
+ && precision_not_specified;
+
+ if (zero_padded) {
+ int num_pad_chars = width - num_str.length();
+
+ // leave space for the sign
+ if (negative
+ || flags & AlwaysShowSign
+ || flags & BlankBeforePositive)
+ --num_pad_chars;
+
+ // leave space for optional '0x' in hex form
+ if (base == 16 && (flags & ShowBase))
+ num_pad_chars -= 2;
+ // leave space for optional '0b' in binary form
+ else if (base == 2 && (flags & ShowBase))
+ num_pad_chars -= 2;
+
+ for (int i = 0; i < num_pad_chars; ++i)
+ num_str.prepend(base == 10 ? zero : QChar::fromLatin1('0'));
+ }
+
+ if (flags & CapitalEorX)
+ num_str = std::move(num_str).toUpper();
+
+ if (base == 16 && (flags & ShowBase))
+ num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
+ if (base == 2 && (flags & ShowBase))
+ num_str.prepend(QLatin1String(flags & UppercaseBase ? "0B" : "0b"));
+
+ // add sign
+ if (negative)
+ num_str.prepend(minus);
+ else if (flags & AlwaysShowSign)
+ num_str.prepend(plus);
+ else if (flags & BlankBeforePositive)
+ num_str.prepend(QLatin1Char(' '));
+
+ return num_str;
+}
+
+QString QLocaleData::unsLongLongToString(qulonglong l, int precision,
+ int base, int width,
+ unsigned flags) const
+{
+ return unsLongLongToString(m_zero, m_group, m_plus,
+ l, precision, base, width, flags);
+}
+
+QString QLocaleData::unsLongLongToString(const QChar zero, const QChar group,
+ const QChar plus,
+ qulonglong l, int precision,
+ int base, int width,
+ unsigned flags)
+{
+ const QChar resultZero = base == 10 ? zero : QChar(QLatin1Char('0'));
+ QString num_str = l ? qulltoa(l, base, zero) : QString(resultZero);
+
+ bool precision_not_specified = false;
+ if (precision == -1) {
+ if (flags == NoFlags)
+ return num_str; // fast-path: nothing below applies, so we're done.
+
+ precision_not_specified = true;
+ precision = 1;
+ }
+
+ uint cnt_thousand_sep = 0;
+ if (flags & ThousandsGroup && base == 10) {
+ for (int i = num_str.length() - 3; i > 0; i -=3) {
+ num_str.insert(i, group);
+ ++cnt_thousand_sep;
+ }
+ }
+
+ const int zeroPadding = precision - num_str.length()/* + cnt_thousand_sep*/;
+ if (zeroPadding > 0)
+ num_str.prepend(QString(zeroPadding, resultZero));
+
+ if ((flags & ShowBase)
+ && base == 8
+ && (num_str.isEmpty() || num_str.at(0).unicode() != QLatin1Char('0')))
+ num_str.prepend(QLatin1Char('0'));
+
+ // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
+ // when precision is not specified in the format string
+ bool zero_padded = flags & ZeroPadded
+ && !(flags & LeftAdjusted)
+ && precision_not_specified;
+
+ if (zero_padded) {
+ int num_pad_chars = width - num_str.length();
+
+ // leave space for optional '0x' in hex form
+ if (base == 16 && flags & ShowBase)
+ num_pad_chars -= 2;
+ // leave space for optional '0b' in binary form
+ else if (base == 2 && flags & ShowBase)
+ num_pad_chars -= 2;
+
+ if (num_pad_chars > 0)
+ num_str.prepend(QString(num_pad_chars, resultZero));
+ }
+
+ if (flags & CapitalEorX)
+ num_str = std::move(num_str).toUpper();
+
+ if (base == 16 && flags & ShowBase)
+ num_str.prepend(QLatin1String(flags & UppercaseBase ? "0X" : "0x"));
+ else if (base == 2 && flags & ShowBase)
+ num_str.prepend(QLatin1String(flags & UppercaseBase ? "0B" : "0b"));
+
+ // add sign
+ if (flags & AlwaysShowSign)
+ num_str.prepend(plus);
+ else if (flags & BlankBeforePositive)
+ num_str.prepend(QLatin1Char(' '));
+
+ return num_str;
+}
+
+/*
+ Converts a number in locale to its representation in the C locale.
+ Only has to guarantee that a string that is a correct representation of
+ a number will be converted. If junk is passed in, junk will be passed
+ out and the error will be detected during the actual conversion to a
+ number. We can't detect junk here, since we don't even know the base
+ of the number.
+*/
+bool QLocaleData::numberToCLocale(QStringView s, QLocale::NumberOptions number_options,
+ CharBuff *result) const
+{
+ const QChar *uc = s.data();
+ auto l = s.size();
+ decltype(l) idx = 0;
+
+ // Skip whitespace
+ while (idx < l && uc[idx].isSpace())
+ ++idx;
+ if (idx == l)
+ return false;
+
+ // Check trailing whitespace
+ for (; idx < l; --l) {
+ if (!uc[l - 1].isSpace())
+ break;
+ }
+
+ int group_cnt = 0; // counts number of group chars
+ int decpt_idx = -1;
+ int last_separator_idx = -1;
+ int start_of_digits_idx = -1;
+ int exponent_idx = -1;
+
+ while (idx < l) {
+ const QChar in = uc[idx];
+
+ char out = digitToCLocale(in);
+ if (out == 0) {
+ if (in == m_list)
+ out = ';';
+ else if (in == m_percent)
+ out = '%';
+ // for handling base-x numbers
+ else if (in.unicode() >= 'A' && in.unicode() <= 'Z')
+ out = in.toLower().toLatin1();
+ else if (in.unicode() >= 'a' && in.unicode() <= 'z')
+ out = in.toLatin1();
+ else
+ break;
+ } else if (out == '.') {
+ // Fail if more than one decimal point or point after e
+ if (decpt_idx != -1 || exponent_idx != -1)
+ return false;
+ decpt_idx = idx;
+ } else if (out == 'e' || out == 'E') {
+ exponent_idx = idx;
+ }
+
+ if (number_options & QLocale::RejectLeadingZeroInExponent) {
+ if (exponent_idx != -1 && out == '0' && idx < l - 1) {
+ // After the exponent there can only be '+', '-' or digits.
+ // If we find a '0' directly after some non-digit, then that is a leading zero.
+ if (result->last() < '0' || result->last() > '9')
+ return false;
+ }
+ }
+
+ if (number_options & QLocale::RejectTrailingZeroesAfterDot) {
+ // If we've seen a decimal point and the last character after the exponent is 0, then
+ // that is a trailing zero.
+ if (decpt_idx >= 0 && idx == exponent_idx && result->last() == '0')
+ return false;
+ }
+
+ if (!(number_options & QLocale::RejectGroupSeparator)) {
+ if (start_of_digits_idx == -1 && out >= '0' && out <= '9') {
+ start_of_digits_idx = idx;
+ } else if (out == ',') {
+ // Don't allow group chars after the decimal point or exponent
+ if (decpt_idx != -1 || exponent_idx != -1)
+ return false;
+
+ // check distance from the last separator or from the beginning of the digits
+ // ### FIXME: Some locales allow other groupings! See https://en.wikipedia.org/wiki/Thousands_separator
+ if (last_separator_idx != -1 && idx - last_separator_idx != 4)
+ return false;
+ if (last_separator_idx == -1 && (start_of_digits_idx == -1 || idx - start_of_digits_idx > 3))
+ return false;
+
+ last_separator_idx = idx;
+ ++group_cnt;
+
+ // don't add the group separator
+ ++idx;
+ continue;
+ } else if (out == '.' || out == 'e' || out == 'E') {
+ // check distance from the last separator
+ // ### FIXME: Some locales allow other groupings! See https://en.wikipedia.org/wiki/Thousands_separator
+ if (last_separator_idx != -1 && idx - last_separator_idx != 4)
+ return false;
+
+ // stop processing separators
+ last_separator_idx = -1;
+ }
+ }
+
+ result->append(out);
+
+ ++idx;
+ }
+
+ if (!(number_options & QLocale::RejectGroupSeparator)) {
+ // group separator post-processing
+ // did we end in a separator?
+ if (last_separator_idx + 1 == idx)
+ return false;
+ // were there enough digits since the last separator?
+ if (last_separator_idx != -1 && idx - last_separator_idx != 4)
+ return false;
+ }
+
+ if (number_options & QLocale::RejectTrailingZeroesAfterDot) {
+ // In decimal form, the last character can be a trailing zero if we've seen a decpt.
+ if (decpt_idx != -1 && exponent_idx == -1 && result->last() == '0')
+ return false;
+ }
+
+ result->append('\0');
+ return idx == l;
+}
+
+bool QLocaleData::validateChars(QStringView str, NumberMode numMode, QByteArray *buff,
+ int decDigits, QLocale::NumberOptions number_options) const
+{
+ buff->clear();
+ buff->reserve(str.length());
+
+ const bool scientific = numMode == DoubleScientificMode;
+ bool lastWasE = false;
+ bool lastWasDigit = false;
+ int eCnt = 0;
+ int decPointCnt = 0;
+ bool dec = false;
+ int decDigitCnt = 0;
+
+ for (qsizetype i = 0; i < str.size(); ++i) {
+ char c = digitToCLocale(str.at(i));
+
+ if (c >= '0' && c <= '9') {
+ if (numMode != IntegerMode) {
+ // If a double has too many digits after decpt, it shall be Invalid.
+ if (dec && decDigits != -1 && decDigits < ++decDigitCnt)
+ return false;
+ }
+
+ // The only non-digit character after the 'e' can be '+' or '-'.
+ // If a zero is directly after that, then the exponent is zero-padded.
+ if ((number_options & QLocale::RejectLeadingZeroInExponent) && c == '0' && eCnt > 0 &&
+ !lastWasDigit)
+ return false;
+
+ lastWasDigit = true;
+ } else {
+ switch (c) {
+ case '.':
+ if (numMode == IntegerMode) {
+ // If an integer has a decimal point, it shall be Invalid.
+ return false;
+ } else {
+ // If a double has more than one decimal point, it shall be Invalid.
+ if (++decPointCnt > 1)
+ return false;
+#if 0
+ // If a double with no decimal digits has a decimal point, it shall be
+ // Invalid.
+ if (decDigits == 0)
+ return false;
+#endif // On second thoughts, it shall be Valid.
+
+ dec = true;
+ }
+ break;
+
+ case '+':
+ case '-':
+ if (scientific) {
+ // If a scientific has a sign that's not at the beginning or after
+ // an 'e', it shall be Invalid.
+ if (i != 0 && !lastWasE)
+ return false;
+ } else {
+ // If a non-scientific has a sign that's not at the beginning,
+ // it shall be Invalid.
+ if (i != 0)
+ return false;
+ }
+ break;
+
+ case ',':
+ //it can only be placed after a digit which is before the decimal point
+ if ((number_options & QLocale::RejectGroupSeparator) || !lastWasDigit ||
+ decPointCnt > 0)
+ return false;
+ break;
+
+ case 'e':
+ if (scientific) {
+ // If a scientific has more than one 'e', it shall be Invalid.
+ if (++eCnt > 1)
+ return false;
+ dec = false;
+ } else {
+ // If a non-scientific has an 'e', it shall be Invalid.
+ return false;
+ }
+ break;
+
+ default:
+ // If it's not a valid digit, it shall be Invalid.
+ return false;
+ }
+ lastWasDigit = false;
+ }
+
+ lastWasE = c == 'e';
+ if (c != ',')
+ buff->append(c);
+ }
+
+ return true;
+}
+
+double QLocaleData::stringToDouble(QStringView str, bool *ok,
+ QLocale::NumberOptions number_options) const
+{
+ CharBuff buff;
+ if (!numberToCLocale(str, number_options, &buff)) {
+ if (ok != nullptr)
+ *ok = false;
+ return 0.0;
+ }
+ int processed = 0;
+ bool nonNullOk = false;
+ double d = qt_asciiToDouble(buff.constData(), buff.length() - 1, nonNullOk, processed);
+ if (ok != nullptr)
+ *ok = nonNullOk;
+ return d;
+}
+
+qlonglong QLocaleData::stringToLongLong(QStringView str, int base, bool *ok,
+ QLocale::NumberOptions number_options) const
+{
+ CharBuff buff;
+ if (!numberToCLocale(str, number_options, &buff)) {
+ if (ok != nullptr)
+ *ok = false;
+ return 0;
+ }
+
+ return bytearrayToLongLong(buff.constData(), base, ok);
+}
+
+qulonglong QLocaleData::stringToUnsLongLong(QStringView str, int base, bool *ok,
+ QLocale::NumberOptions number_options) const
+{
+ CharBuff buff;
+ if (!numberToCLocale(str, number_options, &buff)) {
+ if (ok != nullptr)
+ *ok = false;
+ return 0;
+ }
+
+ return bytearrayToUnsLongLong(buff.constData(), base, ok);
+}
+
+double QLocaleData::bytearrayToDouble(const char *num, bool *ok)
+{
+ bool nonNullOk = false;
+ int len = static_cast<int>(strlen(num));
+ Q_ASSERT(len >= 0);
+ int processed = 0;
+ double d = qt_asciiToDouble(num, len, nonNullOk, processed);
+ if (ok != nullptr)
+ *ok = nonNullOk;
+ return d;
+}
+
+qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)
+{
+ bool _ok;
+ const char *endptr;
+
+ if (*num == '\0') {
+ if (ok != nullptr)
+ *ok = false;
+ return 0;
+ }
+
+ qlonglong l = qstrtoll(num, &endptr, base, &_ok);
+
+ if (!_ok) {
+ if (ok != nullptr)
+ *ok = false;
+ return 0;
+ }
+
+ if (*endptr != '\0') {
+ while (ascii_isspace(*endptr))
+ ++endptr;
+ }
+
+ if (*endptr != '\0') {
+ // we stopped at a non-digit character after converting some digits
+ if (ok != nullptr)
+ *ok = false;
+ return 0;
+ }
+
+ if (ok != nullptr)
+ *ok = true;
+ return l;
+}
+
+qulonglong QLocaleData::bytearrayToUnsLongLong(const char *num, int base, bool *ok)
+{
+ bool _ok;
+ const char *endptr;
+ qulonglong l = qstrtoull(num, &endptr, base, &_ok);
+
+ if (!_ok) {
+ if (ok != nullptr)
+ *ok = false;
+ return 0;
+ }
+
+ if (*endptr != '\0') {
+ while (ascii_isspace(*endptr))
+ ++endptr;
+ }
+
+ if (*endptr != '\0') {
+ if (ok != nullptr)
+ *ok = false;
+ return 0;
+ }
+
+ if (ok != nullptr)
+ *ok = true;
+ return l;
+}
+
+/*!
+ \since 4.8
+
+ \enum QLocale::CurrencySymbolFormat
+
+ Specifies the format of the currency symbol.
+
+ \value CurrencyIsoCode a ISO-4217 code of the currency.
+ \value CurrencySymbol a currency symbol.
+ \value CurrencyDisplayName a user readable name of the currency.
+*/
+
+/*!
+ \since 4.8
+ Returns a currency symbol according to the \a format.
+*/
+QString QLocale::currencySymbol(QLocale::CurrencySymbolFormat format) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(QSystemLocale::CurrencySymbol, format);
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ quint32 idx, size;
+ switch (format) {
+ case CurrencySymbol:
+ idx = d->m_data->m_currency_symbol_idx;
+ size = d->m_data->m_currency_symbol_size;
+ return getLocaleData(currency_symbol_data + idx, size);
+ case CurrencyDisplayName:
+ idx = d->m_data->m_currency_display_name_idx;
+ size = d->m_data->m_currency_display_name_size;
+ return getLocaleListData(currency_display_name_data + idx, size, 0);
+ case CurrencyIsoCode: {
+ int len = 0;
+ const QLocaleData *data = this->d->m_data;
+ for (; len < 3; ++len)
+ if (!data->m_currency_iso_code[len])
+ break;
+ return len ? QString::fromLatin1(data->m_currency_iso_code, len) : QString();
+ }
+ }
+ return QString();
+}
+
+/*!
+ \since 4.8
+
+ Returns a localized string representation of \a value as a currency.
+ If the \a symbol is provided it is used instead of the default currency symbol.
+
+ \sa currencySymbol()
+*/
+QString QLocale::toCurrencyString(qlonglong value, const QString &symbol) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QSystemLocale::CurrencyToStringArgument arg(value, symbol);
+ QVariant res = systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg));
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ const QLocalePrivate *d = this->d;
+ quint8 idx = d->m_data->m_currency_format_idx;
+ quint8 size = d->m_data->m_currency_format_size;
+ if (d->m_data->m_currency_negative_format_size && value < 0) {
+ idx = d->m_data->m_currency_negative_format_idx;
+ size = d->m_data->m_currency_negative_format_size;
+ value = -value;
+ }
+ QString str = toString(value);
+ QString sym = symbol.isNull() ? currencySymbol() : symbol;
+ if (sym.isEmpty())
+ sym = currencySymbol(QLocale::CurrencyIsoCode);
+ QString format = getLocaleData(currency_format_data + idx, size);
+ return format.arg(str, sym);
+}
+
+/*!
+ \since 4.8
+ \overload
+*/
+QString QLocale::toCurrencyString(qulonglong value, const QString &symbol) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QSystemLocale::CurrencyToStringArgument arg(value, symbol);
+ QVariant res = systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg));
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ const QLocaleData *data = this->d->m_data;
+ quint8 idx = data->m_currency_format_idx;
+ quint8 size = data->m_currency_format_size;
+ QString str = toString(value);
+ QString sym = symbol.isNull() ? currencySymbol() : symbol;
+ if (sym.isEmpty())
+ sym = currencySymbol(QLocale::CurrencyIsoCode);
+ QString format = getLocaleData(currency_format_data + idx, size);
+ return format.arg(str, sym);
+}
+
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+/*!
+ \since 4.8
+ \overload
+*/
+QString QLocale::toCurrencyString(double value, const QString &symbol) const
+{
+ return toCurrencyString(value, symbol, d->m_data->m_currency_digits);
+}
+#endif
+
+/*!
+ \since 5.7
+ \overload toCurrencyString()
+
+ Returns a localized string representation of \a value as a currency.
+ If the \a symbol is provided it is used instead of the default currency symbol.
+ If the \a precision is provided it is used to set the precision of the currency value.
+
+ \sa currencySymbol()
+ */
+QString QLocale::toCurrencyString(double value, const QString &symbol, int precision) const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QSystemLocale::CurrencyToStringArgument arg(value, symbol);
+ QVariant res = systemLocale()->query(QSystemLocale::CurrencyToString, QVariant::fromValue(arg));
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ const QLocaleData *data = this->d->m_data;
+ quint8 idx = data->m_currency_format_idx;
+ quint8 size = data->m_currency_format_size;
+ if (data->m_currency_negative_format_size && value < 0) {
+ idx = data->m_currency_negative_format_idx;
+ size = data->m_currency_negative_format_size;
+ value = -value;
+ }
+ QString str = toString(value, 'f', precision == -1 ? d->m_data->m_currency_digits : precision);
+ QString sym = symbol.isNull() ? currencySymbol() : symbol;
+ if (sym.isEmpty())
+ sym = currencySymbol(QLocale::CurrencyIsoCode);
+ QString format = getLocaleData(currency_format_data + idx, size);
+ return format.arg(str, sym);
+}
+
+/*!
+ \fn QString QLocale::toCurrencyString(float i, const QString &symbol) const
+ \fn QString QLocale::toCurrencyString(float i, const QString &symbol, int precision) const
+ \overload toCurrencyString()
+*/
+
+/*!
+ \since 5.10
+
+ \enum QLocale::DataSizeFormat
+
+ Specifies the format for representation of data quantities.
+
+ \omitvalue DataSizeBase1000
+ \omitvalue DataSizeSIQuantifiers
+ \value DataSizeIecFormat format using base 1024 and IEC prefixes: KiB, MiB, GiB, ...
+ \value DataSizeTraditionalFormat format using base 1024 and SI prefixes: kB, MB, GB, ...
+ \value DataSizeSIFormat format using base 1000 and SI prefixes: kB, MB, GB, ...
+
+ \sa formattedDataSize()
+*/
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+/*!
+ \obsolete
+
+ Use the const version instead.
+*/
+QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format)
+{
+ const auto *that = this;
+ return that->formattedDataSize(bytes, precision, format);
+}
+#endif
+
+/*!
+ \since 5.10
+
+ Converts a size in bytes to a human-readable localized string, comprising a
+ number and a quantified unit. The quantifier is chosen such that the number
+ is at least one, and as small as possible. For example if \a bytes is
+ 16384, \a precision is 2, and \a format is \l DataSizeIecFormat (the
+ default), this function returns "16.00 KiB"; for 1330409069609 bytes it
+ returns "1.21 GiB"; and so on. If \a format is \l DataSizeIecFormat or
+ \l DataSizeTraditionalFormat, the given number of bytes is divided by a
+ power of 1024, with result less than 1024; for \l DataSizeSIFormat, it is
+ divided by a power of 1000, with result less than 1000.
+ \c DataSizeIecFormat uses the new IEC standard quantifiers Ki, Mi and so on,
+ whereas \c DataSizeSIFormat uses the older SI quantifiers k, M, etc., and
+ \c DataSizeTraditionalFormat abuses them.
+*/
+QString QLocale::formattedDataSize(qint64 bytes, int precision, DataSizeFormats format) const
+{
+ int power, base = 1000;
+ if (!bytes) {
+ power = 0;
+ } else if (format & DataSizeBase1000) {
+ power = int(std::log10(qAbs(bytes)) / 3);
+ } else { // Compute log2(bytes) / 10:
+ power = int((63 - qCountLeadingZeroBits(quint64(qAbs(bytes)))) / 10);
+ base = 1024;
+ }
+ // Only go to doubles if we'll be using a quantifier:
+ const QString number = power
+ ? toString(bytes / std::pow(double(base), power), 'f', qMin(precision, 3 * power))
+ : toString(bytes);
+
+ // We don't support sizes in units larger than exbibytes because
+ // the number of bytes would not fit into qint64.
+ Q_ASSERT(power <= 6 && power >= 0);
+ QString unit;
+ if (power > 0) {
+ quint16 index, size;
+ if (format & DataSizeSIQuantifiers) {
+ index = d->m_data->m_byte_si_quantified_idx;
+ size = d->m_data->m_byte_si_quantified_size;
+ } else {
+ index = d->m_data->m_byte_iec_quantified_idx;
+ size = d->m_data->m_byte_iec_quantified_size;
+ }
+ unit = getLocaleListData(byte_unit_data + index, size, power - 1);
+ } else {
+ unit = getLocaleData(byte_unit_data + d->m_data->m_byte_idx, d->m_data->m_byte_size);
+ }
+
+ return number + QLatin1Char(' ') + unit;
+}
+
+/*!
+ \since 4.8
+
+ Returns an ordered list of locale names for translation purposes in
+ preference order (like "en-Latn-US", "en-US", "en").
+
+ The return value represents locale names that the user expects to see the
+ UI translation in.
+
+ Most like you do not need to use this function directly, but just pass the
+ QLocale object to the QTranslator::load() function.
+
+ The first item in the list is the most preferred one.
+
+ \sa QTranslator, bcp47Name()
+*/
+QStringList QLocale::uiLanguages() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(QSystemLocale::UILanguages, QVariant());
+ if (!res.isNull()) {
+ QStringList result = res.toStringList();
+ if (!result.isEmpty())
+ return result;
+ }
+ }
+#endif
+ QLocaleId id = QLocaleId::fromIds(d->m_data->m_language_id, d->m_data->m_script_id, d->m_data->m_country_id);
+ const QLocaleId max = id.withLikelySubtagsAdded();
+ const QLocaleId min = max.withLikelySubtagsRemoved();
+
+ QStringList uiLanguages;
+ uiLanguages.append(QString::fromLatin1(min.name()));
+ if (id.script_id) {
+ id.script_id = 0;
+ if (id != min && id.withLikelySubtagsAdded() == max)
+ uiLanguages.append(QString::fromLatin1(id.name()));
+ }
+ if (max != min && max != id)
+ uiLanguages.append(QString::fromLatin1(max.name()));
+ return uiLanguages;
+}
+
+/*!
+ \since 5.13
+
+ Returns the locale to use for collation.
+
+ The result is usually this locale; however, the system locale (which is
+ commonly the default locale) will return the system collation locale.
+ The result is suitable for passing to QCollator's constructor.
+
+ \sa QCollator
+*/
+QLocale QLocale::collation() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QString res = systemLocale()->query(QSystemLocale::Collation, QVariant()).toString();
+ if (!res.isEmpty())
+ return QLocale(res);
+ }
+#endif
+ return *this;
+}
+
+/*!
+ \since 4.8
+
+ Returns a native name of the language for the locale. For example
+ "Schwiizertüütsch" for Swiss-German locale.
+
+ \sa nativeCountryName(), languageToString()
+*/
+QString QLocale::nativeLanguageName() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(QSystemLocale::NativeLanguageName, QVariant());
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ return getLocaleData(endonyms_data + d->m_data->m_language_endonym_idx, d->m_data->m_language_endonym_size);
+}
+
+/*!
+ \since 4.8
+
+ Returns a native name of the country for the locale. For example
+ "España" for Spanish/Spain locale.
+
+ \sa nativeLanguageName(), countryToString()
+*/
+QString QLocale::nativeCountryName() const
+{
+#ifndef QT_NO_SYSTEMLOCALE
+ if (d->m_data == systemData()) {
+ QVariant res = systemLocale()->query(QSystemLocale::NativeCountryName, QVariant());
+ if (!res.isNull())
+ return res.toString();
+ }
+#endif
+ return getLocaleData(endonyms_data + d->m_data->m_country_endonym_idx, d->m_data->m_country_endonym_size);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QDebug operator<<(QDebug dbg, const QLocale &l)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace().noquote()
+ << "QLocale(" << QLocale::languageToString(l.language())
+ << ", " << QLocale::scriptToString(l.script())
+ << ", " << QLocale::countryToString(l.country()) << ')';
+ return dbg;
+}
+#endif
+QT_END_NAMESPACE
+
+#ifndef QT_NO_QOBJECT
+#include "moc_qlocale.cpp"
+#endif
diff --git a/src/corelib/text/qlocale.h b/src/corelib/text/qlocale.h
new file mode 100644
index 0000000000..09de830ca3
--- /dev/null
+++ b/src/corelib/text/qlocale.h
@@ -0,0 +1,1153 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLOCALE_H
+#define QLOCALE_H
+
+#include <QtCore/qvariant.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qobjectdefs.h>
+#include <QtCore/qshareddata.h>
+
+QT_BEGIN_NAMESPACE
+
+
+class QDataStream;
+class QDate;
+class QDateTime;
+class QLocale;
+class QTime;
+class QVariant;
+class QTextStream;
+class QTextStreamPrivate;
+
+class QLocalePrivate;
+
+Q_CORE_EXPORT uint qHash(const QLocale &key, uint seed = 0) noexcept;
+
+class Q_CORE_EXPORT QLocale
+{
+ Q_GADGET
+ friend class QString;
+ friend class QStringRef;
+ friend class QByteArray;
+ friend class QIntValidator;
+ friend class QDoubleValidatorPrivate;
+ friend class QTextStream;
+ friend class QTextStreamPrivate;
+
+public:
+// GENERATED PART STARTS HERE
+// see qlocale_data_p.h for more info on generated data
+ enum Language {
+ AnyLanguage = 0,
+ C = 1,
+ Abkhazian = 2,
+ Oromo = 3,
+ Afar = 4,
+ Afrikaans = 5,
+ Albanian = 6,
+ Amharic = 7,
+ Arabic = 8,
+ Armenian = 9,
+ Assamese = 10,
+ Aymara = 11,
+ Azerbaijani = 12,
+ Bashkir = 13,
+ Basque = 14,
+ Bengali = 15,
+ Dzongkha = 16,
+ Bihari = 17,
+ Bislama = 18,
+ Breton = 19,
+ Bulgarian = 20,
+ Burmese = 21,
+ Belarusian = 22,
+ Khmer = 23,
+ Catalan = 24,
+ Chinese = 25,
+ Corsican = 26,
+ Croatian = 27,
+ Czech = 28,
+ Danish = 29,
+ Dutch = 30,
+ English = 31,
+ Esperanto = 32,
+ Estonian = 33,
+ Faroese = 34,
+ Fijian = 35,
+ Finnish = 36,
+ French = 37,
+ WesternFrisian = 38,
+ Gaelic = 39,
+ Galician = 40,
+ Georgian = 41,
+ German = 42,
+ Greek = 43,
+ Greenlandic = 44,
+ Guarani = 45,
+ Gujarati = 46,
+ Hausa = 47,
+ Hebrew = 48,
+ Hindi = 49,
+ Hungarian = 50,
+ Icelandic = 51,
+ Indonesian = 52,
+ Interlingua = 53,
+ Interlingue = 54,
+ Inuktitut = 55,
+ Inupiak = 56,
+ Irish = 57,
+ Italian = 58,
+ Japanese = 59,
+ Javanese = 60,
+ Kannada = 61,
+ Kashmiri = 62,
+ Kazakh = 63,
+ Kinyarwanda = 64,
+ Kirghiz = 65,
+ Korean = 66,
+ Kurdish = 67,
+ Rundi = 68,
+ Lao = 69,
+ Latin = 70,
+ Latvian = 71,
+ Lingala = 72,
+ Lithuanian = 73,
+ Macedonian = 74,
+ Malagasy = 75,
+ Malay = 76,
+ Malayalam = 77,
+ Maltese = 78,
+ Maori = 79,
+ Marathi = 80,
+ Marshallese = 81,
+ Mongolian = 82,
+ NauruLanguage = 83,
+ Nepali = 84,
+ NorwegianBokmal = 85,
+ Occitan = 86,
+ Oriya = 87,
+ Pashto = 88,
+ Persian = 89,
+ Polish = 90,
+ Portuguese = 91,
+ Punjabi = 92,
+ Quechua = 93,
+ Romansh = 94,
+ Romanian = 95,
+ Russian = 96,
+ Samoan = 97,
+ Sango = 98,
+ Sanskrit = 99,
+ Serbian = 100,
+ Ossetic = 101,
+ SouthernSotho = 102,
+ Tswana = 103,
+ Shona = 104,
+ Sindhi = 105,
+ Sinhala = 106,
+ Swati = 107,
+ Slovak = 108,
+ Slovenian = 109,
+ Somali = 110,
+ Spanish = 111,
+ Sundanese = 112,
+ Swahili = 113,
+ Swedish = 114,
+ Sardinian = 115,
+ Tajik = 116,
+ Tamil = 117,
+ Tatar = 118,
+ Telugu = 119,
+ Thai = 120,
+ Tibetan = 121,
+ Tigrinya = 122,
+ Tongan = 123,
+ Tsonga = 124,
+ Turkish = 125,
+ Turkmen = 126,
+ Tahitian = 127,
+ Uighur = 128,
+ Ukrainian = 129,
+ Urdu = 130,
+ Uzbek = 131,
+ Vietnamese = 132,
+ Volapuk = 133,
+ Welsh = 134,
+ Wolof = 135,
+ Xhosa = 136,
+ Yiddish = 137,
+ Yoruba = 138,
+ Zhuang = 139,
+ Zulu = 140,
+ NorwegianNynorsk = 141,
+ Bosnian = 142,
+ Divehi = 143,
+ Manx = 144,
+ Cornish = 145,
+ Akan = 146,
+ Konkani = 147,
+ Ga = 148,
+ Igbo = 149,
+ Kamba = 150,
+ Syriac = 151,
+ Blin = 152,
+ Geez = 153,
+ Koro = 154,
+ Sidamo = 155,
+ Atsam = 156,
+ Tigre = 157,
+ Jju = 158,
+ Friulian = 159,
+ Venda = 160,
+ Ewe = 161,
+ Walamo = 162,
+ Hawaiian = 163,
+ Tyap = 164,
+ Nyanja = 165,
+ Filipino = 166,
+ SwissGerman = 167,
+ SichuanYi = 168,
+ Kpelle = 169,
+ LowGerman = 170,
+ SouthNdebele = 171,
+ NorthernSotho = 172,
+ NorthernSami = 173,
+ Taroko = 174,
+ Gusii = 175,
+ Taita = 176,
+ Fulah = 177,
+ Kikuyu = 178,
+ Samburu = 179,
+ Sena = 180,
+ NorthNdebele = 181,
+ Rombo = 182,
+ Tachelhit = 183,
+ Kabyle = 184,
+ Nyankole = 185,
+ Bena = 186,
+ Vunjo = 187,
+ Bambara = 188,
+ Embu = 189,
+ Cherokee = 190,
+ Morisyen = 191,
+ Makonde = 192,
+ Langi = 193,
+ Ganda = 194,
+ Bemba = 195,
+ Kabuverdianu = 196,
+ Meru = 197,
+ Kalenjin = 198,
+ Nama = 199,
+ Machame = 200,
+ Colognian = 201,
+ Masai = 202,
+ Soga = 203,
+ Luyia = 204,
+ Asu = 205,
+ Teso = 206,
+ Saho = 207,
+ KoyraChiini = 208,
+ Rwa = 209,
+ Luo = 210,
+ Chiga = 211,
+ CentralMoroccoTamazight = 212,
+ KoyraboroSenni = 213,
+ Shambala = 214,
+ Bodo = 215,
+ Avaric = 216,
+ Chamorro = 217,
+ Chechen = 218,
+ Church = 219,
+ Chuvash = 220,
+ Cree = 221,
+ Haitian = 222,
+ Herero = 223,
+ HiriMotu = 224,
+ Kanuri = 225,
+ Komi = 226,
+ Kongo = 227,
+ Kwanyama = 228,
+ Limburgish = 229,
+ LubaKatanga = 230,
+ Luxembourgish = 231,
+ Navaho = 232,
+ Ndonga = 233,
+ Ojibwa = 234,
+ Pali = 235,
+ Walloon = 236,
+ Aghem = 237,
+ Basaa = 238,
+ Zarma = 239,
+ Duala = 240,
+ JolaFonyi = 241,
+ Ewondo = 242,
+ Bafia = 243,
+ MakhuwaMeetto = 244,
+ Mundang = 245,
+ Kwasio = 246,
+ Nuer = 247,
+ Sakha = 248,
+ Sangu = 249,
+ CongoSwahili = 250,
+ Tasawaq = 251,
+ Vai = 252,
+ Walser = 253,
+ Yangben = 254,
+ Avestan = 255,
+ Asturian = 256,
+ Ngomba = 257,
+ Kako = 258,
+ Meta = 259,
+ Ngiemboon = 260,
+ Aragonese = 261,
+ Akkadian = 262,
+ AncientEgyptian = 263,
+ AncientGreek = 264,
+ Aramaic = 265,
+ Balinese = 266,
+ Bamun = 267,
+ BatakToba = 268,
+ Buginese = 269,
+ Buhid = 270,
+ Carian = 271,
+ Chakma = 272,
+ ClassicalMandaic = 273,
+ Coptic = 274,
+ Dogri = 275,
+ EasternCham = 276,
+ EasternKayah = 277,
+ Etruscan = 278,
+ Gothic = 279,
+ Hanunoo = 280,
+ Ingush = 281,
+ LargeFloweryMiao = 282,
+ Lepcha = 283,
+ Limbu = 284,
+ Lisu = 285,
+ Lu = 286,
+ Lycian = 287,
+ Lydian = 288,
+ Mandingo = 289,
+ Manipuri = 290,
+ Meroitic = 291,
+ NorthernThai = 292,
+ OldIrish = 293,
+ OldNorse = 294,
+ OldPersian = 295,
+ OldTurkish = 296,
+ Pahlavi = 297,
+ Parthian = 298,
+ Phoenician = 299,
+ PrakritLanguage = 300,
+ Rejang = 301,
+ Sabaean = 302,
+ Samaritan = 303,
+ Santali = 304,
+ Saurashtra = 305,
+ Sora = 306,
+ Sylheti = 307,
+ Tagbanwa = 308,
+ TaiDam = 309,
+ TaiNua = 310,
+ Ugaritic = 311,
+ Akoose = 312,
+ Lakota = 313,
+ StandardMoroccanTamazight = 314,
+ Mapuche = 315,
+ CentralKurdish = 316,
+ LowerSorbian = 317,
+ UpperSorbian = 318,
+ Kenyang = 319,
+ Mohawk = 320,
+ Nko = 321,
+ Prussian = 322,
+ Kiche = 323,
+ SouthernSami = 324,
+ LuleSami = 325,
+ InariSami = 326,
+ SkoltSami = 327,
+ Warlpiri = 328,
+ ManichaeanMiddlePersian = 329,
+ Mende = 330,
+ AncientNorthArabian = 331,
+ LinearA = 332,
+ HmongNjua = 333,
+ Ho = 334,
+ Lezghian = 335,
+ Bassa = 336,
+ Mono = 337,
+ TedimChin = 338,
+ Maithili = 339,
+ Ahom = 340,
+ AmericanSignLanguage = 341,
+ ArdhamagadhiPrakrit = 342,
+ Bhojpuri = 343,
+ HieroglyphicLuwian = 344,
+ LiteraryChinese = 345,
+ Mazanderani = 346,
+ Mru = 347,
+ Newari = 348,
+ NorthernLuri = 349,
+ Palauan = 350,
+ Papiamento = 351,
+ Saraiki = 352,
+ TokelauLanguage = 353,
+ TokPisin = 354,
+ TuvaluLanguage = 355,
+ UncodedLanguages = 356,
+ Cantonese = 357,
+ Osage = 358,
+ Tangut = 359,
+ Ido = 360,
+ Lojban = 361,
+ Sicilian = 362,
+ SouthernKurdish = 363,
+ WesternBalochi = 364,
+ Cebuano = 365,
+ Erzya = 366,
+
+ Afan = Oromo,
+ Bhutani = Dzongkha,
+ Byelorussian = Belarusian,
+ Cambodian = Khmer,
+ Chewa = Nyanja,
+ Frisian = WesternFrisian,
+ Kurundi = Rundi,
+ Moldavian = Romanian,
+ Norwegian = NorwegianBokmal,
+ RhaetoRomance = Romansh,
+ SerboCroatian = Serbian,
+ Tagalog = Filipino,
+ Twi = Akan,
+ Uigur = Uighur,
+
+ LastLanguage = Erzya
+ };
+
+ enum Script {
+ AnyScript = 0,
+ ArabicScript = 1,
+ CyrillicScript = 2,
+ DeseretScript = 3,
+ GurmukhiScript = 4,
+ SimplifiedHanScript = 5,
+ TraditionalHanScript = 6,
+ LatinScript = 7,
+ MongolianScript = 8,
+ TifinaghScript = 9,
+ ArmenianScript = 10,
+ BengaliScript = 11,
+ CherokeeScript = 12,
+ DevanagariScript = 13,
+ EthiopicScript = 14,
+ GeorgianScript = 15,
+ GreekScript = 16,
+ GujaratiScript = 17,
+ HebrewScript = 18,
+ JapaneseScript = 19,
+ KhmerScript = 20,
+ KannadaScript = 21,
+ KoreanScript = 22,
+ LaoScript = 23,
+ MalayalamScript = 24,
+ MyanmarScript = 25,
+ OriyaScript = 26,
+ TamilScript = 27,
+ TeluguScript = 28,
+ ThaanaScript = 29,
+ ThaiScript = 30,
+ TibetanScript = 31,
+ SinhalaScript = 32,
+ SyriacScript = 33,
+ YiScript = 34,
+ VaiScript = 35,
+ AvestanScript = 36,
+ BalineseScript = 37,
+ BamumScript = 38,
+ BatakScript = 39,
+ BopomofoScript = 40,
+ BrahmiScript = 41,
+ BugineseScript = 42,
+ BuhidScript = 43,
+ CanadianAboriginalScript = 44,
+ CarianScript = 45,
+ ChakmaScript = 46,
+ ChamScript = 47,
+ CopticScript = 48,
+ CypriotScript = 49,
+ EgyptianHieroglyphsScript = 50,
+ FraserScript = 51,
+ GlagoliticScript = 52,
+ GothicScript = 53,
+ HanScript = 54,
+ HangulScript = 55,
+ HanunooScript = 56,
+ ImperialAramaicScript = 57,
+ InscriptionalPahlaviScript = 58,
+ InscriptionalParthianScript = 59,
+ JavaneseScript = 60,
+ KaithiScript = 61,
+ KatakanaScript = 62,
+ KayahLiScript = 63,
+ KharoshthiScript = 64,
+ LannaScript = 65,
+ LepchaScript = 66,
+ LimbuScript = 67,
+ LinearBScript = 68,
+ LycianScript = 69,
+ LydianScript = 70,
+ MandaeanScript = 71,
+ MeiteiMayekScript = 72,
+ MeroiticScript = 73,
+ MeroiticCursiveScript = 74,
+ NkoScript = 75,
+ NewTaiLueScript = 76,
+ OghamScript = 77,
+ OlChikiScript = 78,
+ OldItalicScript = 79,
+ OldPersianScript = 80,
+ OldSouthArabianScript = 81,
+ OrkhonScript = 82,
+ OsmanyaScript = 83,
+ PhagsPaScript = 84,
+ PhoenicianScript = 85,
+ PollardPhoneticScript = 86,
+ RejangScript = 87,
+ RunicScript = 88,
+ SamaritanScript = 89,
+ SaurashtraScript = 90,
+ SharadaScript = 91,
+ ShavianScript = 92,
+ SoraSompengScript = 93,
+ CuneiformScript = 94,
+ SundaneseScript = 95,
+ SylotiNagriScript = 96,
+ TagalogScript = 97,
+ TagbanwaScript = 98,
+ TaiLeScript = 99,
+ TaiVietScript = 100,
+ TakriScript = 101,
+ UgariticScript = 102,
+ BrailleScript = 103,
+ HiraganaScript = 104,
+ CaucasianAlbanianScript = 105,
+ BassaVahScript = 106,
+ DuployanScript = 107,
+ ElbasanScript = 108,
+ GranthaScript = 109,
+ PahawhHmongScript = 110,
+ KhojkiScript = 111,
+ LinearAScript = 112,
+ MahajaniScript = 113,
+ ManichaeanScript = 114,
+ MendeKikakuiScript = 115,
+ ModiScript = 116,
+ MroScript = 117,
+ OldNorthArabianScript = 118,
+ NabataeanScript = 119,
+ PalmyreneScript = 120,
+ PauCinHauScript = 121,
+ OldPermicScript = 122,
+ PsalterPahlaviScript = 123,
+ SiddhamScript = 124,
+ KhudawadiScript = 125,
+ TirhutaScript = 126,
+ VarangKshitiScript = 127,
+ AhomScript = 128,
+ AnatolianHieroglyphsScript = 129,
+ HatranScript = 130,
+ MultaniScript = 131,
+ OldHungarianScript = 132,
+ SignWritingScript = 133,
+ AdlamScript = 134,
+ BhaiksukiScript = 135,
+ MarchenScript = 136,
+ NewaScript = 137,
+ OsageScript = 138,
+ TangutScript = 139,
+ HanWithBopomofoScript = 140,
+ JamoScript = 141,
+
+ SimplifiedChineseScript = SimplifiedHanScript,
+ TraditionalChineseScript = TraditionalHanScript,
+
+ LastScript = JamoScript
+ };
+ enum Country {
+ AnyCountry = 0,
+ Afghanistan = 1,
+ Albania = 2,
+ Algeria = 3,
+ AmericanSamoa = 4,
+ Andorra = 5,
+ Angola = 6,
+ Anguilla = 7,
+ Antarctica = 8,
+ AntiguaAndBarbuda = 9,
+ Argentina = 10,
+ Armenia = 11,
+ Aruba = 12,
+ Australia = 13,
+ Austria = 14,
+ Azerbaijan = 15,
+ Bahamas = 16,
+ Bahrain = 17,
+ Bangladesh = 18,
+ Barbados = 19,
+ Belarus = 20,
+ Belgium = 21,
+ Belize = 22,
+ Benin = 23,
+ Bermuda = 24,
+ Bhutan = 25,
+ Bolivia = 26,
+ BosniaAndHerzegowina = 27,
+ Botswana = 28,
+ BouvetIsland = 29,
+ Brazil = 30,
+ BritishIndianOceanTerritory = 31,
+ Brunei = 32,
+ Bulgaria = 33,
+ BurkinaFaso = 34,
+ Burundi = 35,
+ Cambodia = 36,
+ Cameroon = 37,
+ Canada = 38,
+ CapeVerde = 39,
+ CaymanIslands = 40,
+ CentralAfricanRepublic = 41,
+ Chad = 42,
+ Chile = 43,
+ China = 44,
+ ChristmasIsland = 45,
+ CocosIslands = 46,
+ Colombia = 47,
+ Comoros = 48,
+ CongoKinshasa = 49,
+ CongoBrazzaville = 50,
+ CookIslands = 51,
+ CostaRica = 52,
+ IvoryCoast = 53,
+ Croatia = 54,
+ Cuba = 55,
+ Cyprus = 56,
+ CzechRepublic = 57,
+ Denmark = 58,
+ Djibouti = 59,
+ Dominica = 60,
+ DominicanRepublic = 61,
+ EastTimor = 62,
+ Ecuador = 63,
+ Egypt = 64,
+ ElSalvador = 65,
+ EquatorialGuinea = 66,
+ Eritrea = 67,
+ Estonia = 68,
+ Ethiopia = 69,
+ FalklandIslands = 70,
+ FaroeIslands = 71,
+ Fiji = 72,
+ Finland = 73,
+ France = 74,
+ Guernsey = 75,
+ FrenchGuiana = 76,
+ FrenchPolynesia = 77,
+ FrenchSouthernTerritories = 78,
+ Gabon = 79,
+ Gambia = 80,
+ Georgia = 81,
+ Germany = 82,
+ Ghana = 83,
+ Gibraltar = 84,
+ Greece = 85,
+ Greenland = 86,
+ Grenada = 87,
+ Guadeloupe = 88,
+ Guam = 89,
+ Guatemala = 90,
+ Guinea = 91,
+ GuineaBissau = 92,
+ Guyana = 93,
+ Haiti = 94,
+ HeardAndMcDonaldIslands = 95,
+ Honduras = 96,
+ HongKong = 97,
+ Hungary = 98,
+ Iceland = 99,
+ India = 100,
+ Indonesia = 101,
+ Iran = 102,
+ Iraq = 103,
+ Ireland = 104,
+ Israel = 105,
+ Italy = 106,
+ Jamaica = 107,
+ Japan = 108,
+ Jordan = 109,
+ Kazakhstan = 110,
+ Kenya = 111,
+ Kiribati = 112,
+ NorthKorea = 113,
+ SouthKorea = 114,
+ Kuwait = 115,
+ Kyrgyzstan = 116,
+ Laos = 117,
+ Latvia = 118,
+ Lebanon = 119,
+ Lesotho = 120,
+ Liberia = 121,
+ Libya = 122,
+ Liechtenstein = 123,
+ Lithuania = 124,
+ Luxembourg = 125,
+ Macau = 126,
+ Macedonia = 127,
+ Madagascar = 128,
+ Malawi = 129,
+ Malaysia = 130,
+ Maldives = 131,
+ Mali = 132,
+ Malta = 133,
+ MarshallIslands = 134,
+ Martinique = 135,
+ Mauritania = 136,
+ Mauritius = 137,
+ Mayotte = 138,
+ Mexico = 139,
+ Micronesia = 140,
+ Moldova = 141,
+ Monaco = 142,
+ Mongolia = 143,
+ Montserrat = 144,
+ Morocco = 145,
+ Mozambique = 146,
+ Myanmar = 147,
+ Namibia = 148,
+ NauruCountry = 149,
+ Nepal = 150,
+ Netherlands = 151,
+ CuraSao = 152,
+ NewCaledonia = 153,
+ NewZealand = 154,
+ Nicaragua = 155,
+ Niger = 156,
+ Nigeria = 157,
+ Niue = 158,
+ NorfolkIsland = 159,
+ NorthernMarianaIslands = 160,
+ Norway = 161,
+ Oman = 162,
+ Pakistan = 163,
+ Palau = 164,
+ PalestinianTerritories = 165,
+ Panama = 166,
+ PapuaNewGuinea = 167,
+ Paraguay = 168,
+ Peru = 169,
+ Philippines = 170,
+ Pitcairn = 171,
+ Poland = 172,
+ Portugal = 173,
+ PuertoRico = 174,
+ Qatar = 175,
+ Reunion = 176,
+ Romania = 177,
+ Russia = 178,
+ Rwanda = 179,
+ SaintKittsAndNevis = 180,
+ SaintLucia = 181,
+ SaintVincentAndTheGrenadines = 182,
+ Samoa = 183,
+ SanMarino = 184,
+ SaoTomeAndPrincipe = 185,
+ SaudiArabia = 186,
+ Senegal = 187,
+ Seychelles = 188,
+ SierraLeone = 189,
+ Singapore = 190,
+ Slovakia = 191,
+ Slovenia = 192,
+ SolomonIslands = 193,
+ Somalia = 194,
+ SouthAfrica = 195,
+ SouthGeorgiaAndTheSouthSandwichIslands = 196,
+ Spain = 197,
+ SriLanka = 198,
+ SaintHelena = 199,
+ SaintPierreAndMiquelon = 200,
+ Sudan = 201,
+ Suriname = 202,
+ SvalbardAndJanMayenIslands = 203,
+ Swaziland = 204,
+ Sweden = 205,
+ Switzerland = 206,
+ Syria = 207,
+ Taiwan = 208,
+ Tajikistan = 209,
+ Tanzania = 210,
+ Thailand = 211,
+ Togo = 212,
+ TokelauCountry = 213,
+ Tonga = 214,
+ TrinidadAndTobago = 215,
+ Tunisia = 216,
+ Turkey = 217,
+ Turkmenistan = 218,
+ TurksAndCaicosIslands = 219,
+ TuvaluCountry = 220,
+ Uganda = 221,
+ Ukraine = 222,
+ UnitedArabEmirates = 223,
+ UnitedKingdom = 224,
+ UnitedStates = 225,
+ UnitedStatesMinorOutlyingIslands = 226,
+ Uruguay = 227,
+ Uzbekistan = 228,
+ Vanuatu = 229,
+ VaticanCityState = 230,
+ Venezuela = 231,
+ Vietnam = 232,
+ BritishVirginIslands = 233,
+ UnitedStatesVirginIslands = 234,
+ WallisAndFutunaIslands = 235,
+ WesternSahara = 236,
+ Yemen = 237,
+ CanaryIslands = 238,
+ Zambia = 239,
+ Zimbabwe = 240,
+ ClippertonIsland = 241,
+ Montenegro = 242,
+ Serbia = 243,
+ SaintBarthelemy = 244,
+ SaintMartin = 245,
+ LatinAmerica = 246,
+ AscensionIsland = 247,
+ AlandIslands = 248,
+ DiegoGarcia = 249,
+ CeutaAndMelilla = 250,
+ IsleOfMan = 251,
+ Jersey = 252,
+ TristanDaCunha = 253,
+ SouthSudan = 254,
+ Bonaire = 255,
+ SintMaarten = 256,
+ Kosovo = 257,
+ EuropeanUnion = 258,
+ OutlyingOceania = 259,
+ World = 260,
+ Europe = 261,
+
+ DemocraticRepublicOfCongo = CongoKinshasa,
+ DemocraticRepublicOfKorea = NorthKorea,
+ LatinAmericaAndTheCaribbean = LatinAmerica,
+ PeoplesRepublicOfCongo = CongoBrazzaville,
+ RepublicOfKorea = SouthKorea,
+ RussianFederation = Russia,
+ SyrianArabRepublic = Syria,
+ Tokelau = TokelauCountry,
+ Tuvalu = TuvaluCountry,
+
+ LastCountry = Europe
+ };
+// GENERATED PART ENDS HERE
+
+ Q_ENUM(Language)
+ Q_ENUM(Country)
+ Q_ENUM(Script)
+
+ enum MeasurementSystem {
+ MetricSystem,
+ ImperialUSSystem,
+ ImperialUKSystem,
+ ImperialSystem = ImperialUSSystem // Qt 4 compatibility
+ };
+ Q_ENUM(MeasurementSystem)
+
+ enum FormatType { LongFormat, ShortFormat, NarrowFormat };
+ enum NumberOption {
+ DefaultNumberOptions = 0x0,
+ OmitGroupSeparator = 0x01,
+ RejectGroupSeparator = 0x02,
+ OmitLeadingZeroInExponent = 0x04,
+ RejectLeadingZeroInExponent = 0x08,
+ IncludeTrailingZeroesAfterDot = 0x10,
+ RejectTrailingZeroesAfterDot = 0x20
+ };
+ Q_DECLARE_FLAGS(NumberOptions, NumberOption)
+
+ enum FloatingPointPrecisionOption {
+ FloatingPointShortest = -128
+ };
+
+ enum CurrencySymbolFormat {
+ CurrencyIsoCode,
+ CurrencySymbol,
+ CurrencyDisplayName
+ };
+
+ enum DataSizeFormat {
+ // Single-bit values, for internal use.
+ DataSizeBase1000 = 1, // use factors of 1000 instead of IEC's 1024;
+ DataSizeSIQuantifiers = 2, // use SI quantifiers instead of IEC ones.
+
+ // Flags values for use in API:
+ DataSizeIecFormat = 0, // base 1024, KiB, MiB, GiB, ...
+ DataSizeTraditionalFormat = DataSizeSIQuantifiers, // base 1024, kB, MB, GB, ...
+ DataSizeSIFormat = DataSizeBase1000 | DataSizeSIQuantifiers // base 1000, kB, MB, GB, ...
+ };
+ Q_DECLARE_FLAGS(DataSizeFormats, DataSizeFormat)
+ Q_FLAG(DataSizeFormats)
+
+ QLocale();
+ QLocale(const QString &name);
+ QLocale(Language language, Country country = AnyCountry);
+ QLocale(Language language, Script script, Country country);
+ QLocale(const QLocale &other);
+ QLocale &operator=(QLocale &&other) noexcept { swap(other); return *this; }
+ QLocale &operator=(const QLocale &other);
+ ~QLocale();
+
+ void swap(QLocale &other) noexcept { qSwap(d, other.d); }
+
+ Language language() const;
+ Script script() const;
+ Country country() const;
+ QString name() const;
+
+ QString bcp47Name() const;
+ QString nativeLanguageName() const;
+ QString nativeCountryName() const;
+
+#if QT_STRINGVIEW_LEVEL < 2
+ short toShort(const QString &s, bool *ok = nullptr) const;
+ ushort toUShort(const QString &s, bool *ok = nullptr) const;
+ int toInt(const QString &s, bool *ok = nullptr) const;
+ uint toUInt(const QString &s, bool *ok = nullptr) const;
+ long toLong(const QString &s, bool *ok = nullptr) const;
+ ulong toULong(const QString &s, bool *ok = nullptr) const;
+ qlonglong toLongLong(const QString &s, bool *ok = nullptr) const;
+ qulonglong toULongLong(const QString &s, bool *ok = nullptr) const;
+ float toFloat(const QString &s, bool *ok = nullptr) const;
+ double toDouble(const QString &s, bool *ok = nullptr) const;
+
+ short toShort(const QStringRef &s, bool *ok = nullptr) const;
+ ushort toUShort(const QStringRef &s, bool *ok = nullptr) const;
+ int toInt(const QStringRef &s, bool *ok = nullptr) const;
+ uint toUInt(const QStringRef &s, bool *ok = nullptr) const;
+ long toLong(const QStringRef &s, bool *ok = nullptr) const;
+ ulong toULong(const QStringRef &s, bool *ok = nullptr) const;
+ qlonglong toLongLong(const QStringRef &s, bool *ok = nullptr) const;
+ qulonglong toULongLong(const QStringRef &s, bool *ok = nullptr) const;
+ float toFloat(const QStringRef &s, bool *ok = nullptr) const;
+ double toDouble(const QStringRef &s, bool *ok = nullptr) const;
+#endif
+
+ short toShort(QStringView s, bool *ok = nullptr) const;
+ ushort toUShort(QStringView s, bool *ok = nullptr) const;
+ int toInt(QStringView s, bool *ok = nullptr) const;
+ uint toUInt(QStringView s, bool *ok = nullptr) const;
+ long toLong(QStringView s, bool *ok = nullptr) const;
+ ulong toULong(QStringView s, bool *ok = nullptr) const;
+ qlonglong toLongLong(QStringView s, bool *ok = nullptr) const;
+ qulonglong toULongLong(QStringView s, bool *ok = nullptr) const;
+ float toFloat(QStringView s, bool *ok = nullptr) const;
+ double toDouble(QStringView s, bool *ok = nullptr) const;
+
+ QString toString(qlonglong i) const;
+ QString toString(qulonglong i) const;
+ inline QString toString(long i) const;
+ inline QString toString(ulong i) const;
+ inline QString toString(short i) const;
+ inline QString toString(ushort i) const;
+ inline QString toString(int i) const;
+ inline QString toString(uint i) const;
+ QString toString(double i, char f = 'g', int prec = 6) const;
+ inline QString toString(float i, char f = 'g', int prec = 6) const;
+
+#if QT_STRINGVIEW_LEVEL < 2
+ QString toString(const QDate &date, const QString &formatStr) const;
+ QString toString(const QTime &time, const QString &formatStr) const;
+ QString toString(const QDateTime &dateTime, const QString &format) const;
+#endif
+ QString toString(const QDate &date, QStringView formatStr) const;
+ QString toString(const QTime &time, QStringView formatStr) const;
+ QString toString(const QDateTime &dateTime, QStringView format) const;
+ QString toString(const QDate &date, FormatType format = LongFormat) const;
+ QString toString(const QTime &time, FormatType format = LongFormat) const;
+ QString toString(const QDateTime &dateTime, FormatType format = LongFormat) const;
+
+ QString dateFormat(FormatType format = LongFormat) const;
+ QString timeFormat(FormatType format = LongFormat) const;
+ QString dateTimeFormat(FormatType format = LongFormat) const;
+#if QT_CONFIG(datestring)
+ QDate toDate(const QString &string, FormatType = LongFormat) const;
+ QTime toTime(const QString &string, FormatType = LongFormat) const;
+ QDateTime toDateTime(const QString &string, FormatType format = LongFormat) const;
+ QDate toDate(const QString &string, const QString &format) const;
+ QTime toTime(const QString &string, const QString &format) const;
+ QDateTime toDateTime(const QString &string, const QString &format) const;
+#endif
+
+ // ### Qt 5: We need to return QString from these function since
+ // unicode data contains several characters for these fields.
+ QChar decimalPoint() const;
+ QChar groupSeparator() const;
+ QChar percent() const;
+ QChar zeroDigit() const;
+ QChar negativeSign() const;
+ QChar positiveSign() const;
+ QChar exponential() const;
+
+ QString monthName(int, FormatType format = LongFormat) const;
+ QString standaloneMonthName(int, FormatType format = LongFormat) const;
+ QString dayName(int, FormatType format = LongFormat) const;
+ QString standaloneDayName(int, FormatType format = LongFormat) const;
+
+ Qt::DayOfWeek firstDayOfWeek() const;
+ QList<Qt::DayOfWeek> weekdays() const;
+
+ QString amText() const;
+ QString pmText() const;
+
+ MeasurementSystem measurementSystem() const;
+ QLocale collation() const;
+ Qt::LayoutDirection textDirection() const;
+
+ QString toUpper(const QString &str) const;
+ QString toLower(const QString &str) const;
+
+ QString currencySymbol(CurrencySymbolFormat = CurrencySymbol) const;
+ QString toCurrencyString(qlonglong, const QString &symbol = QString()) const;
+ QString toCurrencyString(qulonglong, const QString &symbol = QString()) const;
+ inline QString toCurrencyString(short, const QString &symbol = QString()) const;
+ inline QString toCurrencyString(ushort, const QString &symbol = QString()) const;
+ inline QString toCurrencyString(int, const QString &symbol = QString()) const;
+ inline QString toCurrencyString(uint, const QString &symbol = QString()) const;
+#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
+ QString toCurrencyString(double, const QString &symbol = QString(), int precision = -1) const;
+ inline QString toCurrencyString(float i, const QString &symbol = QString(), int precision = -1) const
+ { return toCurrencyString(double(i), symbol, precision); }
+#else
+ QString toCurrencyString(double, const QString &symbol = QString()) const;
+ QString toCurrencyString(double, const QString &symbol, int precision) const;
+ inline QString toCurrencyString(float i, const QString &symbol = QString()) const
+ { return toCurrencyString(double(i), symbol); }
+ inline QString toCurrencyString(float i, const QString &symbol, int precision) const
+ { return toCurrencyString(double(i), symbol, precision); }
+#endif
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ QString formattedDataSize(qint64 bytes, int precision = 2, DataSizeFormats format = DataSizeIecFormat);
+#endif
+ QString formattedDataSize(qint64 bytes, int precision = 2, DataSizeFormats format = DataSizeIecFormat) const;
+
+ QStringList uiLanguages() const;
+
+ bool operator==(const QLocale &other) const;
+ bool operator!=(const QLocale &other) const;
+
+ static QString languageToString(Language language);
+ static QString countryToString(Country country);
+ static QString scriptToString(Script script);
+ static void setDefault(const QLocale &locale);
+
+ static QLocale c() { return QLocale(C); }
+ static QLocale system();
+
+ static QList<QLocale> matchingLocales(QLocale::Language language, QLocale::Script script, QLocale::Country country);
+ static QList<Country> countriesForLanguage(Language lang);
+
+ void setNumberOptions(NumberOptions options);
+ NumberOptions numberOptions() const;
+
+ enum QuotationStyle { StandardQuotation, AlternateQuotation };
+ QString quoteString(const QString &str, QuotationStyle style = StandardQuotation) const;
+ QString quoteString(const QStringRef &str, QuotationStyle style = StandardQuotation) const;
+
+ QString createSeparatedList(const QStringList &strl) const;
+
+private:
+ QLocale(QLocalePrivate &dd);
+ friend class QLocalePrivate;
+ friend class QSystemLocale;
+ friend Q_CORE_EXPORT uint qHash(const QLocale &key, uint seed) noexcept;
+
+ QSharedDataPointer<QLocalePrivate> d;
+};
+Q_DECLARE_SHARED(QLocale)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QLocale::NumberOptions)
+
+inline QString QLocale::toString(long i) const
+ { return toString(qlonglong(i)); }
+inline QString QLocale::toString(ulong i) const
+ { return toString(qulonglong(i)); }
+inline QString QLocale::toString(short i) const
+ { return toString(qlonglong(i)); }
+inline QString QLocale::toString(ushort i) const
+ { return toString(qulonglong(i)); }
+inline QString QLocale::toString(int i) const
+ { return toString(qlonglong(i)); }
+inline QString QLocale::toString(uint i) const
+ { return toString(qulonglong(i)); }
+inline QString QLocale::toString(float i, char f, int prec) const
+ { return toString(double(i), f, prec); }
+
+inline QString QLocale::toCurrencyString(short i, const QString &symbol) const
+ { return toCurrencyString(qlonglong(i), symbol); }
+inline QString QLocale::toCurrencyString(ushort i, const QString &symbol) const
+ { return toCurrencyString(qulonglong(i), symbol); }
+inline QString QLocale::toCurrencyString(int i, const QString &symbol) const
+{ return toCurrencyString(qlonglong(i), symbol); }
+inline QString QLocale::toCurrencyString(uint i, const QString &symbol) const
+{ return toCurrencyString(qulonglong(i), symbol); }
+
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QLocale &);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QLocale &);
+#endif
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_CORE_EXPORT QDebug operator<<(QDebug, const QLocale &);
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QLOCALE_H
diff --git a/src/corelib/text/qlocale.qdoc b/src/corelib/text/qlocale.qdoc
new file mode 100644
index 0000000000..426cb9dbeb
--- /dev/null
+++ b/src/corelib/text/qlocale.qdoc
@@ -0,0 +1,1278 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QLocale
+ \inmodule QtCore
+ \brief The QLocale class converts between numbers and their
+ string representations in various languages.
+
+ \reentrant
+ \ingroup i18n
+ \ingroup string-processing
+ \ingroup shared
+
+
+ QLocale is initialized with a language/country pair in its
+ constructor and offers number-to-string and string-to-number
+ conversion functions similar to those in QString.
+
+ Example:
+
+ \snippet code/src_corelib_tools_qlocale.cpp 0
+
+ QLocale supports the concept of a default locale, which is
+ determined from the system's locale settings at application
+ startup. The default locale can be changed by calling the
+ static member setDefault(). Setting the default locale has the
+ following effects:
+
+ \list
+ \li If a QLocale object is constructed with the default constructor,
+ it will use the default locale's settings.
+ \li QString::toInt(), QString::toDouble(), etc., interpret the
+ string according to the default locale. If this fails, it
+ falls back on the "C" locale.
+ \li QString::arg() uses the default locale to format a number when
+ its position specifier in the format string contains an 'L',
+ e.g. "%L1".
+ \endlist
+
+ The following example illustrates how to use QLocale directly:
+
+ \snippet code/src_corelib_tools_qlocale.cpp 1
+
+ When a language/country pair is specified in the constructor, one
+ of three things can happen:
+
+ \list
+ \li If the language/country pair is found in the database, it is used.
+ \li If the language is found but the country is not, or if the country
+ is \c AnyCountry, the language is used with the most
+ appropriate available country (for example, Germany for German),
+ \li If neither the language nor the country are found, QLocale
+ defaults to the default locale (see setDefault()).
+ \endlist
+
+ Use language() and country() to determine the actual language and
+ country values used.
+
+ An alternative method for constructing a QLocale object is by
+ specifying the locale name.
+
+ \snippet code/src_corelib_tools_qlocale.cpp 2
+
+ This constructor converts the locale name to a language/country
+ pair; it does not use the system locale database.
+
+ \note For the current keyboard input locale take a look at
+ QInputMethod::locale().
+
+ QLocale's data is based on Common Locale Data Repository v35.1.
+
+ \sa QString::arg(), QString::toInt(), QString::toDouble(),
+ QInputMethod::locale()
+*/
+
+/*!
+ \enum QLocale::Language
+
+ This enumerated type is used to specify a language.
+
+ \value AnyLanguage
+ \value C A simplified English locale; see QLocale::c()
+
+ \value Abkhazian
+ \value Afan Obsolete, please use Oromo
+ \value Afar
+ \value Afrikaans
+ \value Aghem
+ \value Ahom Since Qt 5.7
+ \value Akan
+ \value Akkadian Since Qt 5.1
+ \value Akoose Since Qt 5.3
+ \value Albanian
+ \value AmericanSignLanguage Since Qt 5.7
+ \value Amharic
+ \value AncientEgyptian Since Qt 5.1
+ \value AncientGreek Since Qt 5.1
+ \value AncientNorthArabian Since Qt 5.5
+ \value Arabic
+ \value Aragonese Since Qt 5.1
+ \value Aramaic Since Qt 5.1
+ \value ArdhamagadhiPrakrit Since Qt 5.7
+ \value Armenian
+ \value Assamese
+ \value Asturian
+ \value Asu
+ \value Atsam
+ \value Avaric
+ \value Avestan
+ \value Aymara
+ \value Azerbaijani
+ \value Bafia
+ \value Balinese Since Qt 5.1
+ \value Bambara
+ \value Bamun Since Qt 5.1
+ \value Basaa
+ \value Bashkir
+ \value Basque
+ \value Bassa Since Qt 5.5
+ \value BatakToba Since Qt 5.1
+ \value Belarusian
+ \value Bemba
+ \value Bena
+ \value Bengali
+ \value Bhojpuri Since Qt 5.7
+ \value Bhutani Obsolete, please use Dzongkha
+ \value Bihari
+ \value Bislama
+ \value Blin
+ \value Bodo
+ \value Bosnian
+ \value Breton
+ \value Buginese Since Qt 5.1
+ \value Buhid Since Qt 5.1
+ \value Bulgarian
+ \value Burmese
+ \value Byelorussian Obsolete, please use Belarusian
+ \value Cambodian Obsolete, please use Khmer
+ \value Cantonese Since Qt 5.7
+ \value Carian Since Qt 5.1
+ \value Catalan
+ \value Cebuano Since Qt 5.14
+ \value CentralKurdish Since Qt 5.5
+ \value CentralMoroccoTamazight
+ \value Chakma Since Qt 5.1
+ \value Chamorro
+ \value Chechen
+ \value Cherokee
+ \value Chewa Obsolete, please use Nyanja
+ \value Chiga
+ \value Chinese
+ \value Church
+ \value Chuvash
+ \value ClassicalMandaic Since Qt 5.1
+ \value Colognian
+ \value CongoSwahili
+ \value Coptic Since Qt 5.1
+ \value Cornish
+ \value Corsican
+ \value Cree
+ \value Croatian
+ \value Czech
+ \value Danish
+ \value Divehi
+ \value Dogri Since Qt 5.1
+ \value Duala
+ \value Dutch
+ \value Dzongkha
+ \value EasternCham Since Qt 5.1
+ \value EasternKayah Since Qt 5.1
+ \value Embu
+ \value English
+ \value Erzya Since Qt 5.14
+ \value Esperanto
+ \value Estonian
+ \value Etruscan Since Qt 5.1
+ \value Ewe
+ \value Ewondo
+ \value Faroese
+ \value Fijian
+ \value Filipino
+ \value Finnish
+ \value French
+ \value Frisian same as WesternFrisian
+ \value Friulian
+ \value Fulah
+ \value Ga
+ \value Gaelic
+ \value Galician
+ \value Ganda
+ \value Geez
+ \value Georgian
+ \value German
+ \value Gothic Since Qt 5.1
+ \value Greek
+ \value Greenlandic
+ \value Guarani
+ \value Gujarati
+ \value Gusii
+ \value Haitian
+ \value Hanunoo Since Qt 5.1
+ \value Hausa
+ \value Hawaiian
+ \value Hebrew
+ \value Herero
+ \value HieroglyphicLuwian Since Qt 5.7
+ \value Hindi
+ \value HiriMotu
+ \value HmongNjua Since Qt 5.5
+ \value Ho Since Qt 5.5
+ \value Hungarian
+ \value Icelandic
+ \value Ido Since Qt 5.12
+ \value Igbo
+ \value InariSami Since Qt 5.5
+ \value Indonesian
+ \value Ingush Since Qt 5.1
+ \value Interlingua
+ \value Interlingue
+ \value Inuktitut
+ \value Inupiak
+ \value Irish
+ \value Italian
+ \value Japanese
+ \value Javanese
+ \value Jju
+ \value JolaFonyi
+ \value Kabuverdianu
+ \value Kabyle
+ \value Kako
+ \value Kalenjin
+ \value Kamba
+ \value Kannada
+ \value Kanuri
+ \value Kashmiri
+ \value Kazakh
+ \value Kenyang Since Qt 5.5
+ \value Khmer
+ \value Kiche Since Qt 5.5
+ \value Kikuyu
+ \value Kinyarwanda
+ \value Kirghiz
+ \value Komi
+ \value Kongo
+ \value Konkani
+ \value Korean
+ \value Koro
+ \value KoyraboroSenni
+ \value KoyraChiini
+ \value Kpelle
+ \value Kurdish
+ \value Kurundi Obsolete, please use Rundi
+ \value Kwanyama
+ \value Kwasio
+ \value Lakota Since Qt 5.3
+ \value Langi
+ \value Lao
+ \value LargeFloweryMiao Since Qt 5.1
+ \value Latin
+ \value Latvian
+ \value Lepcha Since Qt 5.1
+ \value Lezghian Since Qt 5.5
+ \value Limburgish
+ \value Limbu Since Qt 5.1
+ \value LinearA Since Qt 5.5
+ \value Lingala
+ \value Lisu Since Qt 5.1
+ \value LiteraryChinese Since Qt 5.7
+ \value Lithuanian
+ \value Lojban Since Qt 5.12
+ \value LowerSorbian Since Qt 5.5
+ \value LowGerman
+ \value LubaKatanga
+ \value LuleSami Since Qt 5.5
+ \value Luo
+ \value Lu Since Qt 5.1
+ \value Luxembourgish
+ \value Luyia
+ \value Lycian Since Qt 5.1
+ \value Lydian Since Qt 5.1
+ \value Macedonian
+ \value Machame
+ \value Maithili Since Qt 5.5
+ \value MakhuwaMeetto
+ \value Makonde
+ \value Malagasy
+ \value Malay
+ \value Malayalam
+ \value Maltese
+ \value Mandingo Since Qt 5.1
+ \value ManichaeanMiddlePersian Since Qt 5.5
+ \value Manipuri Since Qt 5.1
+ \value Manx
+ \value Maori
+ \value Mapuche Since Qt 5.5
+ \value Marathi
+ \value Marshallese
+ \value Masai
+ \value Mazanderani Since Qt 5.7
+ \value Mende Since Qt 5.5
+ \value Meroitic Since Qt 5.1
+ \value Meru
+ \value Meta
+ \value Mohawk Since Qt 5.5
+ \value Moldavian Obsolete, please use Romanian
+ \value Mongolian
+ \value Mono Since Qt 5.5
+ \value Morisyen
+ \value Mru Since Qt 5.7
+ \value Mundang
+ \value Nama
+ \value NauruLanguage
+ \value Navaho
+ \value Ndonga
+ \value Nepali
+ \value Newari Since Qt 5.7
+ \value Ngiemboon
+ \value Ngomba
+ \value Nko Since Qt 5.5
+ \value NorthernLuri Since Qt 5.7
+ \value NorthernSami
+ \value NorthernSotho
+ \value NorthernThai Since Qt 5.1
+ \value NorthNdebele
+ \value NorwegianBokmal same as Norwegian
+ \value NorwegianNynorsk
+ \value Norwegian same as NorwegianBokmal
+ \value Nuer
+ \value Nyanja
+ \value Nyankole
+ \value Occitan
+ \value Ojibwa
+ \value OldIrish Since Qt 5.1
+ \value OldNorse Since Qt 5.1
+ \value OldPersian Since Qt 5.1
+ \value OldTurkish Since Qt 5.1
+ \value Oriya
+ \value Oromo
+ \value Osage Since Qt 5.7
+ \value Ossetic
+ \value Pahlavi Since Qt 5.1
+ \value Palauan Since Qt 5.7
+ \value Pali
+ \value Papiamento Since Qt 5.7
+ \value Parthian Since Qt 5.1
+ \value Pashto
+ \value Persian
+ \value Phoenician Since Qt 5.1
+ \value Polish
+ \value Portuguese
+ \value PrakritLanguage Since Qt 5.1
+ \value Prussian Since Qt 5.5
+ \value Punjabi
+ \value Quechua
+ \value Rejang Since Qt 5.1
+ \value RhaetoRomance Obsolete, please use Romansh
+ \value Romanian
+ \value Romansh
+ \value Rombo
+ \value Rundi
+ \value Russian
+ \value Rwa
+ \value Sabaean Since Qt 5.1
+ \value Saho
+ \value Sakha
+ \value Samaritan Since Qt 5.1
+ \value Samburu
+ \value Samoan
+ \value Sango
+ \value Sangu
+ \value Sanskrit
+ \value Santali Since Qt 5.1
+ \value Saraiki Since Qt 5.7
+ \value Sardinian
+ \value Saurashtra Since Qt 5.1
+ \value Sena
+ \value Serbian
+ \value SerboCroatian Obsolete, please use Serbian
+ \value Shambala
+ \value Shona
+ \value SichuanYi
+ \value Sicilian Since Qt 5.12
+ \value Sidamo
+ \value Sindhi
+ \value Sinhala
+ \value SkoltSami Since Qt 5.5
+ \value Slovak
+ \value Slovenian
+ \value Soga
+ \value Somali
+ \value Sora Since Qt 5.1
+ \value SouthernKurdish Since Qt 5.12
+ \value SouthernSami Since Qt 5.5
+ \value SouthernSotho
+ \value SouthNdebele
+ \value Spanish
+ \value StandardMoroccanTamazight Since Qt 5.3
+ \value Sundanese
+ \value Swahili
+ \value Swati
+ \value Swedish
+ \value SwissGerman
+ \value Sylheti Since Qt 5.1
+ \value Syriac
+ \value Tachelhit
+ \value Tagalog Obsolete, please use Filipino
+ \value Tagbanwa Since Qt 5.1
+ \value Tahitian
+ \value TaiDam Since Qt 5.1
+ \value TaiNua Since Qt 5.1
+ \value Taita
+ \value Tajik
+ \value Tamil
+ \value Tangut Since Qt 5.7
+ \value Taroko
+ \value Tasawaq
+ \value Tatar
+ \value TedimChin Since Qt 5.5
+ \value Telugu
+ \value Teso
+ \value Thai
+ \value Tibetan
+ \value Tigre
+ \value Tigrinya
+ \value TokelauLanguage Since Qt 5.7
+ \value TokPisin Since Qt 5.7
+ \value Tongan
+ \value Tsonga
+ \value Tswana
+ \value Turkish
+ \value Turkmen
+ \value TuvaluLanguage Since Qt 5.7
+ \value Twi Obsolete, please use Akan
+ \value Tyap
+ \value Ugaritic Since Qt 5.1
+ \value Uighur
+ \value Uigur Obsolete, please use Uighur
+ \value Ukrainian
+ \value UncodedLanguages Since Qt 5.7
+ \value UpperSorbian Since Qt 5.5
+ \value Urdu
+ \value Uzbek
+ \value Vai
+ \value Venda
+ \value Vietnamese
+ \value Volapuk
+ \value Vunjo
+ \value Walamo
+ \value Walloon
+ \value Walser
+ \value Warlpiri Since Qt 5.5
+ \value Welsh
+ \value WesternBalochi Since Qt 5.12
+ \value WesternFrisian same as Frisian
+ \value Wolof
+ \value Xhosa
+ \value Yangben
+ \value Yiddish
+ \value Yoruba
+ \value Zarma
+ \value Zhuang
+ \value Zulu
+
+ \omitvalue LastLanguage
+
+ \sa language(), languageToString()
+*/
+
+/*!
+ \enum QLocale::Country
+
+ This enumerated type is used to specify a country.
+
+ \value AnyCountry
+
+ \value Afghanistan
+ \value AlandIslands
+ \value Albania
+ \value Algeria
+ \value AmericanSamoa
+ \value Andorra
+ \value Angola
+ \value Anguilla
+ \value Antarctica
+ \value AntiguaAndBarbuda
+ \value Argentina
+ \value Armenia
+ \value Aruba
+ \value AscensionIsland
+ \value Australia
+ \value Austria
+ \value Azerbaijan
+ \value Bahamas
+ \value Bahrain
+ \value Bangladesh
+ \value Barbados
+ \value Belarus
+ \value Belgium
+ \value Belize
+ \value Benin
+ \value Bermuda
+ \value Bhutan
+ \value Bolivia
+ \value Bonaire
+ \value BosniaAndHerzegowina
+ \value Botswana
+ \value BouvetIsland
+ \value Brazil
+ \value BritishIndianOceanTerritory
+ \value BritishVirginIslands
+ \value Brunei
+ \value Bulgaria
+ \value BurkinaFaso
+ \value Burundi
+ \value Cambodia
+ \value Cameroon
+ \value Canada
+ \value CanaryIslands
+ \value CapeVerde
+ \value CaymanIslands
+ \value CentralAfricanRepublic
+ \value CeutaAndMelilla
+ \value Chad
+ \value Chile
+ \value China
+ \value ChristmasIsland
+ \value ClippertonIsland
+ \value CocosIslands
+ \value Colombia
+ \value Comoros
+ \value CongoBrazzaville
+ \value CongoKinshasa
+ \value CookIslands
+ \value CostaRica
+ \value Croatia
+ \value Cuba
+ \value CuraSao
+ \value Cyprus
+ \value CzechRepublic
+ \value DemocraticRepublicOfCongo Obsolete, please use CongoKinshasa
+ \value DemocraticRepublicOfKorea Obsolete, please use NorthKorea
+ \value Denmark
+ \value DiegoGarcia
+ \value Djibouti
+ \value Dominica
+ \value DominicanRepublic
+ \value EastTimor
+ \value Ecuador
+ \value Egypt
+ \value ElSalvador
+ \value EquatorialGuinea
+ \value Eritrea
+ \value Estonia
+ \value Ethiopia
+ \value EuropeanUnion Since Qt 5.7
+ \value Europe Since Qt 5.12
+ \value FalklandIslands
+ \value FaroeIslands
+ \value Fiji
+ \value Finland
+ \value France
+ \value FrenchGuiana
+ \value FrenchPolynesia
+ \value FrenchSouthernTerritories
+ \value Gabon
+ \value Gambia
+ \value Georgia
+ \value Germany
+ \value Ghana
+ \value Gibraltar
+ \value Greece
+ \value Greenland
+ \value Grenada
+ \value Guadeloupe
+ \value Guam
+ \value Guatemala
+ \value Guernsey
+ \value Guinea
+ \value GuineaBissau
+ \value Guyana
+ \value Haiti
+ \value HeardAndMcDonaldIslands
+ \value Honduras
+ \value HongKong
+ \value Hungary
+ \value Iceland
+ \value India
+ \value Indonesia
+ \value Iran
+ \value Iraq
+ \value Ireland
+ \value IsleOfMan
+ \value Israel
+ \value Italy
+ \value IvoryCoast
+ \value Jamaica
+ \value Japan
+ \value Jersey
+ \value Jordan
+ \value Kazakhstan
+ \value Kenya
+ \value Kiribati
+ \value Kosovo Since Qt 5.2
+ \value Kuwait
+ \value Kyrgyzstan
+ \value Laos
+ \value LatinAmerica
+ \value LatinAmericaAndTheCaribbean Obsolete, please use LatinAmerica
+ \value Latvia
+ \value Lebanon
+ \value Lesotho
+ \value Liberia
+ \value Libya
+ \value Liechtenstein
+ \value Lithuania
+ \value Luxembourg
+ \value Macau
+ \value Macedonia
+ \value Madagascar
+ \value Malawi
+ \value Malaysia
+ \value Maldives
+ \value Mali
+ \value Malta
+ \value MarshallIslands
+ \value Martinique
+ \value Mauritania
+ \value Mauritius
+ \value Mayotte
+ \value Mexico
+ \value Micronesia
+ \value Moldova
+ \value Monaco
+ \value Mongolia
+ \value Montenegro
+ \value Montserrat
+ \value Morocco
+ \value Mozambique
+ \value Myanmar
+ \value Namibia
+ \value NauruCountry
+ \value Nepal
+ \value Netherlands
+ \value NewCaledonia
+ \value NewZealand
+ \value Nicaragua
+ \value Niger
+ \value Nigeria
+ \value Niue
+ \value NorfolkIsland
+ \value NorthernMarianaIslands
+ \value NorthKorea
+ \value Norway
+ \value Oman
+ \value OutlyingOceania Since Qt 5.7
+ \value Pakistan
+ \value Palau
+ \value PalestinianTerritories
+ \value Panama
+ \value PapuaNewGuinea
+ \value Paraguay
+ \value PeoplesRepublicOfCongo Obsolete, please use CongoBrazzaville
+ \value Peru
+ \value Philippines
+ \value Pitcairn
+ \value Poland
+ \value Portugal
+ \value PuertoRico
+ \value Qatar
+ \value RepublicOfKorea Obsolete, please use SouthKorea
+ \value Reunion
+ \value Romania
+ \value RussianFederation same as Russia
+ \value Russia same as RussianFederation
+ \value Rwanda
+ \value SaintBarthelemy
+ \value SaintHelena
+ \value SaintKittsAndNevis
+ \value SaintLucia
+ \value SaintMartin
+ \value SaintPierreAndMiquelon
+ \value SaintVincentAndTheGrenadines
+ \value Samoa
+ \value SanMarino
+ \value SaoTomeAndPrincipe
+ \value SaudiArabia
+ \value Senegal
+ \value Serbia
+ \value Seychelles
+ \value SierraLeone
+ \value Singapore
+ \value SintMaarten
+ \value Slovakia
+ \value Slovenia
+ \value SolomonIslands
+ \value Somalia
+ \value SouthAfrica
+ \value SouthGeorgiaAndTheSouthSandwichIslands
+ \value SouthKorea
+ \value SouthSudan
+ \value Spain
+ \value SriLanka
+ \value Sudan
+ \value Suriname
+ \value SvalbardAndJanMayenIslands
+ \value Swaziland
+ \value Sweden
+ \value Switzerland
+ \value Syria
+ \value SyrianArabRepublic Obsolete, please use Syria
+ \value Taiwan
+ \value Tajikistan
+ \value Tanzania
+ \value Thailand
+ \value Togo
+ \value TokelauCountry
+ \value Tokelau Obsolete, please use TokelauCountry
+ \value Tonga
+ \value TrinidadAndTobago
+ \value TristanDaCunha
+ \value Tunisia
+ \value Turkey
+ \value Turkmenistan
+ \value TurksAndCaicosIslands
+ \value TuvaluCountry
+ \value Tuvalu Obsolete, please use TuvaluCountry
+ \value Uganda
+ \value Ukraine
+ \value UnitedArabEmirates
+ \value UnitedKingdom
+ \value UnitedStates
+ \value UnitedStatesMinorOutlyingIslands
+ \value UnitedStatesVirginIslands
+ \value Uruguay
+ \value Uzbekistan
+ \value Vanuatu
+ \value VaticanCityState
+ \value Venezuela
+ \value Vietnam
+ \value WallisAndFutunaIslands
+ \value WesternSahara
+ \value World Since Qt 5.12
+ \value Yemen
+ \value Zambia
+ \value Zimbabwe
+
+ \omitvalue LastCountry
+
+ \sa country(), countryToString()
+*/
+
+/*!
+ \enum QLocale::Script
+
+ This enumerated type is used to specify a script.
+
+ \value AnyScript
+
+ \value AdlamScript Since Qt 5.7
+ \value AhomScript Since Qt 5.7
+ \value AnatolianHieroglyphsScript Since Qt 5.7
+ \value ArabicScript
+ \value ArmenianScript
+ \value AvestanScript Since Qt 5.1
+ \value BalineseScript Since Qt 5.1
+ \value BamumScript Since Qt 5.1
+ \value BassaVahScript Since Qt 5.5
+ \value BatakScript Since Qt 5.1
+ \value BengaliScript
+ \value BhaiksukiScript Since Qt 5.7
+ \value BopomofoScript Since Qt 5.1
+ \value BrahmiScript Since Qt 5.1
+ \value BrailleScript Since Qt 5.1
+ \value BugineseScript Since Qt 5.1
+ \value BuhidScript Since Qt 5.1
+ \value CanadianAboriginalScript Since Qt 5.1
+ \value CarianScript Since Qt 5.1
+ \value CaucasianAlbanianScript Since Qt 5.5
+ \value ChakmaScript Since Qt 5.1
+ \value ChamScript Since Qt 5.1
+ \value CherokeeScript
+ \value CopticScript Since Qt 5.1
+ \value CuneiformScript Since Qt 5.1
+ \value CypriotScript Since Qt 5.1
+ \value CyrillicScript
+ \value DeseretScript Since Qt 5.1
+ \value DevanagariScript
+ \value DuployanScript Since Qt 5.5
+ \value EgyptianHieroglyphsScript Since Qt 5.1
+ \value ElbasanScript Since Qt 5.5
+ \value EthiopicScript
+ \value FraserScript Since Qt 5.1
+ \value GeorgianScript
+ \value GlagoliticScript Since Qt 5.1
+ \value GothicScript Since Qt 5.1
+ \value GranthaScript Since Qt 5.5
+ \value GreekScript
+ \value GujaratiScript
+ \value GurmukhiScript
+ \value HangulScript Since Qt 5.1
+ \value HanScript Since Qt 5.1
+ \value HanunooScript Since Qt 5.1
+ \value HanWithBopomofoScript Since Qt 5.7
+ \value HatranScript Since Qt 5.7
+ \value HebrewScript
+ \value HiraganaScript Since Qt 5.1
+ \value ImperialAramaicScript Since Qt 5.1
+ \value InscriptionalPahlaviScript Since Qt 5.1
+ \value InscriptionalParthianScript Since Qt 5.1
+ \value JamoScript Since Qt 5.7
+ \value JapaneseScript
+ \value JavaneseScript Since Qt 5.1
+ \value KaithiScript Since Qt 5.1
+ \value KannadaScript
+ \value KatakanaScript Since Qt 5.1
+ \value KayahLiScript Since Qt 5.1
+ \value KharoshthiScript Since Qt 5.1
+ \value KhmerScript Since Qt 5.1
+ \value KhojkiScript Since Qt 5.5
+ \value KhudawadiScript Since Qt 5.5
+ \value KoreanScript
+ \value LannaScript Since Qt 5.1
+ \value LaoScript
+ \value LatinScript
+ \value LepchaScript Since Qt 5.1
+ \value LimbuScript Since Qt 5.1
+ \value LinearAScript Since Qt 5.5
+ \value LinearBScript Since Qt 5.1
+ \value LycianScript Since Qt 5.1
+ \value LydianScript Since Qt 5.1
+ \value MahajaniScript Since Qt 5.5
+ \value MalayalamScript
+ \value MandaeanScript Since Qt 5.1
+ \value ManichaeanScript Since Qt 5.5
+ \value MarchenScript Since Qt 5.7
+ \value MeiteiMayekScript Since Qt 5.1
+ \value MendeKikakuiScript Since Qt 5.5
+ \value MeroiticCursiveScript Since Qt 5.1
+ \value MeroiticScript Since Qt 5.1
+ \value ModiScript Since Qt 5.5
+ \value MongolianScript
+ \value MroScript Since Qt 5.5
+ \value MultaniScript Since Qt 5.7
+ \value MyanmarScript
+ \value NabataeanScript Since Qt 5.5
+ \value NewaScript Since Qt 5.7
+ \value NewTaiLueScript Since Qt 5.1
+ \value NkoScript Since Qt 5.1
+ \value OghamScript Since Qt 5.1
+ \value OlChikiScript Since Qt 5.1
+ \value OldHungarianScript Since Qt 5.7
+ \value OldItalicScript Since Qt 5.1
+ \value OldNorthArabianScript Since Qt 5.5
+ \value OldPermicScript Since Qt 5.5
+ \value OldPersianScript Since Qt 5.1
+ \value OldSouthArabianScript Since Qt 5.1
+ \value OriyaScript
+ \value OrkhonScript Since Qt 5.1
+ \value OsageScript Since Qt 5.7
+ \value OsmanyaScript Since Qt 5.1
+ \value PahawhHmongScript Since Qt 5.5
+ \value PalmyreneScript Since Qt 5.5
+ \value PauCinHauScript Since Qt 5.5
+ \value PhagsPaScript Since Qt 5.1
+ \value PhoenicianScript Since Qt 5.1
+ \value PollardPhoneticScript Since Qt 5.1
+ \value PsalterPahlaviScript Since Qt 5.5
+ \value RejangScript Since Qt 5.1
+ \value RunicScript Since Qt 5.1
+ \value SamaritanScript Since Qt 5.1
+ \value SaurashtraScript Since Qt 5.1
+ \value SharadaScript Since Qt 5.1
+ \value ShavianScript Since Qt 5.1
+ \value SiddhamScript Since Qt 5.5
+ \value SignWritingScript Since Qt 5.7
+ \value SimplifiedChineseScript same as SimplifiedHanScript
+ \value SimplifiedHanScript same as SimplifiedChineseScript
+ \value SinhalaScript
+ \value SoraSompengScript Since Qt 5.1
+ \value SundaneseScript Since Qt 5.1
+ \value SylotiNagriScript Since Qt 5.1
+ \value SyriacScript
+ \value TagalogScript Since Qt 5.1
+ \value TagbanwaScript Since Qt 5.1
+ \value TaiLeScript Since Qt 5.1
+ \value TaiVietScript Since Qt 5.1
+ \value TakriScript Since Qt 5.1
+ \value TamilScript
+ \value TangutScript Since Qt 5.7
+ \value TeluguScript
+ \value ThaanaScript
+ \value ThaiScript
+ \value TibetanScript
+ \value TifinaghScript
+ \value TirhutaScript Since Qt 5.5
+ \value TraditionalChineseScript same as TraditionalHanScript
+ \value TraditionalHanScript same as TraditionalChineseScript
+ \value UgariticScript Since Qt 5.1
+ \value VaiScript
+ \value VarangKshitiScript Since Qt 5.5
+ \value YiScript
+
+ \omitvalue LastScript
+
+ \sa script(), scriptToString(), languageToString()
+*/
+
+/*!
+ \enum QLocale::FormatType
+
+ This enum describes the types of format that can be used when
+ converting QDate and QTime objects to strings.
+
+ \value LongFormat The long version of day and month names; for
+ example, returning "January" as a month name.
+
+ \value ShortFormat The short version of day and month names; for
+ example, returning "Jan" as a month name.
+
+ \value NarrowFormat A special version of day and month names for
+ use when space is limited; for example, returning "J" as a month
+ name. Note that the narrow format might contain the same text for
+ different months and days or it can even be an empty string if the
+ locale doesn't support narrow names, so you should avoid using it
+ for date formatting. Also, for the system locale this format is
+ the same as ShortFormat.
+
+ \sa QDateTime::toString(), QDate::toString(), QTime::toString()
+*/
+
+/*!
+ \enum QLocale::NumberOption
+
+ This enum defines a set of options for number-to-string and string-to-number
+ conversions. They can be retrieved with numberOptions() and set with
+ setNumberOptions().
+
+ \value DefaultNumberOptions This option represents the default behavior, with
+ group separators, with one leading zero in single digit exponents, and
+ without trailing zeroes after the decimal dot.
+ \value OmitGroupSeparator If this option is set, the number-to-string functions
+ will not insert group separators in their return values. The default
+ is to insert group separators.
+ \value RejectGroupSeparator If this option is set, the string-to-number functions
+ will fail if they encounter group separators in their input. The default
+ is to accept numbers containing correctly placed group separators.
+ \value OmitLeadingZeroInExponent If this option is set, the number-to-string
+ functions will not pad exponents with zeroes when printing floating point
+ numbers in scientific notation. The default is to add one leading zero to
+ single digit exponents.
+ \value RejectLeadingZeroInExponent If this option is set, the string-to-number
+ functions will fail if they encounter an exponent padded with zeroes when
+ parsing a floating point number in scientific notation. The default is to
+ accept such padding.
+ \value IncludeTrailingZeroesAfterDot If this option is set, the number-to-string
+ functions will pad numbers with zeroes to the requested precision in "g"
+ or "most concise" mode, even if the number of significant digits is lower
+ than the requested precision. The default is to omit trailing zeroes.
+ \value RejectTrailingZeroesAfterDot If this option is set, the string-to-number
+ functions will fail if they encounter trailing zeroes after the decimal
+ dot when parsing a number in scientific or decimal representation. The
+ default is to accept trailing zeroes.
+
+ \sa setNumberOptions(), numberOptions()
+*/
+
+/*!
+ \enum QLocale::FloatingPointPrecisionOption
+
+ This enum defines constants that can be given as precision to QString::number(),
+ QByteArray::number(), and QLocale::toString() when converting floats or doubles,
+ in order to express a variable number of digits as precision.
+
+ \value FloatingPointShortest The conversion algorithm will try to find the
+ shortest accurate representation for the given number. "Accurate" means
+ that you get the exact same number back from an inverse conversion on
+ the generated string representation.
+
+ \sa toString(), QString, QByteArray
+
+ \since 5.7
+*/
+
+/*!
+ \enum QLocale::MeasurementSystem
+
+ This enum defines which units are used for measurement.
+
+ \value MetricSystem This value indicates metric units, such as meters,
+ centimeters and millimeters.
+ \value ImperialUSSystem This value indicates imperial units, such as inches and
+ miles as they are used in the United States.
+ \value ImperialUKSystem This value indicates imperial units, such as inches and
+ miles as they are used in the United Kingdom.
+ \value ImperialSystem Provided for compatibility. Same as ImperialUSSystem
+
+ \since 4.4
+*/
+
+
+/*!
+ \fn bool QLocale::operator==(const QLocale &other) const
+
+ Returns \c true if the QLocale object is the same as the \a other
+ locale specified; otherwise returns \c false.
+*/
+
+/*!
+ \fn bool QLocale::operator!=(const QLocale &other) const
+
+ Returns \c true if the QLocale object is not the same as the \a other
+ locale specified; otherwise returns \c false.
+*/
+
+/*!
+ \enum QLocale::QuotationStyle
+
+ This enum defines a set of possible styles for locale specific quotation.
+
+ \value StandardQuotation If this option is set, the standard quotation marks
+ will be used to quote strings.
+ \value AlternateQuotation If this option is set, the alternate quotation marks
+ will be used to quote strings.
+
+ \since 4.8
+
+ \sa quoteString()
+*/
+
+/*!
+ \internal
+ \class QSystemLocale
+ \inmodule QtCore
+ \brief The QSystemLocale class can be used to finetune the system locale
+ of the user.
+ \since 4.2
+
+ \ingroup i18n
+
+ \warning This class is only useful in very rare cases. Usually QLocale offers
+ all the functionality required for application development.
+
+ QSystemLocale allows to override the values provided by the system
+ locale (QLocale::system()).
+
+ \sa QLocale
+*/
+
+/*!
+ \enum QSystemLocale::QueryType
+
+ Specifies the type of information queried by query(). For each value
+ the type of information to return from the query() method is listed.
+
+ \value LanguageId a uint specifying the language.
+ \value ScriptId a uint specifying the script.
+ \value CountryId a uint specifying the country.
+ \value DecimalPoint a QString specifying the decimal point.
+ \value GroupSeparator a QString specifying the group separator.
+ \value ZeroDigit a QString specifying the zero digit.
+ \value NegativeSign a QString specifying the minus sign.
+ \value PositiveSign a QString specifying the plus sign.
+ \value DateFormatLong a QString specifying the long date format
+ \value DateFormatShort a QString specifying the short date format
+ \value TimeFormatLong a QString specifying the long time format
+ \value TimeFormatShort a QString specifying the short time format
+ \value DayNameLong a QString specifying the name of a weekday. the in variant contains an integer between 1 and 7 (Monday - Sunday)
+ \value DayNameShort a QString specifying the short name of a weekday. the in variant contains an integer between 1 and 7 (Monday - Sunday)
+ \value MonthNameLong a QString specifying the name of a month. the in variant contains an integer between 1 and 12
+ \value MonthNameShort a QString specifying the short name of a month. the in variant contains an integer between 1 and 12
+ \value DateToStringLong converts the QDate stored in the in variant to a QString using the long date format
+ \value DateToStringShort converts the QDate stored in the in variant to a QString using the short date format
+ \value TimeToStringLong converts the QTime stored in the in variant to a QString using the long time format
+ \value TimeToStringShort converts the QTime stored in the in variant to a QString using the short time format
+ \value DateTimeFormatLong a QString specifying the long date time format
+ \value DateTimeFormatShort a QString specifying the short date time format
+ \value DateTimeToStringLong converts the QDateTime in the in variant to a QString using the long datetime format
+ \value DateTimeToStringShort converts the QDateTime in the in variant to a QString using the short datetime format
+ \value MeasurementSystem a QLocale::MeasurementSystem enum specifying the measurement system
+ \value AMText a string that represents the system AM designator associated with a 12-hour clock.
+ \value PMText a string that represents the system PM designator associated with a 12-hour clock.
+ \value FirstDayOfWeek a Qt::DayOfWeek enum specifiying the first day of the week
+ \value CurrencySymbol a string that represents a currency in a format QLocale::CurrencyFormat.
+ \value CurrencyToString a localized string representation of a number with a currency symbol. Converts a QSystemLocale::CurrencyToStringArgument stored in the in variant to a QString.
+ \value UILanguages a list of strings representing locale names that could be used for UI translation.
+ \value StringToStandardQuotation a QString containing a quoted version of the string ref stored in the in variant using standard quotes.
+ \value StringToAlternateQuotation a QString containing a quoted version of the string ref stored in the in variant using alternate quotes.
+ \value Weekdays a QList<Qt::DayOfWeek> specifying the regular weekdays
+ \value LocaleChanged this type is queried whenever the system locale is changed.
+ \value ListToSeparatedString a string that represents a join of a given QStringList with a locale-defined separator.
+ \value NativeLanguageName a string that represents the name of the native language.
+ \value NativeCountryName a string that represents the name of the native country.
+
+ \sa FormatType
+*/
+
+/*!
+ \fn QLocale QSystemLocale::fallbackUiLocale() const
+
+ \since 4.6
+ Returns the fallback locale obtained from the system.
+*/
+
+/*!
+ \fn QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
+
+ Generic query method for locale data. Provides indirection.
+ Denotes the \a type of the query
+ with \a in as input data depending on the query.
+
+ \sa QSystemLocale::QueryType
+*/
+
+/*!
+ \class QSystemLocale::CurrencyToStringArgument
+ \inmodule QtCore
+
+ A helper class that provides arguments for the QSystemLocale::query()
+ function with query type QSystemLocale::CurrencyToString.
+
+ \sa QSystemLocale::QueryType
+ \since 4.8
+*/
+
+/*!
+ \fn QSystemLocale::CurrencyToStringArgument::CurrencyToStringArgument()
+ \internal
+*/
+/*!
+ \variable QSystemLocale::CurrencyToStringArgument::value
+
+ An input value that should be converted to its string representation.
+ Contains one of QVariant::LongLong, QVariant::ULongLong or QVariant::Double
+ types.
+*/
+/*!
+ \variable QSystemLocale::CurrencyToStringArgument::symbol
+
+ An optional argument containing a currency symbol to be used in the
+ currency string.
+*/
+
+/*!
+\fn QString QLocale::toString(long i) const
+
+\overload
+
+\sa toLong()
+*/
+
+/*!
+\fn QString QLocale::toString(ulong i) const
+
+\overload
+
+\sa toULong()
+*/
+
+/*!
+\fn QString QLocale::toString(ushort i) const
+
+\overload
+
+\sa toUShort()
+*/
+
+
+/*!
+\fn QString QLocale::toString(short i) const
+
+\overload
+
+\sa toShort()
+*/
+
+/*!
+\fn QString QLocale::toString(ushort i) const
+
+\overload
+
+\sa toUShort()
+*/
+
+/*!
+\fn QString QLocale::toString(int i) const
+
+\overload
+
+\sa toInt()
+*/
+
+/*!
+\fn QString QLocale::toString(uint i) const
+
+\overload
+
+\sa toUInt()
+*/
+
+/*
+\fn QString QLocale::toString(long i) const
+
+\overload
+
+\sa toLong()
+*/
+
+/*
+\fn QString QLocale::toString(ulong i) const
+
+\overload
+
+\sa toULong()
+*/
+
+/*!
+\fn QString QLocale::toString(float i, char f = 'g', int prec = 6) const
+
+\overload
+
+\a f and \a prec have the same meaning as in QString::number(double, char, int).
+
+\sa toDouble()
+*/
+
+/*!
+ \fn QString QLocale::toCurrencyString(short value, const QString &symbol) const
+ \since 4.8
+ \overload
+*/
+
+/*!
+ \fn QString QLocale::toCurrencyString(ushort value, const QString &symbol) const
+ \since 4.8
+ \overload
+*/
+
+/*!
+ \fn QString QLocale::toCurrencyString(int value, const QString &symbol) const
+ \since 4.8
+ \overload
+*/
+
+/*!
+ \fn QString QLocale::toCurrencyString(uint value, const QString &symbol) const
+ \since 4.8
+ \overload
+*/
+/*!
+ \fn QString QLocale::toCurrencyString(float value, const QString &symbol) const
+ \since 4.8
+ \overload
+*/
diff --git a/src/corelib/text/qlocale_data_p.h b/src/corelib/text/qlocale_data_p.h
new file mode 100644
index 0000000000..2c351a3fb1
--- /dev/null
+++ b/src/corelib/text/qlocale_data_p.h
@@ -0,0 +1,8814 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLOCALE_DATA_P_H
+#define QLOCALE_DATA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/private/qglobal_p.h>
+
+QT_BEGIN_NAMESPACE
+
+/* This part of the file isn't generated, but written by hand since
+ * Unicode CLDR doesn't contain measurement system information.
+ */
+struct CountryLanguage
+{
+ quint16 languageId;
+ quint16 countryId;
+ QLocale::MeasurementSystem system;
+};
+static const CountryLanguage ImperialMeasurementSystems[] = {
+ { QLocale::English, QLocale::UnitedStates, QLocale::ImperialUSSystem },
+ { QLocale::English, QLocale::UnitedStatesMinorOutlyingIslands, QLocale::ImperialUSSystem },
+ { QLocale::Spanish, QLocale::UnitedStates, QLocale::ImperialUSSystem },
+ { QLocale::Hawaiian, QLocale::UnitedStates, QLocale::ImperialUSSystem },
+ { QLocale::English, QLocale::UnitedKingdom, QLocale::ImperialUKSystem }
+};
+static const int ImperialMeasurementSystemsCount =
+ sizeof(ImperialMeasurementSystems)/sizeof(ImperialMeasurementSystems[0]);
+
+// GENERATED PART STARTS HERE
+
+/*
+ This part of the file was generated on 2019-05-09 from the
+ Common Locale Data Repository v35.1
+
+ http://www.unicode.org/cldr/
+
+ Do not edit this section: instead regenerate it using
+ cldr2qlocalexml.py and qlocalexml2cpp.py on updated (or
+ edited) CLDR data; see qtbase/util/locale_database/.
+*/
+
+static const QLocaleId likely_subtags[] = {
+ { 4, 0, 0 }, { 4, 7, 69 }, // aa -> aa_Latn_ET
+ { 2, 0, 0 }, { 2, 2, 81 }, // ab -> ab_Cyrl_GE
+ { 255, 0, 0 }, { 255, 36, 102 }, // ae -> ae_Avst_IR
+ { 5, 0, 0 }, { 5, 7, 195 }, // af -> af_Latn_ZA
+ { 237, 0, 0 }, { 237, 7, 37 }, // agq -> agq_Latn_CM
+ { 340, 0, 0 }, { 340, 128, 100 }, // aho -> aho_Ahom_IN
+ { 146, 0, 0 }, { 146, 7, 83 }, // ak -> ak_Latn_GH
+ { 262, 0, 0 }, { 262, 94, 103 }, // akk -> akk_Xsux_IQ
+ { 7, 0, 0 }, { 7, 14, 69 }, // am -> am_Ethi_ET
+ { 8, 0, 0 }, { 8, 1, 64 }, // ar -> ar_Arab_EG
+ { 265, 0, 0 }, { 265, 57, 102 }, // arc -> arc_Armi_IR
+ { 265, 119, 0 }, { 265, 119, 109 }, // arc_Nbat -> arc_Nbat_JO
+ { 265, 120, 0 }, { 265, 120, 207 }, // arc_Palm -> arc_Palm_SY
+ { 315, 0, 0 }, { 315, 7, 43 }, // arn -> arn_Latn_CL
+ { 10, 0, 0 }, { 10, 11, 100 }, // as -> as_Beng_IN
+ { 205, 0, 0 }, { 205, 7, 210 }, // asa -> asa_Latn_TZ
+ { 341, 0, 0 }, { 341, 133, 225 }, // ase -> ase_Sgnw_US
+ { 256, 0, 0 }, { 256, 7, 197 }, // ast -> ast_Latn_ES
+ { 216, 0, 0 }, { 216, 2, 178 }, // av -> av_Cyrl_RU
+ { 11, 0, 0 }, { 11, 7, 26 }, // ay -> ay_Latn_BO
+ { 12, 0, 0 }, { 12, 7, 15 }, // az -> az_Latn_AZ
+ { 12, 0, 103 }, { 12, 1, 103 }, // az_IQ -> az_Arab_IQ
+ { 12, 0, 102 }, { 12, 1, 102 }, // az_IR -> az_Arab_IR
+ { 12, 0, 178 }, { 12, 2, 178 }, // az_RU -> az_Cyrl_RU
+ { 12, 1, 0 }, { 12, 1, 102 }, // az_Arab -> az_Arab_IR
+ { 13, 0, 0 }, { 13, 2, 178 }, // ba -> ba_Cyrl_RU
+ { 266, 0, 0 }, { 266, 7, 101 }, // ban -> ban_Latn_ID
+ { 238, 0, 0 }, { 238, 7, 37 }, // bas -> bas_Latn_CM
+ { 267, 0, 0 }, { 267, 38, 37 }, // bax -> bax_Bamu_CM
+ { 268, 0, 0 }, { 268, 7, 101 }, // bbc -> bbc_Latn_ID
+ { 22, 0, 0 }, { 22, 2, 20 }, // be -> be_Cyrl_BY
+ { 195, 0, 0 }, { 195, 7, 239 }, // bem -> bem_Latn_ZM
+ { 186, 0, 0 }, { 186, 7, 210 }, // bez -> bez_Latn_TZ
+ { 20, 0, 0 }, { 20, 2, 33 }, // bg -> bg_Cyrl_BG
+ { 364, 0, 0 }, { 364, 1, 163 }, // bgn -> bgn_Arab_PK
+ { 343, 0, 0 }, { 343, 13, 100 }, // bho -> bho_Deva_IN
+ { 18, 0, 0 }, { 18, 7, 229 }, // bi -> bi_Latn_VU
+ { 270, 0, 0 }, { 270, 7, 170 }, // bku -> bku_Latn_PH
+ { 309, 0, 0 }, { 309, 100, 232 }, // blt -> blt_Tavt_VN
+ { 188, 0, 0 }, { 188, 7, 132 }, // bm ->